Merge branch 'MDL-63968-master' of git://github.com/andrewnicols/moodle
[moodle.git] / message / tests / api_test.php
blobbabfa107017b029734ab0cfc6b373785e9f72fd8
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
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/>.
17 /**
18 * Test message API.
20 * @package core_message
21 * @category test
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();
28 global $CFG;
30 require_once($CFG->dirroot . '/message/tests/messagelib_test.php');
32 use \core_message\tests\helper as testhelper;
34 /**
35 * Test message API.
37 * @package core_message
38 * @category test
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() {
107 global $USER;
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);
153 // Create a course.
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);
163 // Perform a search.
164 $results = \core_message\api::search_users_in_course($user1->id, $course1->id, 'User');
166 $this->assertEquals(1, count($results));
168 $user = $results[0];
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() {
184 global $DB;
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 users.
312 public function test_message_search_users() {
313 // Create some users.
314 $user1 = new stdClass();
315 $user1->firstname = 'User search';
316 $user1->lastname = 'One';
317 $user1 = self::getDataGenerator()->create_user($user1);
319 // Set as the user performing the search.
320 $this->setUser($user1);
322 $user2 = new stdClass();
323 $user2->firstname = 'User search';
324 $user2->lastname = 'Two';
325 $user2 = self::getDataGenerator()->create_user($user2);
327 $user3 = new stdClass();
328 $user3->firstname = 'User search';
329 $user3->lastname = 'Three';
330 $user3 = self::getDataGenerator()->create_user($user3);
332 $user4 = new stdClass();
333 $user4->firstname = 'User';
334 $user4->lastname = 'Four';
335 $user4 = self::getDataGenerator()->create_user($user4);
337 $user5 = new stdClass();
338 $user5->firstname = 'User search';
339 $user5->lastname = 'Five';
340 $user5 = self::getDataGenerator()->create_user($user5);
342 $user6 = new stdClass();
343 $user6->firstname = 'User search';
344 $user6->lastname = 'Six';
345 $user6 = self::getDataGenerator()->create_user($user6);
347 $user7 = new stdClass();
348 $user7->firstname = 'User search';
349 $user7->lastname = 'Seven';
350 $user7 = self::getDataGenerator()->create_user($user7);
352 // Add some users as contacts.
353 \core_message\api::add_contact($user1->id, $user2->id);
354 \core_message\api::add_contact($user3->id, $user1->id);
355 \core_message\api::add_contact($user1->id, $user4->id);
357 // Create private conversations with some users.
358 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
359 array($user1->id, $user6->id));
360 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
361 array($user7->id, $user1->id));
363 // Perform a search $CFG->messagingallusers setting enabled.
364 set_config('messagingallusers', 1);
365 list($contacts, $noncontacts) = \core_message\api::message_search_users($user1->id, 'search');
367 // Check that we retrieved the correct contacts.
368 $this->assertCount(2, $contacts);
369 $this->assertEquals($user3->id, $contacts[0]->id);
370 $this->assertEquals($user2->id, $contacts[1]->id);
372 // Check that we retrieved the correct non-contacts.
373 $this->assertCount(3, $noncontacts);
374 $this->assertEquals($user5->id, $noncontacts[0]->id);
375 $this->assertEquals($user7->id, $noncontacts[1]->id);
376 $this->assertEquals($user6->id, $noncontacts[2]->id);
378 // Perform a search $CFG->messagingallusers setting disabled.
379 set_config('messagingallusers', 0);
380 list($contacts, $noncontacts) = \core_message\api::message_search_users($user1->id, 'search');
382 // Check that we retrieved the correct contacts.
383 $this->assertCount(2, $contacts);
384 $this->assertEquals($user3->id, $contacts[0]->id);
385 $this->assertEquals($user2->id, $contacts[1]->id);
387 // Check that we retrieved the correct non-contacts.
388 $this->assertCount(2, $noncontacts);
389 $this->assertEquals($user7->id, $noncontacts[0]->id);
390 $this->assertEquals($user6->id, $noncontacts[1]->id);
394 * Tests getting conversations between 2 users.
396 public function test_get_conversations_between_users() {
397 // Create some users.
398 $user1 = new stdClass();
399 $user1->firstname = 'User';
400 $user1->lastname = 'One';
401 $user1 = self::getDataGenerator()->create_user($user1);
403 $user2 = new stdClass();
404 $user2->firstname = 'User';
405 $user2->lastname = 'Two';
406 $user2 = self::getDataGenerator()->create_user($user2);
408 $user3 = new stdClass();
409 $user3->firstname = 'User search';
410 $user3->lastname = 'Three';
411 $user3 = self::getDataGenerator()->create_user($user3);
413 $user4 = new stdClass();
414 $user4->firstname = 'User';
415 $user4->lastname = 'Four';
416 $user4 = self::getDataGenerator()->create_user($user4);
418 $user5 = new stdClass();
419 $user5->firstname = 'User';
420 $user5->lastname = 'Five';
421 $user5 = self::getDataGenerator()->create_user($user5);
423 $user6 = new stdClass();
424 $user6->firstname = 'User search';
425 $user6->lastname = 'Six';
426 $user6 = self::getDataGenerator()->create_user($user6);
428 // Add some users as contacts.
429 \core_message\api::add_contact($user1->id, $user2->id);
430 \core_message\api::add_contact($user6->id, $user1->id);
432 // Create private conversations with some users.
433 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
434 array($user1->id, $user2->id));
435 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
436 array($user3->id, $user1->id));
438 // Create a group conversation with users.
439 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
440 array($user1->id, $user2->id, $user3->id, $user4->id),
441 'Project chat');
443 // Check that we retrieved the correct conversations.
444 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user2->id));
445 $this->assertCount(2, \core_message\api::get_conversations_between_users($user2->id, $user1->id));
446 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user3->id));
447 $this->assertCount(2, \core_message\api::get_conversations_between_users($user3->id, $user1->id));
448 $this->assertCount(1, \core_message\api::get_conversations_between_users($user1->id, $user4->id));
449 $this->assertCount(1, \core_message\api::get_conversations_between_users($user4->id, $user1->id));
450 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user5->id));
451 $this->assertCount(0, \core_message\api::get_conversations_between_users($user5->id, $user1->id));
452 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user6->id));
453 $this->assertCount(0, \core_message\api::get_conversations_between_users($user6->id, $user1->id));
457 * Tests searching users with and without conversations.
459 public function test_message_search_users_with_and_without_conversations() {
460 // Create some users.
461 $user1 = new stdClass();
462 $user1->firstname = 'User search';
463 $user1->lastname = 'One';
464 $user1 = self::getDataGenerator()->create_user($user1);
466 // Set as the user performing the search.
467 $this->setUser($user1);
469 $user2 = new stdClass();
470 $user2->firstname = 'User search';
471 $user2->lastname = 'Two';
472 $user2 = self::getDataGenerator()->create_user($user2);
474 $user3 = new stdClass();
475 $user3->firstname = 'User search';
476 $user3->lastname = 'Three';
477 $user3 = self::getDataGenerator()->create_user($user3);
479 $user4 = new stdClass();
480 $user4->firstname = 'User';
481 $user4->lastname = 'Four';
482 $user4 = self::getDataGenerator()->create_user($user4);
484 $user5 = new stdClass();
485 $user5->firstname = 'User search';
486 $user5->lastname = 'Five';
487 $user5 = self::getDataGenerator()->create_user($user5);
489 // Add a user as contact.
490 \core_message\api::add_contact($user1->id, $user2->id);
492 // Create private conversations with some users.
493 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
494 array($user1->id, $user2->id));
495 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
496 array($user3->id, $user1->id));
498 // Create a group conversation with users.
499 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
500 array($user1->id, $user2->id, $user4->id),
501 'Project chat');
503 // Perform a search $CFG->messagingallusers setting enabled.
504 set_config('messagingallusers', 1);
505 list($contacts, $noncontacts) = \core_message\api::message_search_users($user1->id, 'search');
507 // Check that we retrieved the correct contacts.
508 $this->assertCount(1, $contacts);
510 // Check that we retrieved the correct conversations for contacts.
511 $this->assertCount(2, $contacts[0]->conversations);
513 // Check that we retrieved the correct non-contacts.
514 $this->assertCount(2, $noncontacts);
515 $this->assertEquals($user5->id, $noncontacts[0]->id);
516 $this->assertEquals($user3->id, $noncontacts[1]->id);
518 // Check that we retrieved the correct conversations for non-contacts.
519 $this->assertCount(0, $noncontacts[0]->conversations);
520 $this->assertCount(1, $noncontacts[1]->conversations);
524 * Tests searching users with empty result.
526 public function test_message_search_users_with_empty_result() {
528 // Create some users.
529 $user1 = new stdClass();
530 $user1->firstname = 'User';
531 $user1->lastname = 'One';
532 $user1 = self::getDataGenerator()->create_user($user1);
534 // Set as the user performing the search.
535 $this->setUser($user1);
537 $user2 = new stdClass();
538 $user2->firstname = 'User';
539 $user2->lastname = 'Two';
540 $user2 = self::getDataGenerator()->create_user($user2);
542 // Perform a search $CFG->messagingallusers setting enabled.
543 set_config('messagingallusers', 1);
544 list($contacts, $noncontacts) = \core_message\api::message_search_users($user1->id, 'search');
546 // Check results are empty.
547 $this->assertEquals(0, count($contacts));
548 $this->assertEquals(0, count($noncontacts));
552 * Tests searching messages.
554 public function test_search_messages() {
555 // Create some users.
556 $user1 = self::getDataGenerator()->create_user();
557 $user2 = self::getDataGenerator()->create_user();
558 $user3 = self::getDataGenerator()->create_user();
560 // The person doing the search.
561 $this->setUser($user1);
563 // Send some messages back and forth.
564 $time = 1;
565 $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
566 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
567 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
568 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
569 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
571 // Block user 3.
572 \core_message\api::block_user($user1->id, $user3->id);
574 // Perform a search.
575 $messages = \core_message\api::search_messages($user1->id, 'o');
577 // Confirm the data is correct.
578 $this->assertEquals(3, count($messages));
580 $message1 = $messages[0];
581 $message2 = $messages[1];
582 $message3 = $messages[2];
584 $this->assertEquals($user2->id, $message1->userid);
585 $this->assertEquals($user2->id, $message1->useridfrom);
586 $this->assertEquals(fullname($user2), $message1->fullname);
587 $this->assertTrue($message1->ismessaging);
588 $this->assertEquals('Word.', $message1->lastmessage);
589 $this->assertNotEmpty($message1->messageid);
590 $this->assertNull($message1->isonline);
591 $this->assertFalse($message1->isread);
592 $this->assertFalse($message1->isblocked);
593 $this->assertNull($message1->unreadcount);
595 $this->assertEquals($user2->id, $message2->userid);
596 $this->assertEquals($user1->id, $message2->useridfrom);
597 $this->assertEquals(fullname($user2), $message2->fullname);
598 $this->assertTrue($message2->ismessaging);
599 $this->assertEquals('Yo!', $message2->lastmessage);
600 $this->assertNotEmpty($message2->messageid);
601 $this->assertNull($message2->isonline);
602 $this->assertTrue($message2->isread);
603 $this->assertFalse($message2->isblocked);
604 $this->assertNull($message2->unreadcount);
606 $this->assertEquals($user3->id, $message3->userid);
607 $this->assertEquals($user3->id, $message3->useridfrom);
608 $this->assertEquals(fullname($user3), $message3->fullname);
609 $this->assertTrue($message3->ismessaging);
610 $this->assertEquals('Don\'t block me.', $message3->lastmessage);
611 $this->assertNotEmpty($message3->messageid);
612 $this->assertNull($message3->isonline);
613 $this->assertFalse($message3->isread);
614 $this->assertTrue($message3->isblocked);
615 $this->assertNull($message3->unreadcount);
619 * Test verifying that favourited conversations can be retrieved.
621 public function test_get_favourite_conversations() {
622 // Create some users.
623 $user1 = self::getDataGenerator()->create_user();
624 $user2 = self::getDataGenerator()->create_user();
625 $user3 = self::getDataGenerator()->create_user();
626 $user4 = self::getDataGenerator()->create_user();
628 // The person doing the search.
629 $this->setUser($user1);
631 // No conversations yet.
632 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
634 // Create some conversations for user1.
635 $time = 1;
636 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
637 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
638 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
639 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
641 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
642 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
643 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
644 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
646 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
647 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
648 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
650 // Favourite the first 2 conversations for user1.
651 $convoids = [];
652 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
653 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
654 $user1context = context_user::instance($user1->id);
655 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
656 foreach ($convoids as $convoid) {
657 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
660 // We should have 3 conversations.
661 $this->assertCount(3, \core_message\api::get_conversations($user1->id));
663 // And 2 favourited conversations.
664 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
665 $this->assertCount(2, $conversations);
669 * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
671 public function test_get_favourite_conversations_limit_offset() {
672 // Create some users.
673 $user1 = self::getDataGenerator()->create_user();
674 $user2 = self::getDataGenerator()->create_user();
675 $user3 = self::getDataGenerator()->create_user();
676 $user4 = self::getDataGenerator()->create_user();
678 // The person doing the search.
679 $this->setUser($user1);
681 // No conversations yet.
682 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
684 // Create some conversations for user1.
685 $time = 1;
686 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
687 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
688 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
689 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
691 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
692 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
693 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
694 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
696 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
697 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
698 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
700 // Favourite the all conversations for user1.
701 $convoids = [];
702 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
703 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
704 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
705 $user1context = context_user::instance($user1->id);
706 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
707 foreach ($convoids as $convoid) {
708 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
711 // Get all records, using offset 0 and large limit.
712 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
714 // Now, get 10 conversations starting at the second record. We should see 2 conversations.
715 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
717 // Now, try to get favourited conversations using an invalid offset.
718 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 4, 10, null, true));
722 * Tests retrieving favourite conversations when a conversation contains a deleted user.
724 public function test_get_favourite_conversations_with_deleted_user() {
725 // Create some users.
726 $user1 = self::getDataGenerator()->create_user();
727 $user2 = self::getDataGenerator()->create_user();
728 $user3 = self::getDataGenerator()->create_user();
730 // Send some messages back and forth, have some different conversations with different users.
731 $time = 1;
732 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
733 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
734 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
735 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
737 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
738 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
739 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
740 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
742 // Favourite the all conversations for user1.
743 $convoids = [];
744 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
745 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
746 $user1context = context_user::instance($user1->id);
747 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
748 foreach ($convoids as $convoid) {
749 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
752 // Delete the second user.
753 delete_user($user2);
755 // Retrieve the conversations.
756 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
758 // We should only have one conversation because the other user was deleted.
759 $this->assertCount(1, $conversations);
761 // Confirm the conversation is from the non-deleted user.
762 $conversation = reset($conversations);
763 $this->assertEquals($convoids[1], $conversation->id);
767 * Test confirming that conversations can be marked as favourites.
769 public function test_set_favourite_conversation() {
770 // Create some users.
771 $user1 = self::getDataGenerator()->create_user();
772 $user2 = self::getDataGenerator()->create_user();
773 $user3 = self::getDataGenerator()->create_user();
775 // Send some messages back and forth, have some different conversations with different users.
776 $time = 1;
777 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
778 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
779 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
780 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
782 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
783 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
784 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
785 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
787 // Favourite the first conversation as user 1.
788 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
789 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
791 // Verify we have a single favourite conversation a user 1.
792 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
794 // Verify we have no favourites as user2, despite being a member in that conversation.
795 $this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
797 // Try to favourite the same conversation again.
798 $this->expectException(\moodle_exception::class);
799 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
803 * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
805 public function test_set_favourite_conversation_nonexistent_conversation() {
806 // Create some users.
807 $user1 = self::getDataGenerator()->create_user();
808 // Try to favourite a non-existent conversation.
809 $this->expectException(\moodle_exception::class);
810 \core_message\api::set_favourite_conversation(0, $user1->id);
814 * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
816 public function test_set_favourite_conversation_non_member() {
817 // Create some users.
818 $user1 = self::getDataGenerator()->create_user();
819 $user2 = self::getDataGenerator()->create_user();
820 $user3 = self::getDataGenerator()->create_user();
822 // Send some messages back and forth, have some different conversations with different users.
823 $time = 1;
824 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
825 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
826 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
827 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
829 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
830 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
831 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
832 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
834 // Try to favourite the first conversation as user 3, who is not a member.
835 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
836 $this->expectException(\moodle_exception::class);
837 \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
841 * Test confirming that those conversations marked as favourites can be unfavourited.
843 public function test_unset_favourite_conversation() {
844 // Create some users.
845 $user1 = self::getDataGenerator()->create_user();
846 $user2 = self::getDataGenerator()->create_user();
847 $user3 = self::getDataGenerator()->create_user();
849 // Send some messages back and forth, have some different conversations with different users.
850 $time = 1;
851 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
852 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
853 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
854 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
856 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
857 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
858 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
859 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
861 // Favourite the first conversation as user 1 and the second as user 3.
862 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
863 $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
864 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
865 \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
867 // Verify we have a single favourite conversation for both user 1 and user 3.
868 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
869 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
871 // Now unfavourite the conversation as user 1.
872 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
874 // Verify we have a single favourite conversation user 3 only, and none for user1.
875 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
876 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
878 // Try to favourite the same conversation again as user 1.
879 $this->expectException(\moodle_exception::class);
880 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
884 * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
886 public function test_unset_favourite_conversation_not_favourite() {
887 // Create some users.
888 $user1 = self::getDataGenerator()->create_user();
889 $user2 = self::getDataGenerator()->create_user();
891 // Send some messages back and forth, have some different conversations with different users.
892 $time = 1;
893 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
894 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
895 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
896 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
898 // Now try to unfavourite the conversation as user 1.
899 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
900 $this->expectException(\moodle_exception::class);
901 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
905 * Test verifying that a non-existent conversation cannot be unset as a favourite.
907 public function test_unset_favourite_conversation_non_existent_conversation() {
908 // Create some users.
909 $user1 = self::getDataGenerator()->create_user();
911 // Now try to unfavourite the conversation as user 1.
912 $this->expectException(\moodle_exception::class);
913 \core_message\api::unset_favourite_conversation(0, $user1->id);
917 * Helper to seed the database with initial state.
919 protected function create_conversation_test_data() {
920 // Create some users.
921 $user1 = self::getDataGenerator()->create_user();
922 $user2 = self::getDataGenerator()->create_user();
923 $user3 = self::getDataGenerator()->create_user();
924 $user4 = self::getDataGenerator()->create_user();
926 $time = 1;
928 // Create some conversations. We want:
929 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
930 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
931 // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
932 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
933 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
935 // Individual conversation, user1 is a member, last message from other user.
936 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
937 [$user1->id, $user2->id]);
938 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
939 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
941 // Individual conversation, user1 is a member, last message from user1.
942 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
943 [$user1->id, $user3->id]);
944 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
945 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
947 // Individual conversation, user1 is not a member.
948 $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
949 [$user2->id, $user3->id]);
950 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
951 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
953 // Group conversation, user1 is not a member.
954 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
955 [$user2->id, $user3->id, $user4->id], 'Project discussions');
956 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
957 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
959 // Group conversation, user1 is a member, last message from another user.
960 $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
961 [$user1->id, $user3->id, $user4->id], 'Group chat');
962 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
963 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
964 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
966 // Group conversation, user1 is a member, last message from user1.
967 $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
968 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
969 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
970 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
971 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
973 // Empty group conversations (x2), user1 is a member.
974 $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
975 [$user1->id, $user2->id, $user3->id], 'Empty group');
976 $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
977 [$user1->id, $user2->id, $user4->id], 'Another empty group');
979 // Empty group conversation, user1 is NOT a member.
980 $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
981 [$user2->id, $user3->id, $user4->id], 'Empty group 3');
983 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
987 * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
989 public function test_get_conversations_no_restrictions() {
990 global $DB;
991 // No conversations should exist yet.
992 $user1 = self::getDataGenerator()->create_user();
993 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
995 // Get a bunch of conversations, some group, some individual and in different states.
996 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
997 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
999 // Get all conversations for user1.
1000 $conversations = core_message\api::get_conversations($user1->id);
1002 // Verify there are 2 individual conversation, 2 group conversations, and 2 empty group conversations.
1003 // The conversations with the most recent messages should be listed first, followed by the empty
1004 // conversations, with the most recently created first.
1005 $this->assertCount(6, $conversations);
1006 $typecounts = array_count_values(array_column($conversations, 'type'));
1007 $this->assertEquals(2, $typecounts[1]);
1008 $this->assertEquals(4, $typecounts[2]);
1010 // Those conversations having messages should be listed first, ordered by most recent message time.
1011 $this->assertEquals($gc3->id, $conversations[0]->id);
1012 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
1013 $this->assertFalse($conversations[0]->isfavourite);
1014 $this->assertCount(1, $conversations[0]->members);
1015 $this->assertEquals(4, $conversations[0]->membercount);
1016 $this->assertCount(1, $conversations[0]->messages);
1017 $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]);
1018 $expectedmessagetext = message_format_message_text($message);
1019 $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text);
1020 $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
1022 $this->assertEquals($gc2->id, $conversations[1]->id);
1023 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
1024 $this->assertFalse($conversations[1]->isfavourite);
1025 $this->assertCount(1, $conversations[1]->members);
1026 $this->assertEquals(3, $conversations[1]->membercount);
1027 $this->assertCount(1, $conversations[1]->messages);
1028 $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]);
1029 $expectedmessagetext = message_format_message_text($message);
1030 $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text);
1031 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1033 $this->assertEquals($ic2->id, $conversations[2]->id);
1034 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
1035 $this->assertFalse($conversations[2]->isfavourite);
1036 $this->assertCount(1, $conversations[2]->members);
1037 $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
1038 $this->assertEquals(2, $conversations[2]->membercount);
1039 $this->assertCount(1, $conversations[2]->messages);
1040 $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]);
1041 $expectedmessagetext = message_format_message_text($message);
1042 $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text);
1043 $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
1045 $this->assertEquals($ic1->id, $conversations[3]->id);
1046 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
1047 $this->assertFalse($conversations[3]->isfavourite);
1048 $this->assertCount(1, $conversations[3]->members);
1049 $this->assertEquals(2, $conversations[3]->membercount);
1050 $this->assertCount(1, $conversations[3]->messages);
1051 $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]);
1052 $expectedmessagetext = message_format_message_text($message);
1053 $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text);
1054 $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
1056 // Of the groups without messages, we expect to see the most recently created first.
1057 $this->assertEquals($gc5->id, $conversations[4]->id);
1058 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
1059 $this->assertFalse($conversations[4]->isfavourite);
1060 $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
1061 $this->assertEquals(3, $conversations[4]->membercount);
1062 $this->assertEmpty($conversations[4]->messages);
1064 $this->assertEquals($gc4->id, $conversations[5]->id);
1065 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
1066 $this->assertFalse($conversations[5]->isfavourite);
1067 $this->assertCount(0, $conversations[5]->members);
1068 $this->assertEquals(3, $conversations[5]->membercount);
1069 $this->assertEmpty($conversations[5]->messages);
1071 // Verify format of the return structure.
1072 foreach ($conversations as $conv) {
1073 $this->assertObjectHasAttribute('id', $conv);
1074 $this->assertObjectHasAttribute('name', $conv);
1075 $this->assertObjectHasAttribute('subname', $conv);
1076 $this->assertObjectHasAttribute('imageurl', $conv);
1077 $this->assertObjectHasAttribute('type', $conv);
1078 $this->assertObjectHasAttribute('isfavourite', $conv);
1079 $this->assertObjectHasAttribute('membercount', $conv);
1080 $this->assertObjectHasAttribute('isread', $conv);
1081 $this->assertObjectHasAttribute('unreadcount', $conv);
1082 $this->assertObjectHasAttribute('members', $conv);
1083 foreach ($conv->members as $member) {
1084 $this->assertObjectHasAttribute('id', $member);
1085 $this->assertObjectHasAttribute('fullname', $member);
1086 $this->assertObjectHasAttribute('profileimageurl', $member);
1087 $this->assertObjectHasAttribute('profileimageurlsmall', $member);
1088 $this->assertObjectHasAttribute('isonline', $member);
1089 $this->assertObjectHasAttribute('showonlinestatus', $member);
1090 $this->assertObjectHasAttribute('isblocked', $member);
1091 $this->assertObjectHasAttribute('iscontact', $member);
1092 $this->assertObjectHasAttribute('isdeleted', $member);
1093 $this->assertObjectHasAttribute('canmessage', $member);
1094 $this->assertObjectHasAttribute('requirescontact', $member);
1095 $this->assertObjectHasAttribute('contactrequests', $member);
1097 $this->assertObjectHasAttribute('messages', $conv);
1098 foreach ($conv->messages as $message) {
1099 $this->assertObjectHasAttribute('id', $message);
1100 $this->assertObjectHasAttribute('useridfrom', $message);
1101 $this->assertObjectHasAttribute('text', $message);
1102 $this->assertObjectHasAttribute('timecreated', $message);
1108 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately.
1110 public function test_get_conversations_message_format() {
1111 global $DB;
1112 // Create some users.
1113 $user1 = self::getDataGenerator()->create_user();
1114 $user2 = self::getDataGenerator()->create_user();
1116 // Create conversation.
1117 $conversation = \core_message\api::create_conversation(
1118 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1119 [$user1->id, $user2->id]
1122 // Send some messages back and forth.
1123 $time = 1;
1124 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1);
1125 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2);
1127 // Verify the format of the html message.
1128 $message = $DB->get_record('messages', ['id' => $mid]);
1129 $expectedmessagetext = message_format_message_text($message);
1130 $conversations = \core_message\api::get_conversations($user1->id);
1131 $messages = $conversations[0]->messages;
1132 $this->assertEquals($expectedmessagetext, $messages[0]->text);
1136 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
1138 public function test_get_conversations_limit_offset() {
1139 // Get a bunch of conversations, some group, some individual and in different states.
1140 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1141 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1143 // Get all conversations for user1, limited to 1 result.
1144 $conversations = core_message\api::get_conversations($user1->id, 0, 1);
1146 // Verify the first conversation.
1147 $this->assertCount(1, $conversations);
1148 $conversation = array_shift($conversations);
1149 $this->assertEquals($conversation->id, $gc3->id);
1151 // Verify the next conversation.
1152 $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
1153 $this->assertCount(1, $conversations);
1154 $this->assertEquals($gc2->id, $conversations[0]->id);
1156 // Verify the next conversation.
1157 $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
1158 $this->assertCount(1, $conversations);
1159 $this->assertEquals($ic2->id, $conversations[0]->id);
1161 // Skip one and get both empty conversations.
1162 $conversations = \core_message\api::get_conversations($user1->id, 4, 2);
1163 $this->assertCount(2, $conversations);
1164 $this->assertEquals($gc5->id, $conversations[0]->id);
1165 $this->assertEmpty($conversations[0]->messages);
1166 $this->assertEquals($gc4->id, $conversations[1]->id);
1167 $this->assertEmpty($conversations[1]->messages);
1169 // Ask for an offset that doesn't exist and verify no conversations are returned.
1170 $conversations = \core_message\api::get_conversations($user1->id, 10, 1);
1171 $this->assertCount(0, $conversations);
1175 * Test verifying the type filtering behaviour of the
1177 public function test_get_conversations_type_filter() {
1178 // Get a bunch of conversations, some group, some individual and in different states.
1179 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1180 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1182 // Verify we can ask for only individual conversations.
1183 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1184 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1185 $this->assertCount(2, $conversations);
1187 // Verify we can ask for only group conversations.
1188 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1189 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP);
1190 $this->assertCount(4, $conversations);
1192 // Verify an exception is thrown if an unrecognized type is specified.
1193 $this->expectException(\moodle_exception::class);
1194 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 0);
1198 * Tests retrieving conversations when a conversation contains a deleted user.
1200 public function test_get_conversations_with_deleted_user() {
1201 // Get a bunch of conversations, some group, some individual and in different states.
1202 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1203 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1205 // Delete the second user and retrieve the conversations.
1206 // We should have 5, as $ic1 drops off the list.
1207 // Group conversations remain albeit with less members.
1208 delete_user($user2);
1209 $conversations = \core_message\api::get_conversations($user1->id);
1210 $this->assertCount(5, $conversations);
1211 $this->assertEquals($gc3->id, $conversations[0]->id);
1212 $this->assertcount(1, $conversations[0]->members);
1213 $this->assertEquals($gc2->id, $conversations[1]->id);
1214 $this->assertcount(1, $conversations[1]->members);
1215 $this->assertEquals($ic2->id, $conversations[2]->id);
1216 $this->assertEquals($gc5->id, $conversations[3]->id);
1217 $this->assertEquals($gc4->id, $conversations[4]->id);
1219 // Delete a user from a group conversation where that user had sent the most recent message.
1220 // This user will still be present in the members array, as will the message in the messages array.
1221 delete_user($user4);
1222 $conversations = \core_message\api::get_conversations($user1->id);
1223 $this->assertCount(5, $conversations);
1224 $this->assertEquals($gc2->id, $conversations[1]->id);
1225 $this->assertcount(1, $conversations[1]->members);
1226 $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
1227 $this->assertcount(1, $conversations[1]->messages);
1228 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1230 // Delete the third user and retrieve the conversations.
1231 // We should have 4, as $ic1, $ic2 drop off the list.
1232 // Group conversations remain albeit with less members.
1233 delete_user($user3);
1234 $conversations = \core_message\api::get_conversations($user1->id);
1235 $this->assertCount(4, $conversations);
1236 $this->assertEquals($gc3->id, $conversations[0]->id);
1237 $this->assertcount(1, $conversations[0]->members);
1238 $this->assertEquals($gc2->id, $conversations[1]->id);
1239 $this->assertcount(1, $conversations[1]->members);
1240 $this->assertEquals($gc5->id, $conversations[2]->id);
1241 $this->assertEquals($gc4->id, $conversations[3]->id);
1245 * Test confirming the behaviour of get_conversations() when users delete all messages.
1247 public function test_get_conversations_deleted_messages() {
1248 // Get a bunch of conversations, some group, some individual and in different states.
1249 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1250 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1252 $conversations = \core_message\api::get_conversations($user1->id);
1253 $this->assertCount(6, $conversations);
1255 // Delete all messages from a group conversation the user is in - it should be returned.
1256 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $gc2->id));
1257 $convmessages = \core_message\api::get_conversation_messages($user1->id, $gc2->id);
1258 $messages = $convmessages['messages'];
1259 foreach ($messages as $message) {
1260 \core_message\api::delete_message($user1->id, $message->id);
1262 $conversations = \core_message\api::get_conversations($user1->id);
1263 $this->assertCount(6, $conversations);
1264 $this->assertContains($gc2->id, array_column($conversations, 'id'));
1266 // Delete all messages from an individual conversation the user is in - it should not be returned.
1267 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $ic1->id));
1268 $convmessages = \core_message\api::get_conversation_messages($user1->id, $ic1->id);
1269 $messages = $convmessages['messages'];
1270 foreach ($messages as $message) {
1271 \core_message\api::delete_message($user1->id, $message->id);
1273 $conversations = \core_message\api::get_conversations($user1->id);
1274 $this->assertCount(5, $conversations);
1275 $this->assertNotContains($ic1->id, array_column($conversations, 'id'));
1279 * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single
1280 * favourite.
1282 public function test_get_conversations_favourite_conversations_single() {
1283 // Get a bunch of conversations, some group, some individual and in different states.
1284 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1285 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1287 // Mark a single conversation as favourites.
1288 \core_message\api::set_favourite_conversation($ic2->id, $user1->id);
1290 // Get the conversation, first with no restrictions, confirming the favourite status of the conversations.
1291 $conversations = \core_message\api::get_conversations($user1->id);
1292 $this->assertCount(6, $conversations);
1293 foreach ($conversations as $conv) {
1294 if (in_array($conv->id, [$ic2->id])) {
1295 $this->assertTrue($conv->isfavourite);
1296 } else {
1297 $this->assertFalse($conv->isfavourite);
1301 // Now, get ONLY favourite conversations.
1302 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1303 $this->assertCount(1, $conversations);
1304 foreach ($conversations as $conv) {
1305 $this->assertTrue($conv->isfavourite);
1306 $this->assertEquals($ic2->id, $conv->id);
1309 // Now, try ONLY favourites of type 'group'.
1310 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1311 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1312 $this->assertEmpty($conversations);
1314 // And NO favourite conversations.
1315 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1316 $this->assertCount(5, $conversations);
1317 foreach ($conversations as $conv) {
1318 $this->assertFalse($conv->isfavourite);
1319 $this->assertNotEquals($ic2, $conv->id);
1324 * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
1326 public function test_get_conversations_favourite_conversations() {
1327 // Get a bunch of conversations, some group, some individual and in different states.
1328 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1329 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1331 // Try to get ONLY favourite conversations, when no favourites exist.
1332 $this->assertEquals([], \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1334 // Try to get NO favourite conversations, when no favourites exist.
1335 $this->assertCount(6, \core_message\api::get_conversations($user1->id, 0, 20, null, false));
1337 // Mark a few conversations as favourites.
1338 \core_message\api::set_favourite_conversation($ic1->id, $user1->id);
1339 \core_message\api::set_favourite_conversation($gc2->id, $user1->id);
1340 \core_message\api::set_favourite_conversation($gc5->id, $user1->id);
1341 $favouriteids = [$ic1->id, $gc2->id, $gc5->id];
1343 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
1344 $conversations = \core_message\api::get_conversations($user1->id);
1345 $this->assertCount(6, $conversations);
1346 foreach ($conversations as $conv) {
1347 if (in_array($conv->id, $favouriteids)) {
1348 $this->assertTrue($conv->isfavourite);
1349 } else {
1350 $this->assertFalse($conv->isfavourite);
1354 // Now, get ONLY favourite conversations.
1355 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1356 $this->assertCount(3, $conversations);
1357 foreach ($conversations as $conv) {
1358 $this->assertTrue($conv->isfavourite);
1359 $this->assertNotFalse(array_search($conv->id, $favouriteids));
1362 // Now, try ONLY favourites of type 'group'.
1363 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1364 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1365 $this->assertCount(2, $conversations);
1366 foreach ($conversations as $conv) {
1367 $this->assertTrue($conv->isfavourite);
1368 $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id]));
1371 // And NO favourite conversations.
1372 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1373 $this->assertCount(3, $conversations);
1374 foreach ($conversations as $conv) {
1375 $this->assertFalse($conv->isfavourite);
1376 $this->assertFalse(array_search($conv->id, $favouriteids));
1381 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this
1382 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want
1383 * to confirm this happens.
1385 public function test_get_conversations_user_in_group_and_individual_chat() {
1386 $this->resetAfterTest();
1388 $user1 = self::getDataGenerator()->create_user();
1389 $user2 = self::getDataGenerator()->create_user();
1390 $user3 = self::getDataGenerator()->create_user();
1392 $conversation = \core_message\api::create_conversation(
1393 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1395 $user1->id,
1396 $user2->id
1398 'Individual conversation'
1401 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1403 $conversation = \core_message\api::create_conversation(
1404 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1406 $user1->id,
1407 $user2->id,
1409 'Group conversation'
1412 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1414 \core_message\api::create_contact_request($user1->id, $user2->id);
1415 \core_message\api::create_contact_request($user1->id, $user3->id);
1417 $conversations = \core_message\api::get_conversations($user2->id);
1419 $groupconversation = array_shift($conversations);
1420 $individualconversation = array_shift($conversations);
1422 $this->assertEquals('Group conversation', $groupconversation->name);
1423 $this->assertEquals('Individual conversation', $individualconversation->name);
1425 $this->assertCount(1, $groupconversation->members);
1426 $this->assertCount(1, $individualconversation->members);
1428 $groupmember = reset($groupconversation->members);
1429 $this->assertNull($groupmember->requirescontact);
1430 $this->assertNull($groupmember->canmessage);
1431 $this->assertEmpty($groupmember->contactrequests);
1433 $individualmember = reset($individualconversation->members);
1434 $this->assertNotNull($individualmember->requirescontact);
1435 $this->assertNotNull($individualmember->canmessage);
1436 $this->assertNotEmpty($individualmember->contactrequests);
1440 * Test verifying that group linked conversations are returned and contain a subname matching the course name.
1442 public function test_get_conversations_group_linked() {
1443 global $CFG;
1445 // Create some users.
1446 $user1 = self::getDataGenerator()->create_user();
1447 $user2 = self::getDataGenerator()->create_user();
1448 $user3 = self::getDataGenerator()->create_user();
1450 $course1 = $this->getDataGenerator()->create_course();
1452 // Create a group with a linked conversation and a valid image.
1453 $this->setAdminUser();
1454 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1455 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1456 $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1457 $group1 = $this->getDataGenerator()->create_group([
1458 'courseid' => $course1->id,
1459 'enablemessaging' => 1,
1460 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
1463 // Add users to group1.
1464 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1465 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
1467 // Verify the group with the image works as expected.
1468 $conversations = \core_message\api::get_conversations($user1->id);
1469 $this->assertEquals(2, $conversations[0]->membercount);
1470 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1471 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true);
1472 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1474 // Create a group with a linked conversation and without any image.
1475 $group2 = $this->getDataGenerator()->create_group([
1476 'courseid' => $course1->id,
1477 'enablemessaging' => 1,
1480 // Add users to group2.
1481 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1482 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
1484 // Verify the group without any image works as expected too.
1485 $conversations = \core_message\api::get_conversations($user3->id);
1486 $this->assertEquals(2, $conversations[0]->membercount);
1487 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1488 $groupimageurl = get_group_picture_url($group2, $group2->courseid, true);
1489 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1493 * The data provider for get_conversations_mixed.
1495 * This provides sets of data to for testing.
1496 * @return array
1498 public function get_conversations_mixed_provider() {
1499 return array(
1500 'Test that conversations with messages contacts is correctly ordered.' => array(
1501 'users' => array(
1502 'user1',
1503 'user2',
1504 'user3',
1506 'contacts' => array(
1508 'messages' => array(
1509 array(
1510 'from' => 'user1',
1511 'to' => 'user2',
1512 'state' => 'unread',
1513 'subject' => 'S1',
1515 array(
1516 'from' => 'user2',
1517 'to' => 'user1',
1518 'state' => 'unread',
1519 'subject' => 'S2',
1521 array(
1522 'from' => 'user1',
1523 'to' => 'user2',
1524 'state' => 'unread',
1525 'timecreated' => 0,
1526 'subject' => 'S3',
1528 array(
1529 'from' => 'user1',
1530 'to' => 'user3',
1531 'state' => 'read',
1532 'timemodifier' => 1,
1533 'subject' => 'S4',
1535 array(
1536 'from' => 'user3',
1537 'to' => 'user1',
1538 'state' => 'read',
1539 'timemodifier' => 1,
1540 'subject' => 'S5',
1542 array(
1543 'from' => 'user1',
1544 'to' => 'user3',
1545 'state' => 'read',
1546 'timecreated' => 0,
1547 'subject' => 'S6',
1550 'expectations' => array(
1551 'user1' => array(
1552 // User1 has conversed most recently with user3. The most recent message is M5.
1553 array(
1554 'messageposition' => 0,
1555 'with' => 'user3',
1556 'subject' => '<p>S5</p>',
1557 'unreadcount' => 0,
1559 // User1 has also conversed with user2. The most recent message is S2.
1560 array(
1561 'messageposition' => 1,
1562 'with' => 'user2',
1563 'subject' => '<p>S2</p>',
1564 'unreadcount' => 1,
1567 'user2' => array(
1568 // User2 has only conversed with user1. Their most recent shared message was S2.
1569 array(
1570 'messageposition' => 0,
1571 'with' => 'user1',
1572 'subject' => '<p>S2</p>',
1573 'unreadcount' => 2,
1576 'user3' => array(
1577 // User3 has only conversed with user1. Their most recent shared message was S5.
1578 array(
1579 'messageposition' => 0,
1580 'with' => 'user1',
1581 'subject' => '<p>S5</p>',
1582 'unreadcount' => 0,
1587 'Test conversations with a single user, where some messages are read and some are not.' => array(
1588 'users' => array(
1589 'user1',
1590 'user2',
1592 'contacts' => array(
1594 'messages' => array(
1595 array(
1596 'from' => 'user1',
1597 'to' => 'user2',
1598 'state' => 'read',
1599 'subject' => 'S1',
1601 array(
1602 'from' => 'user2',
1603 'to' => 'user1',
1604 'state' => 'read',
1605 'subject' => 'S2',
1607 array(
1608 'from' => 'user1',
1609 'to' => 'user2',
1610 'state' => 'unread',
1611 'timemodifier' => 1,
1612 'subject' => 'S3',
1614 array(
1615 'from' => 'user1',
1616 'to' => 'user2',
1617 'state' => 'unread',
1618 'timemodifier' => 1,
1619 'subject' => 'S4',
1622 'expectations' => array(
1623 // The most recent message between user1 and user2 was S4.
1624 'user1' => array(
1625 array(
1626 'messageposition' => 0,
1627 'with' => 'user2',
1628 'subject' => '<p>S4</p>',
1629 'unreadcount' => 0,
1632 'user2' => array(
1633 // The most recent message between user1 and user2 was S4.
1634 array(
1635 'messageposition' => 0,
1636 'with' => 'user1',
1637 'subject' => '<p>S4</p>',
1638 'unreadcount' => 2,
1643 'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1644 'are out of order' => array(
1645 // This can happen through a combination of factors including multi-master DB replication with messages
1646 // read somehow (e.g. API).
1647 'users' => array(
1648 'user1',
1649 'user2',
1651 'contacts' => array(
1653 'messages' => array(
1654 array(
1655 'from' => 'user1',
1656 'to' => 'user2',
1657 'state' => 'read',
1658 'subject' => 'S1',
1659 'timemodifier' => 1,
1661 array(
1662 'from' => 'user2',
1663 'to' => 'user1',
1664 'state' => 'read',
1665 'subject' => 'S2',
1666 'timemodifier' => 2,
1668 array(
1669 'from' => 'user1',
1670 'to' => 'user2',
1671 'state' => 'unread',
1672 'subject' => 'S3',
1674 array(
1675 'from' => 'user1',
1676 'to' => 'user2',
1677 'state' => 'unread',
1678 'subject' => 'S4',
1681 'expectations' => array(
1682 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1683 'user1' => array(
1684 array(
1685 'messageposition' => 0,
1686 'with' => 'user2',
1687 'subject' => '<p>S2</p>',
1688 'unreadcount' => 0,
1691 'user2' => array(
1692 array(
1693 'messageposition' => 0,
1694 'with' => 'user1',
1695 'subject' => '<p>S2</p>',
1696 'unreadcount' => 2
1701 'Test unread message count is correct for both users' => array(
1702 'users' => array(
1703 'user1',
1704 'user2',
1706 'contacts' => array(
1708 'messages' => array(
1709 array(
1710 'from' => 'user1',
1711 'to' => 'user2',
1712 'state' => 'read',
1713 'subject' => 'S1',
1714 'timemodifier' => 1,
1716 array(
1717 'from' => 'user2',
1718 'to' => 'user1',
1719 'state' => 'read',
1720 'subject' => 'S2',
1721 'timemodifier' => 2,
1723 array(
1724 'from' => 'user1',
1725 'to' => 'user2',
1726 'state' => 'read',
1727 'subject' => 'S3',
1728 'timemodifier' => 3,
1730 array(
1731 'from' => 'user1',
1732 'to' => 'user2',
1733 'state' => 'read',
1734 'subject' => 'S4',
1735 'timemodifier' => 4,
1737 array(
1738 'from' => 'user1',
1739 'to' => 'user2',
1740 'state' => 'unread',
1741 'subject' => 'S5',
1742 'timemodifier' => 5,
1744 array(
1745 'from' => 'user2',
1746 'to' => 'user1',
1747 'state' => 'unread',
1748 'subject' => 'S6',
1749 'timemodifier' => 6,
1751 array(
1752 'from' => 'user1',
1753 'to' => 'user2',
1754 'state' => 'unread',
1755 'subject' => 'S7',
1756 'timemodifier' => 7,
1758 array(
1759 'from' => 'user1',
1760 'to' => 'user2',
1761 'state' => 'unread',
1762 'subject' => 'S8',
1763 'timemodifier' => 8,
1766 'expectations' => array(
1767 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1768 'user1' => array(
1769 array(
1770 'messageposition' => 0,
1771 'with' => 'user2',
1772 'subject' => '<p>S8</p>',
1773 'unreadcount' => 1,
1776 'user2' => array(
1777 array(
1778 'messageposition' => 0,
1779 'with' => 'user1',
1780 'subject' => '<p>S8</p>',
1781 'unreadcount' => 3,
1790 * Test get_conversations with a mixture of messages.
1792 * @dataProvider get_conversations_mixed_provider
1793 * @param array $usersdata The list of users to create for this test.
1794 * @param array $messagesdata The list of messages to create.
1795 * @param array $expectations The list of expected outcomes.
1797 public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1798 global $DB;
1800 // Create all of the users.
1801 $users = array();
1802 foreach ($usersdata as $username) {
1803 $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1806 foreach ($contacts as $username => $contact) {
1807 foreach ($contact as $contactname => $blocked) {
1808 $record = new stdClass();
1809 $record->userid = $users[$username]->id;
1810 $record->contactid = $users[$contactname]->id;
1811 $record->blocked = $blocked;
1812 $record->id = $DB->insert_record('message_contacts', $record);
1816 $defaulttimecreated = time();
1817 foreach ($messagesdata as $messagedata) {
1818 $from = $users[$messagedata['from']];
1819 $to = $users[$messagedata['to']];
1820 $subject = $messagedata['subject'];
1822 if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
1823 $messageid = $this->send_fake_message($from, $to, $subject);
1824 } else {
1825 // If there is no state, or the state is not 'unread', assume the message is read.
1826 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
1829 $updatemessage = new stdClass();
1830 $updatemessage->id = $messageid;
1831 if (isset($messagedata['timecreated'])) {
1832 $updatemessage->timecreated = $messagedata['timecreated'];
1833 } else if (isset($messagedata['timemodifier'])) {
1834 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
1835 } else {
1836 $updatemessage->timecreated = $defaulttimecreated;
1839 $DB->update_record('messages', $updatemessage);
1842 foreach ($expectations as $username => $data) {
1843 // Get the recent conversations for the specified user.
1844 $user = $users[$username];
1845 $conversations = array_values(\core_message\api::get_conversations($user->id));
1846 foreach ($data as $expectation) {
1847 $otheruser = $users[$expectation['with']];
1848 $conversation = $conversations[$expectation['messageposition']];
1849 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
1850 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
1851 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
1857 * Tests retrieving contacts.
1859 public function test_get_contacts() {
1860 // Create some users.
1861 $user1 = self::getDataGenerator()->create_user();
1863 // Set as the user.
1864 $this->setUser($user1);
1866 $user2 = new stdClass();
1867 $user2->firstname = 'User';
1868 $user2->lastname = 'A';
1869 $user2 = self::getDataGenerator()->create_user($user2);
1871 $user3 = new stdClass();
1872 $user3->firstname = 'User';
1873 $user3->lastname = 'B';
1874 $user3 = self::getDataGenerator()->create_user($user3);
1876 $user4 = new stdClass();
1877 $user4->firstname = 'User';
1878 $user4->lastname = 'C';
1879 $user4 = self::getDataGenerator()->create_user($user4);
1881 $user5 = new stdClass();
1882 $user5->firstname = 'User';
1883 $user5->lastname = 'D';
1884 $user5 = self::getDataGenerator()->create_user($user5);
1886 // Add some users as contacts.
1887 \core_message\api::add_contact($user1->id, $user2->id);
1888 \core_message\api::add_contact($user1->id, $user3->id);
1889 \core_message\api::add_contact($user1->id, $user4->id);
1891 // Retrieve the contacts.
1892 $contacts = \core_message\api::get_contacts($user1->id);
1894 // Confirm the data is correct.
1895 $this->assertEquals(3, count($contacts));
1896 usort($contacts, ['static', 'sort_contacts']);
1898 $contact1 = $contacts[0];
1899 $contact2 = $contacts[1];
1900 $contact3 = $contacts[2];
1902 $this->assertEquals($user2->id, $contact1->userid);
1903 $this->assertEmpty($contact1->useridfrom);
1904 $this->assertFalse($contact1->ismessaging);
1905 $this->assertNull($contact1->lastmessage);
1906 $this->assertNull($contact1->messageid);
1907 $this->assertNull($contact1->isonline);
1908 $this->assertFalse($contact1->isread);
1909 $this->assertFalse($contact1->isblocked);
1910 $this->assertNull($contact1->unreadcount);
1912 $this->assertEquals($user3->id, $contact2->userid);
1913 $this->assertEmpty($contact2->useridfrom);
1914 $this->assertFalse($contact2->ismessaging);
1915 $this->assertNull($contact2->lastmessage);
1916 $this->assertNull($contact2->messageid);
1917 $this->assertNull($contact2->isonline);
1918 $this->assertFalse($contact2->isread);
1919 $this->assertFalse($contact2->isblocked);
1920 $this->assertNull($contact2->unreadcount);
1922 $this->assertEquals($user4->id, $contact3->userid);
1923 $this->assertEmpty($contact3->useridfrom);
1924 $this->assertFalse($contact3->ismessaging);
1925 $this->assertNull($contact3->lastmessage);
1926 $this->assertNull($contact3->messageid);
1927 $this->assertNull($contact3->isonline);
1928 $this->assertFalse($contact3->isread);
1929 $this->assertFalse($contact3->isblocked);
1930 $this->assertNull($contact3->unreadcount);
1934 * Tests retrieving messages.
1936 public function test_get_messages() {
1937 // Create some users.
1938 $user1 = self::getDataGenerator()->create_user();
1939 $user2 = self::getDataGenerator()->create_user();
1941 // The person doing the search.
1942 $this->setUser($user1);
1944 // Send some messages back and forth.
1945 $time = 1;
1946 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1947 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1948 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1949 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1951 // Retrieve the messages.
1952 $messages = \core_message\api::get_messages($user1->id, $user2->id);
1954 // Confirm the message data is correct.
1955 $this->assertEquals(4, count($messages));
1957 $message1 = $messages[0];
1958 $message2 = $messages[1];
1959 $message3 = $messages[2];
1960 $message4 = $messages[3];
1962 $this->assertEquals($user1->id, $message1->useridfrom);
1963 $this->assertEquals($user2->id, $message1->useridto);
1964 $this->assertTrue($message1->displayblocktime);
1965 $this->assertContains('Yo!', $message1->text);
1967 $this->assertEquals($user2->id, $message2->useridfrom);
1968 $this->assertEquals($user1->id, $message2->useridto);
1969 $this->assertFalse($message2->displayblocktime);
1970 $this->assertContains('Sup mang?', $message2->text);
1972 $this->assertEquals($user1->id, $message3->useridfrom);
1973 $this->assertEquals($user2->id, $message3->useridto);
1974 $this->assertFalse($message3->displayblocktime);
1975 $this->assertContains('Writing PHPUnit tests!', $message3->text);
1977 $this->assertEquals($user2->id, $message4->useridfrom);
1978 $this->assertEquals($user1->id, $message4->useridto);
1979 $this->assertFalse($message4->displayblocktime);
1980 $this->assertContains('Word.', $message4->text);
1984 * Tests retrieving conversation messages.
1986 public function test_get_conversation_messages() {
1987 // Create some users.
1988 $user1 = self::getDataGenerator()->create_user();
1989 $user2 = self::getDataGenerator()->create_user();
1991 // Create conversation.
1992 $conversation = \core_message\api::create_conversation(
1993 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1994 [$user1->id, $user2->id]
1997 // The person doing the search.
1998 $this->setUser($user1);
2000 // Send some messages back and forth.
2001 $time = 1;
2002 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2003 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2004 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2005 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2007 // Retrieve the messages.
2008 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2010 // Confirm the conversation id is correct.
2011 $this->assertEquals($conversation->id, $convmessages['id']);
2013 // Confirm the message data is correct.
2014 $messages = $convmessages['messages'];
2015 $this->assertEquals(4, count($messages));
2016 $message1 = $messages[0];
2017 $message2 = $messages[1];
2018 $message3 = $messages[2];
2019 $message4 = $messages[3];
2021 $this->assertEquals($user1->id, $message1->useridfrom);
2022 $this->assertContains('Yo!', $message1->text);
2024 $this->assertEquals($user2->id, $message2->useridfrom);
2025 $this->assertContains('Sup mang?', $message2->text);
2027 $this->assertEquals($user1->id, $message3->useridfrom);
2028 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2030 $this->assertEquals($user1->id, $message4->useridfrom);
2031 $this->assertContains('Word.', $message4->text);
2033 // Confirm the members data is correct.
2034 $members = $convmessages['members'];
2035 $this->assertEquals(2, count($members));
2039 * Tests retrieving group conversation messages.
2041 public function test_get_group_conversation_messages() {
2042 // Create some users.
2043 $user1 = self::getDataGenerator()->create_user();
2044 $user2 = self::getDataGenerator()->create_user();
2045 $user3 = self::getDataGenerator()->create_user();
2046 $user4 = self::getDataGenerator()->create_user();
2048 // Create group conversation.
2049 $conversation = \core_message\api::create_conversation(
2050 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2051 [$user1->id, $user2->id, $user3->id, $user4->id]
2054 // The person doing the search.
2055 $this->setUser($user1);
2057 // Send some messages back and forth.
2058 $time = 1;
2059 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2060 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2061 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2062 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2063 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
2065 // Retrieve the messages.
2066 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2068 // Confirm the conversation id is correct.
2069 $this->assertEquals($conversation->id, $convmessages['id']);
2071 // Confirm the message data is correct.
2072 $messages = $convmessages['messages'];
2073 $this->assertEquals(5, count($messages));
2075 $message1 = $messages[0];
2076 $message2 = $messages[1];
2077 $message3 = $messages[2];
2078 $message4 = $messages[3];
2079 $message5 = $messages[4];
2081 $this->assertEquals($user1->id, $message1->useridfrom);
2082 $this->assertContains('Yo!', $message1->text);
2084 $this->assertEquals($user2->id, $message2->useridfrom);
2085 $this->assertContains('Sup mang?', $message2->text);
2087 $this->assertEquals($user3->id, $message3->useridfrom);
2088 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2090 $this->assertEquals($user1->id, $message4->useridfrom);
2091 $this->assertContains('Word.', $message4->text);
2093 $this->assertEquals($user2->id, $message5->useridfrom);
2094 $this->assertContains('Yeah!', $message5->text);
2096 // Confirm the members data is correct.
2097 $members = $convmessages['members'];
2098 $this->assertEquals(3, count($members));
2102 * Test verifying the sorting param for get_conversation_messages is respected().
2104 public function test_get_conversation_messages_sorting() {
2105 // Create some users.
2106 $user1 = self::getDataGenerator()->create_user();
2107 $user2 = self::getDataGenerator()->create_user();
2108 $user3 = self::getDataGenerator()->create_user();
2110 // Create conversations - 1 group and 1 individual.
2111 $conversation = \core_message\api::create_conversation(
2112 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2113 [$user1->id, $user2->id]
2115 $conversation2 = \core_message\api::create_conversation(
2116 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2117 [$user1->id, $user2->id, $user3->id]
2120 // Send some messages back and forth.
2121 $time = 1;
2122 $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2123 $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2124 $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2125 $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2127 $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
2128 $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
2129 $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
2130 $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
2132 // The person doing the search.
2133 $this->setUser($user1);
2135 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2136 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2137 $messages = $convmessages['messages'];
2138 $this->assertEquals($m1id, $messages[0]->id);
2139 $this->assertEquals($m2id, $messages[1]->id);
2140 $this->assertEquals($m3id, $messages[2]->id);
2141 $this->assertEquals($m4id, $messages[3]->id);
2143 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2144 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
2145 $messages = $convmessages['messages'];
2146 $this->assertEquals($m1id, $messages[3]->id);
2147 $this->assertEquals($m2id, $messages[2]->id);
2148 $this->assertEquals($m3id, $messages[1]->id);
2149 $this->assertEquals($m4id, $messages[0]->id);
2151 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2152 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
2153 $messages = $convmessages['messages'];
2154 $this->assertEquals($gm1id, $messages[0]->id);
2155 $this->assertEquals($gm2id, $messages[1]->id);
2156 $this->assertEquals($gm3id, $messages[2]->id);
2157 $this->assertEquals($gm4id, $messages[3]->id);
2159 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2160 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
2161 $messages = $convmessages['messages'];
2162 $this->assertEquals($gm1id, $messages[3]->id);
2163 $this->assertEquals($gm2id, $messages[2]->id);
2164 $this->assertEquals($gm3id, $messages[1]->id);
2165 $this->assertEquals($gm4id, $messages[0]->id);
2169 * Test retrieving conversation messages by providing a minimum timecreated value.
2171 public function test_get_conversation_messages_time_from_only() {
2172 // Create some users.
2173 $user1 = self::getDataGenerator()->create_user();
2174 $user2 = self::getDataGenerator()->create_user();
2175 $user3 = self::getDataGenerator()->create_user();
2176 $user4 = self::getDataGenerator()->create_user();
2178 // Create group conversation.
2179 $conversation = \core_message\api::create_conversation(
2180 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2181 [$user1->id, $user2->id, $user3->id, $user4->id]
2184 // The person doing the search.
2185 $this->setUser($user1);
2187 // Send some messages back and forth.
2188 $time = 1;
2189 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2190 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2191 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2192 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2194 // Retrieve the messages from $time, which should be all of them.
2195 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
2197 // Confirm the conversation id is correct.
2198 $this->assertEquals($conversation->id, $convmessages['id']);
2200 // Confirm the message data is correct.
2201 $messages = $convmessages['messages'];
2202 $this->assertEquals(4, count($messages));
2204 $message1 = $messages[0];
2205 $message2 = $messages[1];
2206 $message3 = $messages[2];
2207 $message4 = $messages[3];
2209 $this->assertContains('Message 1', $message1->text);
2210 $this->assertContains('Message 2', $message2->text);
2211 $this->assertContains('Message 3', $message3->text);
2212 $this->assertContains('Message 4', $message4->text);
2214 // Confirm the members data is correct.
2215 $members = $convmessages['members'];
2216 $this->assertEquals(3, count($members));
2218 // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2219 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2220 'timecreated ASC', $time + 3);
2222 // Confirm the conversation id is correct.
2223 $this->assertEquals($conversation->id, $convmessages['id']);
2225 // Confirm the message data is correct.
2226 $messages = $convmessages['messages'];
2227 $this->assertEquals(2, count($messages));
2229 $message1 = $messages[0];
2230 $message2 = $messages[1];
2232 $this->assertContains('Message 3', $message1->text);
2233 $this->assertContains('Message 4', $message2->text);
2235 // Confirm the members data is correct.
2236 $members = $convmessages['members'];
2237 $this->assertEquals(2, count($members));
2241 * Test retrieving conversation messages by providing a maximum timecreated value.
2243 public function test_get_conversation_messages_time_to_only() {
2244 // Create some users.
2245 $user1 = self::getDataGenerator()->create_user();
2246 $user2 = self::getDataGenerator()->create_user();
2247 $user3 = self::getDataGenerator()->create_user();
2248 $user4 = self::getDataGenerator()->create_user();
2250 // Create group conversation.
2251 $conversation = \core_message\api::create_conversation(
2252 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2253 [$user1->id, $user2->id, $user3->id, $user4->id]
2256 // The person doing the search.
2257 $this->setUser($user1);
2259 // Send some messages back and forth.
2260 $time = 1;
2261 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2262 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2263 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2264 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2266 // Retrieve the messages up until $time + 4, which should be all of them.
2267 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2268 0, $time + 4);
2270 // Confirm the conversation id is correct.
2271 $this->assertEquals($conversation->id, $convmessages['id']);
2273 // Confirm the message data is correct.
2274 $messages = $convmessages['messages'];
2275 $this->assertEquals(4, count($messages));
2277 $message1 = $messages[0];
2278 $message2 = $messages[1];
2279 $message3 = $messages[2];
2280 $message4 = $messages[3];
2282 $this->assertContains('Message 1', $message1->text);
2283 $this->assertContains('Message 2', $message2->text);
2284 $this->assertContains('Message 3', $message3->text);
2285 $this->assertContains('Message 4', $message4->text);
2287 // Confirm the members data is correct.
2288 $members = $convmessages['members'];
2289 $this->assertEquals(3, count($members));
2291 // Retrieve the messages up until $time + 2, which should be the first two.
2292 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2293 0, $time + 2);
2295 // Confirm the conversation id is correct.
2296 $this->assertEquals($conversation->id, $convmessages['id']);
2298 // Confirm the message data is correct.
2299 $messages = $convmessages['messages'];
2300 $this->assertEquals(2, count($messages));
2302 $message1 = $messages[0];
2303 $message2 = $messages[1];
2305 $this->assertContains('Message 1', $message1->text);
2306 $this->assertContains('Message 2', $message2->text);
2308 // Confirm the members data is correct.
2309 $members = $convmessages['members'];
2310 $this->assertEquals(2, count($members));
2314 * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
2316 public function test_get_conversation_messages_time_from_and_to() {
2317 // Create some users.
2318 $user1 = self::getDataGenerator()->create_user();
2319 $user2 = self::getDataGenerator()->create_user();
2320 $user3 = self::getDataGenerator()->create_user();
2321 $user4 = self::getDataGenerator()->create_user();
2323 // Create group conversation.
2324 $conversation = \core_message\api::create_conversation(
2325 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2326 [$user1->id, $user2->id, $user3->id, $user4->id]
2329 // The person doing the search.
2330 $this->setUser($user1);
2332 // Send some messages back and forth.
2333 $time = 1;
2334 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2335 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2336 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2337 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2339 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2340 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2341 'timecreated ASC', $time + 2, $time + 3);
2343 // Confirm the conversation id is correct.
2344 $this->assertEquals($conversation->id, $convmessages['id']);
2346 // Confirm the message data is correct.
2347 $messages = $convmessages['messages'];
2348 $this->assertEquals(2, count($messages));
2350 $message1 = $messages[0];
2351 $message2 = $messages[1];
2353 $this->assertContains('Message 2', $message1->text);
2354 $this->assertContains('Message 3', $message2->text);
2356 // Confirm the members data is correct.
2357 $members = $convmessages['members'];
2358 $this->assertEquals(2, count($members));
2363 * Test retrieving conversation messages by providing a limitfrom value.
2365 public function test_get_conversation_messages_limitfrom_only() {
2366 // Create some users.
2367 $user1 = self::getDataGenerator()->create_user();
2368 $user2 = self::getDataGenerator()->create_user();
2369 $user3 = self::getDataGenerator()->create_user();
2370 $user4 = self::getDataGenerator()->create_user();
2372 // Create group conversation.
2373 $conversation = \core_message\api::create_conversation(
2374 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2375 [$user1->id, $user2->id, $user3->id, $user4->id]
2378 // The person doing the search.
2379 $this->setUser($user1);
2381 // Send some messages back and forth.
2382 $time = 1;
2383 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2384 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2385 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2386 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2388 // Retrieve the messages from $time, which should be all of them.
2389 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
2391 // Confirm the conversation id is correct.
2392 $messages = $convmessages['messages'];
2393 $this->assertEquals($conversation->id, $convmessages['id']);
2395 // Confirm the message data is correct.
2396 $this->assertEquals(2, count($messages));
2398 $message1 = $messages[0];
2399 $message2 = $messages[1];
2401 $this->assertContains('Message 3', $message1->text);
2402 $this->assertContains('Message 4', $message2->text);
2404 // Confirm the members data is correct.
2405 $members = $convmessages['members'];
2406 $this->assertEquals(2, count($members));
2410 * Test retrieving conversation messages by providing a limitnum value.
2412 public function test_get_conversation_messages_limitnum() {
2413 // Create some users.
2414 $user1 = self::getDataGenerator()->create_user();
2415 $user2 = self::getDataGenerator()->create_user();
2416 $user3 = self::getDataGenerator()->create_user();
2417 $user4 = self::getDataGenerator()->create_user();
2419 // Create group conversation.
2420 $conversation = \core_message\api::create_conversation(
2421 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2422 [$user1->id, $user2->id, $user3->id, $user4->id]
2425 // The person doing the search.
2426 $this->setUser($user1);
2428 // Send some messages back and forth.
2429 $time = 1;
2430 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2431 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2432 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2433 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2435 // Retrieve the messages from $time, which should be all of them.
2436 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
2438 // Confirm the conversation id is correct.
2439 $messages = $convmessages['messages'];
2440 $this->assertEquals($conversation->id, $convmessages['id']);
2442 // Confirm the message data is correct.
2443 $messages = $convmessages['messages'];
2444 $this->assertEquals(1, count($messages));
2446 $message1 = $messages[0];
2448 $this->assertContains('Message 3', $message1->text);
2450 // Confirm the members data is correct.
2451 $members = $convmessages['members'];
2452 $this->assertEquals(1, count($members));
2456 * Tests retrieving most recent message.
2458 public function test_get_most_recent_message() {
2459 // Create some users.
2460 $user1 = self::getDataGenerator()->create_user();
2461 $user2 = self::getDataGenerator()->create_user();
2463 // The person doing the search.
2464 $this->setUser($user1);
2466 // Send some messages back and forth.
2467 $time = 1;
2468 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2469 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2470 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2471 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2473 // Retrieve the most recent messages.
2474 $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
2476 // Check the results are correct.
2477 $this->assertEquals($user2->id, $message->useridfrom);
2478 $this->assertEquals($user1->id, $message->useridto);
2479 $this->assertContains('Word.', $message->text);
2483 * Tests retrieving most recent conversation message.
2485 public function test_get_most_recent_conversation_message() {
2486 // Create some users.
2487 $user1 = self::getDataGenerator()->create_user();
2488 $user2 = self::getDataGenerator()->create_user();
2489 $user3 = self::getDataGenerator()->create_user();
2491 // Create group conversation.
2492 $conversation = \core_message\api::create_conversation(
2493 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2494 [$user1->id, $user2->id, $user3->id]
2497 // The person getting the most recent conversation message.
2498 $this->setUser($user1);
2500 // Send some messages back and forth.
2501 $time = 1;
2502 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2503 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2504 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2505 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2507 // Retrieve the most recent messages.
2508 $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
2510 // Check the results are correct.
2511 $this->assertEquals($user2->id, $message->useridfrom);
2512 $this->assertContains('Word.', $message->text);
2516 * Tests retrieving a user's profile.
2518 public function test_get_profile() {
2519 // Create some users.
2520 $user1 = self::getDataGenerator()->create_user();
2522 $user2 = new stdClass();
2523 $user2->country = 'AU';
2524 $user2->city = 'Perth';
2525 $user2 = self::getDataGenerator()->create_user($user2);
2527 // The person doing the search.
2528 $this->setUser($user1);
2530 // Get the profile.
2531 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2533 $this->assertEquals($user2->id, $profile->userid);
2534 $this->assertEmpty($profile->email);
2535 $this->assertEmpty($profile->country);
2536 $this->assertEmpty($profile->city);
2537 $this->assertEquals(fullname($user2), $profile->fullname);
2538 $this->assertNull($profile->isonline);
2539 $this->assertFalse($profile->isblocked);
2540 $this->assertFalse($profile->iscontact);
2544 * Tests retrieving a user's profile.
2546 public function test_get_profile_as_admin() {
2547 // The person doing the search.
2548 $this->setAdminUser();
2550 // Create some users.
2551 $user1 = self::getDataGenerator()->create_user();
2553 $user2 = new stdClass();
2554 $user2->country = 'AU';
2555 $user2->city = 'Perth';
2556 $user2 = self::getDataGenerator()->create_user($user2);
2558 // Get the profile.
2559 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2561 $this->assertEquals($user2->id, $profile->userid);
2562 $this->assertEquals($user2->email, $profile->email);
2563 $this->assertEquals($user2->country, $profile->country);
2564 $this->assertEquals($user2->city, $profile->city);
2565 $this->assertEquals(fullname($user2), $profile->fullname);
2566 $this->assertFalse($profile->isonline);
2567 $this->assertFalse($profile->isblocked);
2568 $this->assertFalse($profile->iscontact);
2572 * Tests checking if a user can mark all messages as read.
2574 public function test_can_mark_all_messages_as_read() {
2575 // Set as the admin.
2576 $this->setAdminUser();
2578 // Create some users.
2579 $user1 = self::getDataGenerator()->create_user();
2580 $user2 = self::getDataGenerator()->create_user();
2581 $user3 = self::getDataGenerator()->create_user();
2583 // Send some messages back and forth.
2584 $time = 1;
2585 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2586 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2587 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2588 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2590 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2592 // The admin can do anything.
2593 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2595 // Set as the user 1.
2596 $this->setUser($user1);
2598 // The user can mark the messages as he is in the conversation.
2599 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2601 // User 1 can not mark the messages read for user 2.
2602 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
2604 // This user is not a part of the conversation.
2605 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
2609 * Tests checking if a user can delete a conversation.
2611 public function test_can_delete_conversation() {
2612 // Set as the admin.
2613 $this->setAdminUser();
2615 // Create some users.
2616 $user1 = self::getDataGenerator()->create_user();
2617 $user2 = self::getDataGenerator()->create_user();
2619 // Send some messages back and forth.
2620 $time = 1;
2621 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2622 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2623 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2624 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2626 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2628 // The admin can do anything.
2629 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2631 // Set as the user 1.
2632 $this->setUser($user1);
2634 // They can delete their own messages.
2635 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2637 // They can't delete someone elses.
2638 $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
2642 * Tests deleting a conversation.
2644 public function test_delete_conversation() {
2645 global $DB;
2647 // Create some users.
2648 $user1 = self::getDataGenerator()->create_user();
2649 $user2 = self::getDataGenerator()->create_user();
2651 // The person doing the search.
2652 $this->setUser($user1);
2654 // Send some messages back and forth.
2655 $time = 1;
2656 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2657 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2658 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2659 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2661 // Delete the conversation as user 1.
2662 \core_message\api::delete_conversation($user1->id, $user2->id);
2663 $this->assertDebuggingCalled();
2665 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2666 $this->assertCount(4, $muas);
2667 // Sort by id.
2668 ksort($muas);
2670 $mua1 = array_shift($muas);
2671 $mua2 = array_shift($muas);
2672 $mua3 = array_shift($muas);
2673 $mua4 = array_shift($muas);
2675 $this->assertEquals($user1->id, $mua1->userid);
2676 $this->assertEquals($m1id, $mua1->messageid);
2677 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2679 $this->assertEquals($user1->id, $mua2->userid);
2680 $this->assertEquals($m2id, $mua2->messageid);
2681 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2683 $this->assertEquals($user1->id, $mua3->userid);
2684 $this->assertEquals($m3id, $mua3->messageid);
2685 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2687 $this->assertEquals($user1->id, $mua4->userid);
2688 $this->assertEquals($m4id, $mua4->messageid);
2689 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2693 * Tests deleting a conversation by conversation id.
2695 public function test_delete_conversation_by_id() {
2696 global $DB;
2698 // Create some users.
2699 $user1 = self::getDataGenerator()->create_user();
2700 $user2 = self::getDataGenerator()->create_user();
2702 // The person doing the search.
2703 $this->setUser($user1);
2705 // Send some messages back and forth.
2706 $time = 1;
2707 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2708 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2709 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2710 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2712 // Delete the conversation as user 1.
2713 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2714 \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2716 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2717 $this->assertCount(4, $muas);
2718 // Sort by id.
2719 ksort($muas);
2721 $mua1 = array_shift($muas);
2722 $mua2 = array_shift($muas);
2723 $mua3 = array_shift($muas);
2724 $mua4 = array_shift($muas);
2726 $this->assertEquals($user1->id, $mua1->userid);
2727 $this->assertEquals($m1id, $mua1->messageid);
2728 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2730 $this->assertEquals($user1->id, $mua2->userid);
2731 $this->assertEquals($m2id, $mua2->messageid);
2732 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2734 $this->assertEquals($user1->id, $mua3->userid);
2735 $this->assertEquals($m3id, $mua3->messageid);
2736 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2738 $this->assertEquals($user1->id, $mua4->userid);
2739 $this->assertEquals($m4id, $mua4->messageid);
2740 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2744 * Tests counting unread conversations.
2746 public function test_count_unread_conversations() {
2747 $this->resetAfterTest(true);
2749 // Create some users.
2750 $user1 = self::getDataGenerator()->create_user();
2751 $user2 = self::getDataGenerator()->create_user();
2752 $user3 = self::getDataGenerator()->create_user();
2753 $user4 = self::getDataGenerator()->create_user();
2755 // The person wanting the conversation count.
2756 $this->setUser($user1);
2758 // Send some messages back and forth, have some different conversations with different users.
2759 $this->send_fake_message($user1, $user2, 'Yo!');
2760 $this->send_fake_message($user2, $user1, 'Sup mang?');
2761 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2762 $this->send_fake_message($user2, $user1, 'Word.');
2764 $this->send_fake_message($user1, $user3, 'Booyah');
2765 $this->send_fake_message($user3, $user1, 'Whaaat?');
2766 $this->send_fake_message($user1, $user3, 'Nothing.');
2767 $this->send_fake_message($user3, $user1, 'Cool.');
2769 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2770 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2771 $this->send_fake_message($user1, $user4, 'Dope.');
2773 // Check the amount for the current user.
2774 $this->assertEquals(3, core_message\api::count_unread_conversations());
2776 // Check the amount for the second user.
2777 $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2781 * Tests deleting a conversation.
2783 public function test_get_all_message_preferences() {
2784 $user = self::getDataGenerator()->create_user();
2785 $this->setUser($user);
2787 // Set a couple of preferences to test.
2788 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2789 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2791 $processors = get_message_processors();
2792 $providers = message_get_providers_for_user($user->id);
2793 $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2795 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2796 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2800 * Tests the user can post a message.
2802 public function test_can_post_message() {
2803 // Create some users.
2804 $user1 = self::getDataGenerator()->create_user();
2805 $user2 = self::getDataGenerator()->create_user();
2807 // Set as the first user.
2808 $this->setUser($user1);
2810 // With the default privacy setting, users can't message them.
2811 $this->assertFalse(\core_message\api::can_post_message($user2));
2813 // Enrol users to the same course.
2814 $course = $this->getDataGenerator()->create_course();
2815 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2816 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2817 // After enrolling users to the course, they should be able to message them with the default privacy setting.
2818 $this->assertTrue(\core_message\api::can_post_message($user2));
2822 * Tests the user can't post a message without proper capability.
2824 public function test_can_post_message_without_sendmessage_cap() {
2825 global $DB;
2827 // Create some users.
2828 $user1 = self::getDataGenerator()->create_user();
2829 $user2 = self::getDataGenerator()->create_user();
2831 // Set as the user 1.
2832 $this->setUser($user1);
2834 // Remove the capability to send a message.
2835 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
2836 unassign_capability('moodle/site:sendmessage', $roleids['user'],
2837 context_system::instance());
2839 // Check that we can not post a message without the capability.
2840 $this->assertFalse(\core_message\api::can_post_message($user2));
2844 * Tests the user can post a message when they are contact.
2846 public function test_can_post_message_when_contact() {
2847 // Create some users.
2848 $user1 = self::getDataGenerator()->create_user();
2849 $user2 = self::getDataGenerator()->create_user();
2851 // Set as the first user.
2852 $this->setUser($user1);
2854 // Check that we can not send user2 a message.
2855 $this->assertFalse(\core_message\api::can_post_message($user2));
2857 // Add users as contacts.
2858 \core_message\api::add_contact($user1->id, $user2->id);
2860 // Check that the return result is now true.
2861 $this->assertTrue(\core_message\api::can_post_message($user2));
2865 * Tests the user can't post a message if they are not a contact and the user
2866 * has requested messages only from contacts.
2868 public function test_can_post_message_when_not_contact() {
2869 // Create some users.
2870 $user1 = self::getDataGenerator()->create_user();
2871 $user2 = self::getDataGenerator()->create_user();
2873 // Set as the first user.
2874 $this->setUser($user1);
2876 // Set the second user's preference to not receive messages from non-contacts.
2877 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2879 // Check that we can not send user 2 a message.
2880 $this->assertFalse(\core_message\api::can_post_message($user2));
2884 * Tests the user can't post a message if they are blocked.
2886 public function test_can_post_message_when_blocked() {
2887 // Create some users.
2888 $user1 = self::getDataGenerator()->create_user();
2889 $user2 = self::getDataGenerator()->create_user();
2891 // Set the user.
2892 $this->setUser($user1);
2894 // Block the second user.
2895 \core_message\api::block_user($user1->id, $user2->id);
2897 // Check that the second user can no longer send the first user a message.
2898 $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
2902 * Tests the user can post a message when site-wide messaging setting is enabled,
2903 * even if they are not a contact and are not members of the same course.
2905 public function test_can_post_message_site_messaging_setting() {
2906 // Create some users.
2907 $user1 = self::getDataGenerator()->create_user();
2908 $user2 = self::getDataGenerator()->create_user();
2910 // Set as the first user.
2911 $this->setUser($user1);
2913 // By default, user only can be messaged by contacts and members of any of his/her courses.
2914 $this->assertFalse(\core_message\api::can_post_message($user2));
2916 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2917 set_config('messagingallusers', true);
2919 // Set the second user's preference to receive messages from everybody.
2920 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
2922 // Check that we can send user2 a message.
2923 $this->assertTrue(\core_message\api::can_post_message($user2));
2925 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
2926 // and members sharing a course with her.
2927 set_config('messagingallusers', false);
2929 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
2930 $this->assertFalse(\core_message\api::can_post_message($user2));
2932 // Enrol users to the same course.
2933 $course = $this->getDataGenerator()->create_course();
2934 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2935 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2936 // Check that we can send user2 a message because they are sharing a course.
2937 $this->assertTrue(\core_message\api::can_post_message($user2));
2939 // Set the second user's preference to receive messages only from contacts.
2940 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2941 // Check that now the user2 can't be contacted because user1 is not their contact.
2942 $this->assertFalse(\core_message\api::can_post_message($user2));
2944 // Make contacts user1 and user2.
2945 \core_message\api::add_contact($user2->id, $user1->id);
2946 // Check that we can send user2 a message because they are contacts.
2947 $this->assertTrue(\core_message\api::can_post_message($user2));
2951 * Tests the user with the messageanyuser capability can post a message.
2953 public function test_can_post_message_with_messageanyuser_cap() {
2954 global $DB;
2956 // Create some users.
2957 $teacher1 = self::getDataGenerator()->create_user();
2958 $student1 = self::getDataGenerator()->create_user();
2959 $student2 = self::getDataGenerator()->create_user();
2961 // Create users not enrolled in any course.
2962 $user1 = self::getDataGenerator()->create_user();
2964 // Create a course.
2965 $course1 = $this->getDataGenerator()->create_course();
2967 // Enrol the users in the course.
2968 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
2969 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
2970 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
2972 // Set some student preferences to not receive messages from non-contacts.
2973 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
2975 // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
2976 $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
2977 // Check that the teacher can't contact user1 because it's not his teacher.
2978 $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
2980 // Remove the messageanyuser capability from the course1 for teachers.
2981 $coursecontext = context_course::instance($course1->id);
2982 $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
2983 assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
2984 $coursecontext->mark_dirty();
2986 // Check that we can't send user1 a message because they are not contacts.
2987 $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
2988 // However, teacher can message student2 because they are sharing a course.
2989 $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
2993 * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings.
2995 public function test_can_send_message_to_conversation_basic() {
2996 // Create some users.
2997 $user1 = self::getDataGenerator()->create_user();
2998 $user2 = self::getDataGenerator()->create_user();
2999 $user3 = self::getDataGenerator()->create_user();
3001 // Create an individual conversation between user1 and user2.
3002 $ic1 = \core_message\api::create_conversation(
3003 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3005 $user1->id,
3006 $user2->id
3010 // Create a group conversation between and users 1, 2 and 3.
3011 $gc1 = \core_message\api::create_conversation(
3012 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3014 $user1->id,
3015 $user2->id,
3016 $user3->id
3020 // For group conversations, there are no user privacy checks, so only membership in the conversation is needed.
3021 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3023 // For individual conversations, the default privacy setting of 'only contacts and course members' applies.
3024 // Users are not in the same course, nor are they contacts, so messages cannot be sent.
3025 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3027 // Enrol the users into the same course.
3028 $course = $this->getDataGenerator()->create_course();
3029 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3030 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3032 // After enrolling users to the course, they should be able to message them with the default privacy setting.
3033 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3037 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability.
3039 public function test_can_send_message_to_conversation_sendmessage_cap() {
3040 global $DB;
3042 $user1 = self::getDataGenerator()->create_user();
3043 $user2 = self::getDataGenerator()->create_user();
3044 $user3 = self::getDataGenerator()->create_user();
3046 // Enrol the users into the same course.
3047 $course = $this->getDataGenerator()->create_course();
3048 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3049 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3050 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3052 // Create an individual conversation between user1 and user2.
3053 $ic1 = \core_message\api::create_conversation(
3054 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3056 $user1->id,
3057 $user2->id
3061 // Group conversation between and users 1, 2 and 3.
3062 $gc1 = \core_message\api::create_conversation(
3063 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3065 $user1->id,
3066 $user2->id,
3067 $user3->id
3071 // Default settings - user1 can send a message to both conversations.
3072 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3073 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3075 // Remove the capability to send a message.
3076 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3077 unassign_capability('moodle/site:sendmessage', $roleids['user'], context_system::instance());
3079 // Verify that a user cannot send a message to either an individual or a group conversation.
3080 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3081 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3085 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the messageanyuser capability.
3087 public function test_can_send_message_to_conversation_messageanyuser_cap() {
3088 global $DB;
3090 $user1 = self::getDataGenerator()->create_user();
3091 $user2 = self::getDataGenerator()->create_user();
3092 $user3 = self::getDataGenerator()->create_user();
3094 // Enrol the users into the same course.
3095 $course = $this->getDataGenerator()->create_course();
3096 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3097 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3098 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3100 // Create an individual conversation between user1 and user2.
3101 $ic1 = \core_message\api::create_conversation(
3102 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3104 $user1->id,
3105 $user2->id
3109 // Group conversation between and users 1, 2 and 3.
3110 $gc1 = \core_message\api::create_conversation(
3111 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3113 $user1->id,
3114 $user2->id,
3115 $user3->id
3119 // Update the message preference for user2, so they can only be messaged by contacts.
3120 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3122 // Verify that the user cannot be contacted in the individual conversation and that groups are unaffected.
3123 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3124 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3126 // Assign the 'messageanyuser' capability to user1 at system context.
3127 $systemcontext = context_system::instance();
3128 $authenticateduser = $DB->get_record('role', ['shortname' => 'user']);
3129 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, $systemcontext->id);
3131 // Check that user1 can now message user2 due to the capability, and that group conversations is again unaffected.
3132 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3133 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3137 * Test verifying that users cannot send messages to conversations they are not a part of.
3139 public function test_can_post_message_to_conversation_non_member() {
3140 // Create some users.
3141 $user1 = self::getDataGenerator()->create_user();
3142 $user2 = self::getDataGenerator()->create_user();
3143 $user3 = self::getDataGenerator()->create_user();
3144 $user4 = self::getDataGenerator()->create_user();
3146 // Enrol the users into the same course.
3147 $course = $this->getDataGenerator()->create_course();
3148 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3149 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3150 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3151 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
3153 // Create an individual conversation between user1 and user2.
3154 $ic1 = \core_message\api::create_conversation(
3155 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3157 $user1->id,
3158 $user2->id
3162 // Create a group conversation between and users 1, 2 and 3.
3163 $gc1 = \core_message\api::create_conversation(
3164 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3166 $user1->id,
3167 $user2->id,
3168 $user3->id
3172 // Verify, non members cannot send a message.
3173 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user4->id, $gc1->id));
3174 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user4->id, $ic1->id));
3178 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts only.
3180 public function test_can_send_message_to_conversation_privacy_contacts_only() {
3181 // Create some users.
3182 $user1 = self::getDataGenerator()->create_user();
3183 $user2 = self::getDataGenerator()->create_user();
3184 $user3 = self::getDataGenerator()->create_user();
3186 // Create an individual conversation between user1 and user2.
3187 $ic1 = \core_message\api::create_conversation(
3188 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3190 $user1->id,
3191 $user2->id
3195 // Create a group conversation between and users 1, 2 and 3.
3196 $gc1 = \core_message\api::create_conversation(
3197 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3199 $user1->id,
3200 $user2->id,
3201 $user3->id
3205 // Set the message privacy preference to 'contacts only' for user 2.
3206 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3208 // Verify that user1 cannot send a message to the individual conversation, but that the group conversation is unaffected.
3209 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3210 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3212 // Now, simulate a contact request (and approval) between user1 and user2.
3213 \core_message\api::create_contact_request($user1->id, $user2->id);
3214 \core_message\api::confirm_contact_request($user1->id, $user2->id);
3216 // Verify user1 can now message user2 again via their individual conversation.
3217 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3221 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts / course members.
3223 public function test_can_send_message_to_conversation_privacy_contacts_course() {
3224 // Create some users.
3225 $user1 = self::getDataGenerator()->create_user();
3226 $user2 = self::getDataGenerator()->create_user();
3227 $user3 = self::getDataGenerator()->create_user();
3229 // Set the message privacy preference to 'contacts + course members' for user 2.
3230 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
3232 // Create an individual conversation between user1 and user2.
3233 $ic1 = \core_message\api::create_conversation(
3234 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3236 $user1->id,
3237 $user2->id
3241 // Create a group conversation between and users 1, 2 and 3.
3242 $gc1 = \core_message\api::create_conversation(
3243 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3245 $user1->id,
3246 $user2->id,
3247 $user3->id
3251 // Verify that users in a group conversation can message one another (i.e. privacy controls ignored).
3252 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3254 // Verify that user1 can not message user2 unless they are either contacts, or share a course.
3255 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3257 // Enrol the users into the same course.
3258 $course = $this->getDataGenerator()->create_course();
3259 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3260 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3261 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3263 // Verify that user1 can send a message to user2, based on the shared course, without being a contact.
3264 $this->assertFalse(\core_message\api::is_contact($user1->id, $user2->id));
3265 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3269 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to any user.
3271 public function test_can_send_message_to_conversation_privacy_sitewide() {
3272 // Create some users.
3273 $user1 = self::getDataGenerator()->create_user();
3274 $user2 = self::getDataGenerator()->create_user();
3275 $user3 = self::getDataGenerator()->create_user();
3277 // Create an individual conversation between user1 and user2.
3278 $ic1 = \core_message\api::create_conversation(
3279 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3281 $user1->id,
3282 $user2->id
3286 // Create a group conversation between and users 1, 2 and 3.
3287 $gc1 = \core_message\api::create_conversation(
3288 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3290 $user1->id,
3291 $user2->id,
3292 $user3->id
3296 // By default, the messaging privacy dictates that users can only be contacted by contacts, and members of their courses.
3297 // Verify also, that groups are not restricted in this way.
3298 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3299 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3301 // Enable site-wide messagging privacy setting.
3302 // This enables a privacy option for users, allowing them to choose to be contactable by anybody on the site.
3303 set_config('messagingallusers', true);
3305 // Set the second user's preference to receive messages from everybody.
3306 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
3308 // Check that user1 can send user2 a message, and that the group conversation is unaffected.
3309 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3310 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3312 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3313 // and members sharing a course with her.
3314 set_config('messagingallusers', false);
3316 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3317 // Verify also that the group conversation is unaffected.
3318 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3319 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3323 * Test verifying the behaviour of the can_send_message_to_conversation method when a user is blocked.
3325 public function test_can_send_message_to_conversation_when_blocked() {
3326 $user1 = self::getDataGenerator()->create_user();
3327 $user2 = self::getDataGenerator()->create_user();
3328 $user3 = self::getDataGenerator()->create_user();
3330 // Create an individual conversation between user1 and user2.
3331 $ic1 = \core_message\api::create_conversation(
3332 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3334 $user1->id,
3335 $user2->id
3339 // Create a group conversation between and users 1, 2 and 3.
3340 $gc1 = \core_message\api::create_conversation(
3341 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3343 $user1->id,
3344 $user2->id,
3345 $user3->id
3349 // Enrol the users into the same course.
3350 $course = $this->getDataGenerator()->create_course();
3351 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3352 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3353 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3355 // Block the second user.
3356 \core_message\api::block_user($user1->id, $user2->id);
3358 // Check that user2 can not send user1 a message in their individual conversation.
3359 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user2->id, $ic1->id));
3361 // Verify that group conversations are unaffected.
3362 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3363 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user2->id, $gc1->id));
3367 * Tests get_user_privacy_messaging_preference method.
3369 public function test_get_user_privacy_messaging_preference() {
3370 // Create some users.
3371 $user1 = self::getDataGenerator()->create_user();
3372 $user2 = self::getDataGenerator()->create_user();
3373 $user3 = self::getDataGenerator()->create_user();
3375 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3376 set_config('messagingallusers', true);
3378 // Set some user preferences.
3379 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
3380 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3382 // Check the returned value for each user.
3383 $this->assertEquals(
3384 \core_message\api::MESSAGE_PRIVACY_SITE,
3385 \core_message\api::get_user_privacy_messaging_preference($user1->id)
3387 $this->assertEquals(
3388 \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
3389 \core_message\api::get_user_privacy_messaging_preference($user2->id)
3391 $this->assertEquals(
3392 \core_message\api::MESSAGE_PRIVACY_SITE,
3393 \core_message\api::get_user_privacy_messaging_preference($user3->id)
3396 // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
3397 set_config('messagingallusers', false);
3399 // Check the returned value for each user.
3400 $this->assertEquals(
3401 \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
3402 \core_message\api::get_user_privacy_messaging_preference($user1->id)
3404 $this->assertEquals(
3405 \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
3406 \core_message\api::get_user_privacy_messaging_preference($user2->id)
3408 $this->assertEquals(
3409 \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
3410 \core_message\api::get_user_privacy_messaging_preference($user3->id)
3415 * Tests that when blocking messages from non-contacts is enabled that
3416 * non-contacts trying to send a message return false.
3418 public function test_is_user_non_contact_blocked() {
3419 // Create some users.
3420 $user1 = self::getDataGenerator()->create_user();
3421 $user2 = self::getDataGenerator()->create_user();
3423 // Set as the first user.
3424 $this->setUser($user1);
3426 // By default, user only can be messaged by contacts and members of any of his/her courses.
3427 $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
3428 $this->assertDebuggingCalled();
3430 // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
3431 // messages from everybody.
3432 set_config('messagingallusers', true);
3433 // Check that the return result is now false because any site user can contact him/her.
3434 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
3435 $this->assertDebuggingCalled();
3437 // Set the second user's preference to not receive messages from non-contacts.
3438 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3439 // Check that the return result is still true (because is even more restricted).
3440 $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
3441 $this->assertDebuggingCalled();
3443 // Add the first user as a contact for the second user.
3444 \core_message\api::add_contact($user2->id, $user1->id);
3446 // Check that the return result is now false.
3447 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
3448 $this->assertDebuggingCalled();
3450 // Set the second user's preference to receive messages from course members.
3451 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
3452 // Check that the return result is still false (because $user1 is still his/her contact).
3453 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
3454 $this->assertDebuggingCalled();
3458 * Tests that we return true when a user is blocked, or false
3459 * if they are not blocked.
3461 public function test_is_user_blocked() {
3462 // Create some users.
3463 $user1 = self::getDataGenerator()->create_user();
3464 $user2 = self::getDataGenerator()->create_user();
3466 // Set the user.
3467 $this->setUser($user1);
3469 // User shouldn't be blocked.
3470 $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
3471 $this->assertDebuggingCalled();
3473 // Block the user.
3474 \core_message\api::block_user($user1->id, $user2->id);
3476 // User should be blocked.
3477 $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
3478 $this->assertDebuggingCalled();
3480 // Unblock the user.
3481 \core_message\api::unblock_user($user1->id, $user2->id);
3482 $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
3483 $this->assertDebuggingCalled();
3487 * Tests that the admin is not blocked even if someone has chosen to block them.
3489 public function test_is_user_blocked_as_admin() {
3490 // Create a user.
3491 $user1 = self::getDataGenerator()->create_user();
3493 // Set the user.
3494 $this->setUser($user1);
3496 // Block the admin user.
3497 \core_message\api::block_user($user1->id, 2);
3499 // Now change to the admin user.
3500 $this->setAdminUser();
3502 // As the admin you should still be able to send messages to the user.
3503 $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
3504 $this->assertDebuggingCalled();
3508 * Tes get_message_processor api.
3510 public function test_get_message_processor() {
3511 $processors = get_message_processors(true);
3512 if (empty($processors)) {
3513 $this->markTestSkipped("No message processors found");
3516 $name = key($processors);
3517 $processor = current($processors);
3518 $testprocessor = \core_message\api::get_message_processor($name);
3519 $this->assertEquals($processor->name, $testprocessor->name);
3520 $this->assertEquals($processor->enabled, $testprocessor->enabled);
3521 $this->assertEquals($processor->available, $testprocessor->available);
3522 $this->assertEquals($processor->configured, $testprocessor->configured);
3524 // Disable processor and test.
3525 \core_message\api::update_processor_status($testprocessor, 0);
3526 $testprocessor = \core_message\api::get_message_processor($name, true);
3527 $this->assertEmpty($testprocessor);
3528 $testprocessor = \core_message\api::get_message_processor($name);
3529 $this->assertEquals($processor->name, $testprocessor->name);
3530 $this->assertEquals(0, $testprocessor->enabled);
3532 // Enable again and test.
3533 \core_message\api::update_processor_status($testprocessor, 1);
3534 $testprocessor = \core_message\api::get_message_processor($name, true);
3535 $this->assertEquals($processor->name, $testprocessor->name);
3536 $this->assertEquals(1, $testprocessor->enabled);
3537 $testprocessor = \core_message\api::get_message_processor($name);
3538 $this->assertEquals($processor->name, $testprocessor->name);
3539 $this->assertEquals(1, $testprocessor->enabled);
3543 * Test method update_processor_status.
3545 public function test_update_processor_status() {
3546 $processors = get_message_processors();
3547 if (empty($processors)) {
3548 $this->markTestSkipped("No message processors found");
3550 $name = key($processors);
3551 $testprocessor = current($processors);
3553 // Enable.
3554 \core_message\api::update_processor_status($testprocessor, 1);
3555 $testprocessor = \core_message\api::get_message_processor($name);
3556 $this->assertEquals(1, $testprocessor->enabled);
3558 // Disable.
3559 \core_message\api::update_processor_status($testprocessor, 0);
3560 $testprocessor = \core_message\api::get_message_processor($name);
3561 $this->assertEquals(0, $testprocessor->enabled);
3563 // Enable again.
3564 \core_message\api::update_processor_status($testprocessor, 1);
3565 $testprocessor = \core_message\api::get_message_processor($name);
3566 $this->assertEquals(1, $testprocessor->enabled);
3570 * Test method is_user_enabled.
3572 public function is_user_enabled() {
3573 $processors = get_message_processors();
3574 if (empty($processors)) {
3575 $this->markTestSkipped("No message processors found");
3577 $name = key($processors);
3578 $testprocessor = current($processors);
3580 // Enable.
3581 \core_message\api::update_processor_status($testprocessor, 1);
3582 $status = \core_message\api::is_processor_enabled($name);
3583 $this->assertEquals(1, $status);
3585 // Disable.
3586 \core_message\api::update_processor_status($testprocessor, 0);
3587 $status = \core_message\api::is_processor_enabled($name);
3588 $this->assertEquals(0, $status);
3590 // Enable again.
3591 \core_message\api::update_processor_status($testprocessor, 1);
3592 $status = \core_message\api::is_processor_enabled($name);
3593 $this->assertEquals(1, $status);
3597 * Test retrieving messages by providing a minimum timecreated value.
3599 public function test_get_messages_time_from_only() {
3600 // Create some users.
3601 $user1 = self::getDataGenerator()->create_user();
3602 $user2 = self::getDataGenerator()->create_user();
3604 // The person doing the search.
3605 $this->setUser($user1);
3607 // Send some messages back and forth.
3608 $time = 1;
3609 $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
3610 $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
3611 $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
3612 $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
3614 // Retrieve the messages from $time, which should be all of them.
3615 $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
3617 // Confirm the message data is correct.
3618 $this->assertEquals(4, count($messages));
3620 $message1 = $messages[0];
3621 $message2 = $messages[1];
3622 $message3 = $messages[2];
3623 $message4 = $messages[3];
3625 $this->assertContains('Message 1', $message1->text);
3626 $this->assertContains('Message 2', $message2->text);
3627 $this->assertContains('Message 3', $message3->text);
3628 $this->assertContains('Message 4', $message4->text);
3630 // Retrieve the messages from $time + 3, which should only be the 2 last messages.
3631 $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
3633 // Confirm the message data is correct.
3634 $this->assertEquals(2, count($messages));
3636 $message1 = $messages[0];
3637 $message2 = $messages[1];
3639 $this->assertContains('Message 3', $message1->text);
3640 $this->assertContains('Message 4', $message2->text);
3644 * Test retrieving messages by providing a maximum timecreated value.
3646 public function test_get_messages_time_to_only() {
3647 // Create some users.
3648 $user1 = self::getDataGenerator()->create_user();
3649 $user2 = self::getDataGenerator()->create_user();
3651 // The person doing the search.
3652 $this->setUser($user1);
3654 // Send some messages back and forth.
3655 $time = 1;
3656 $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
3657 $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
3658 $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
3659 $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
3661 // Retrieve the messages up until $time + 4, which should be all of them.
3662 $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
3664 // Confirm the message data is correct.
3665 $this->assertEquals(4, count($messages));
3667 $message1 = $messages[0];
3668 $message2 = $messages[1];
3669 $message3 = $messages[2];
3670 $message4 = $messages[3];
3672 $this->assertContains('Message 1', $message1->text);
3673 $this->assertContains('Message 2', $message2->text);
3674 $this->assertContains('Message 3', $message3->text);
3675 $this->assertContains('Message 4', $message4->text);
3677 // Retrieve the messages up until $time + 2, which should be the first two.
3678 $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
3680 // Confirm the message data is correct.
3681 $this->assertEquals(2, count($messages));
3683 $message1 = $messages[0];
3684 $message2 = $messages[1];
3686 $this->assertContains('Message 1', $message1->text);
3687 $this->assertContains('Message 2', $message2->text);
3691 * Test retrieving messages by providing a minimum and maximum timecreated value.
3693 public function test_get_messages_time_from_and_to() {
3694 // Create some users.
3695 $user1 = self::getDataGenerator()->create_user();
3696 $user2 = self::getDataGenerator()->create_user();
3698 // The person doing the search.
3699 $this->setUser($user1);
3701 // Send some messages back and forth.
3702 $time = 1;
3703 $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
3704 $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
3705 $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
3706 $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
3708 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
3709 $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
3711 // Confirm the message data is correct.
3712 $this->assertEquals(2, count($messages));
3714 $message1 = $messages[0];
3715 $message2 = $messages[1];
3717 $this->assertContains('Message 2', $message1->text);
3718 $this->assertContains('Message 3', $message2->text);
3722 * Test returning blocked users.
3724 public function test_get_blocked_users() {
3725 global $USER;
3727 // Set this user as the admin.
3728 $this->setAdminUser();
3730 // Create a user to add to the admin's contact list.
3731 $user1 = $this->getDataGenerator()->create_user();
3732 $user2 = $this->getDataGenerator()->create_user();
3734 // Add users to the admin's contact list.
3735 \core_message\api::block_user($USER->id, $user2->id);
3737 $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
3739 // Block other user.
3740 \core_message\api::block_user($USER->id, $user1->id);
3741 $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
3743 // Test deleting users.
3744 delete_user($user1);
3745 $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
3749 * Test returning contacts with unread message count.
3751 public function test_get_contacts_with_unread_message_count() {
3752 global $DB;
3754 $user1 = self::getDataGenerator()->create_user();
3755 $user2 = self::getDataGenerator()->create_user();
3756 $user3 = self::getDataGenerator()->create_user();
3757 $user4 = self::getDataGenerator()->create_user();
3759 // Add the users to each of their contacts.
3760 \core_message\api::add_contact($user1->id, $user2->id);
3761 \core_message\api::add_contact($user2->id, $user3->id);
3763 $this->send_fake_message($user1, $user2);
3764 $this->send_fake_message($user1, $user2);
3765 $this->send_fake_message($user1, $user2);
3766 $message4id = $this->send_fake_message($user1, $user2);
3768 $this->send_fake_message($user3, $user2);
3769 $message6id = $this->send_fake_message($user3, $user2);
3770 $this->send_fake_message($user3, $user2);
3771 $this->send_fake_message($user3, $user2);
3772 $this->send_fake_message($user3, $user2);
3774 // Send a message that should never be included as the user is not a contact.
3775 $this->send_fake_message($user4, $user2);
3777 // Get the contacts and the unread message count.
3778 $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
3780 // Confirm the size is correct.
3781 $this->assertCount(2, $messages);
3782 ksort($messages);
3784 $messageinfo1 = array_shift($messages);
3785 $messageinfo2 = array_shift($messages);
3787 $this->assertEquals($user1->id, $messageinfo1->id);
3788 $this->assertEquals(4, $messageinfo1->messagecount);
3789 $this->assertEquals($user3->id, $messageinfo2->id);
3790 $this->assertEquals(5, $messageinfo2->messagecount);
3792 // Mark some of the messages as read.
3793 $m4 = $DB->get_record('messages', ['id' => $message4id]);
3794 $m6 = $DB->get_record('messages', ['id' => $message6id]);
3795 \core_message\api::mark_message_as_read($user2->id, $m4);
3796 \core_message\api::mark_message_as_read($user2->id, $m6);
3798 // Get the contacts and the unread message count.
3799 $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
3801 // Confirm the size is correct.
3802 $this->assertCount(2, $messages);
3803 ksort($messages);
3805 // Confirm read messages are not included.
3806 $messageinfo1 = array_shift($messages);
3807 $messageinfo2 = array_shift($messages);
3808 $this->assertEquals($user1->id, $messageinfo1->id);
3809 $this->assertEquals(3, $messageinfo1->messagecount);
3810 $this->assertEquals($user3->id, $messageinfo2->id);
3811 $this->assertEquals(4, $messageinfo2->messagecount);
3813 // Now, let's populate the database with messages from user2 to user 1.
3814 $this->send_fake_message($user2, $user1);
3815 $this->send_fake_message($user2, $user1);
3816 $messageid = $this->send_fake_message($user2, $user1);
3818 // Send a message that should never be included as the user is not a contact.
3819 $this->send_fake_message($user4, $user1);
3821 // Get the contacts and the unread message count.
3822 $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
3824 // Confirm the size is correct.
3825 $this->assertCount(1, $messages);
3826 $messageinfo1 = array_shift($messages);
3827 $this->assertEquals($user2->id, $messageinfo1->id);
3828 $this->assertEquals(3, $messageinfo1->messagecount);
3830 // Mark the last message as read.
3831 $m = $DB->get_record('messages', ['id' => $messageid]);
3832 \core_message\api::mark_message_as_read($user1->id, $m);
3834 $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
3836 // Confirm the size is correct.
3837 $this->assertCount(1, $messages);
3839 // Confirm read messages are not included.
3840 $messageinfo1 = array_shift($messages);
3841 $this->assertEquals($user2->id, $messageinfo1->id);
3842 $this->assertEquals(2, $messageinfo1->messagecount);
3846 * Test returning contacts with unread message count when there are no messages.
3848 public function test_get_contacts_with_unread_message_count_no_messages() {
3849 $user1 = self::getDataGenerator()->create_user();
3850 $user2 = self::getDataGenerator()->create_user();
3852 // Add the users to each of their contacts.
3853 \core_message\api::add_contact($user2->id, $user1->id);
3855 // Check we get the correct message count.
3856 $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
3858 // Confirm the size is correct.
3859 $this->assertCount(1, $messages);
3861 $messageinfo = array_shift($messages);
3863 $this->assertEquals($user1->id, $messageinfo->id);
3864 $this->assertEquals(0, $messageinfo->messagecount);
3868 * Test returning non-contacts with unread message count.
3870 public function test_get_non_contacts_with_unread_message_count() {
3871 global $DB;
3873 $user1 = self::getDataGenerator()->create_user();
3874 $user2 = self::getDataGenerator()->create_user();
3875 $user3 = self::getDataGenerator()->create_user();
3876 $user4 = self::getDataGenerator()->create_user();
3878 // Add a user to the contact list of the users we are testing this function with.
3879 \core_message\api::add_contact($user1->id, $user4->id);
3880 \core_message\api::add_contact($user2->id, $user4->id);
3882 $this->send_fake_message($user1, $user2);
3883 $this->send_fake_message($user1, $user2);
3884 $this->send_fake_message($user1, $user2);
3885 $message4id = $this->send_fake_message($user1, $user2);
3887 $this->send_fake_message($user3, $user2);
3888 $message6id = $this->send_fake_message($user3, $user2);
3889 $this->send_fake_message($user3, $user2);
3890 $this->send_fake_message($user3, $user2);
3891 $this->send_fake_message($user3, $user2);
3893 // Send a message that should never be included as the user is a contact.
3894 $this->send_fake_message($user4, $user2);
3896 // Get the non-contacts and the unread message count.
3897 $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
3899 // Check we get the correct message count.
3900 ksort($messages);
3901 $this->assertCount(2, $messages);
3902 $messageinfo1 = array_shift($messages);
3903 $messageinfo2 = array_shift($messages);
3904 $this->assertEquals($user1->id, $messageinfo1->id);
3905 $this->assertEquals(4, $messageinfo1->messagecount);
3906 $this->assertEquals($user3->id, $messageinfo2->id);
3907 $this->assertEquals(5, $messageinfo2->messagecount);
3909 // Mark some of the messages as read.
3910 $m4 = $DB->get_record('messages', ['id' => $message4id]);
3911 $m6 = $DB->get_record('messages', ['id' => $message6id]);
3912 \core_message\api::mark_message_as_read($user2->id, $m4);
3913 \core_message\api::mark_message_as_read($user2->id, $m6);
3915 // Get the non-contacts and the unread message count.
3916 $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
3918 // Check the marked message is not returned in the message count.
3919 ksort($messages);
3920 $this->assertCount(2, $messages);
3921 $messageinfo1 = array_shift($messages);
3922 $messageinfo2 = array_shift($messages);
3923 $this->assertEquals($user1->id, $messageinfo1->id);
3924 $this->assertEquals(3, $messageinfo1->messagecount);
3925 $this->assertEquals($user3->id, $messageinfo2->id);
3926 $this->assertEquals(4, $messageinfo2->messagecount);
3928 // Now, let's populate the database with messages from user2 to user 1.
3929 $this->send_fake_message($user2, $user1);
3930 $this->send_fake_message($user2, $user1);
3931 $messageid = $this->send_fake_message($user2, $user1);
3933 // Send a message that should never be included as the user is a contact.
3934 $this->send_fake_message($user4, $user1);
3936 // Get the non-contacts and the unread message count.
3937 $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
3939 // Confirm the size is correct.
3940 $this->assertCount(1, $messages);
3941 $messageinfo1 = array_shift($messages);
3942 $this->assertEquals($user2->id, $messageinfo1->id);
3943 $this->assertEquals(3, $messageinfo1->messagecount);
3945 // Mark the last message as read.
3946 $m = $DB->get_record('messages', ['id' => $messageid]);
3947 \core_message\api::mark_message_as_read($user1->id, $m);
3949 // Get the non-contacts and the unread message count.
3950 $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
3952 // Check the marked message is not returned in the message count.
3953 $this->assertCount(1, $messages);
3954 $messageinfo1 = array_shift($messages);
3955 $this->assertEquals($user2->id, $messageinfo1->id);
3956 $this->assertEquals(2, $messageinfo1->messagecount);
3960 * Test marking a message as read.
3962 public function test_mark_message_as_read() {
3963 global $DB;
3965 $user1 = self::getDataGenerator()->create_user();
3966 $user2 = self::getDataGenerator()->create_user();
3968 $this->send_fake_message($user1, $user2);
3969 $m2id = $this->send_fake_message($user1, $user2);
3970 $this->send_fake_message($user2, $user1);
3971 $m4id = $this->send_fake_message($user2, $user1);
3973 $m2 = $DB->get_record('messages', ['id' => $m2id]);
3974 $m4 = $DB->get_record('messages', ['id' => $m4id]);
3975 \core_message\api::mark_message_as_read($user2->id, $m2, 11);
3976 \core_message\api::mark_message_as_read($user1->id, $m4, 12);
3978 // Confirm there are two user actions.
3979 $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
3980 $this->assertEquals(2, count($muas));
3982 // Confirm they are correct.
3983 $mua1 = array_shift($muas);
3984 $mua2 = array_shift($muas);
3986 // Confirm first action.
3987 $this->assertEquals($user2->id, $mua1->userid);
3988 $this->assertEquals($m2id, $mua1->messageid);
3989 $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
3990 $this->assertEquals(11, $mua1->timecreated);
3992 // Confirm second action.
3993 $this->assertEquals($user1->id, $mua2->userid);
3994 $this->assertEquals($m4id, $mua2->messageid);
3995 $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
3996 $this->assertEquals(12, $mua2->timecreated);
4000 * Test marking a notification as read.
4002 public function test_mark_notification_as_read() {
4003 global $DB;
4005 $user1 = self::getDataGenerator()->create_user();
4006 $user2 = self::getDataGenerator()->create_user();
4008 $this->send_fake_message($user1, $user2, 'Notification 1', 1);
4009 $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
4010 $this->send_fake_message($user2, $user1, 'Notification 3', 1);
4011 $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
4013 $n2 = $DB->get_record('notifications', ['id' => $n2id]);
4014 $n4 = $DB->get_record('notifications', ['id' => $n4id]);
4016 \core_message\api::mark_notification_as_read($n2, 11);
4017 \core_message\api::mark_notification_as_read($n4, 12);
4019 // Retrieve the notifications.
4020 $n2 = $DB->get_record('notifications', ['id' => $n2id]);
4021 $n4 = $DB->get_record('notifications', ['id' => $n4id]);
4023 // Confirm they have been marked as read.
4024 $this->assertEquals(11, $n2->timeread);
4025 $this->assertEquals(12, $n4->timeread);
4029 * Test a conversation is not returned if there is none.
4031 public function test_get_conversation_between_users_no_conversation() {
4032 $user1 = self::getDataGenerator()->create_user();
4033 $user2 = self::getDataGenerator()->create_user();
4035 $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
4039 * Test we can return a conversation that exists between users.
4041 public function test_get_conversation_between_users_with_existing_conversation() {
4042 $user1 = self::getDataGenerator()->create_user();
4043 $user2 = self::getDataGenerator()->create_user();
4045 $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
4046 $this->assertDebuggingCalled();
4048 $this->assertEquals($conversationid,
4049 \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
4053 * Test count_conversation_members for non existing conversation.
4055 public function test_count_conversation_members_no_existing_conversation() {
4056 $this->assertEquals(0,
4057 \core_message\api::count_conversation_members(0));
4061 * Test count_conversation_members for existing conversation.
4063 public function test_count_conversation_members_existing_conversation() {
4064 $user1 = self::getDataGenerator()->create_user();
4065 $user2 = self::getDataGenerator()->create_user();
4067 $conversation = \core_message\api::create_conversation(
4068 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4070 $user1->id,
4071 $user2->id
4074 $conversationid = $conversation->id;
4076 $this->assertEquals(2,
4077 \core_message\api::count_conversation_members($conversationid));
4081 * Test add_members_to_conversation for an individual conversation.
4083 public function test_add_members_to_individual_conversation() {
4084 $user1 = self::getDataGenerator()->create_user();
4085 $user2 = self::getDataGenerator()->create_user();
4086 $user3 = self::getDataGenerator()->create_user();
4088 $conversation = \core_message\api::create_conversation(
4089 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4091 $user1->id,
4092 $user2->id
4095 $conversationid = $conversation->id;
4097 $this->expectException('moodle_exception');
4098 \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
4102 * Test add_members_to_conversation for existing conversation.
4104 public function test_add_members_to_existing_conversation() {
4105 $user1 = self::getDataGenerator()->create_user();
4106 $user2 = self::getDataGenerator()->create_user();
4107 $user3 = self::getDataGenerator()->create_user();
4109 $conversation = \core_message\api::create_conversation(
4110 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4112 $user1->id,
4113 $user2->id
4116 $conversationid = $conversation->id;
4118 $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
4119 $this->assertEquals(3,
4120 \core_message\api::count_conversation_members($conversationid));
4124 * Test add_members_to_conversation for non existing conversation.
4126 public function test_add_members_to_no_existing_conversation() {
4127 $user1 = self::getDataGenerator()->create_user();
4129 // Throw dml_missing_record_exception for non existing conversation.
4130 $this->expectException('dml_missing_record_exception');
4131 \core_message\api::add_members_to_conversation([$user1->id], 0);
4135 * Test add_member_to_conversation for non existing user.
4137 public function test_add_members_to_no_existing_user() {
4138 $user1 = self::getDataGenerator()->create_user();
4139 $user2 = self::getDataGenerator()->create_user();
4141 $conversation = \core_message\api::create_conversation(
4142 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4144 $user1->id,
4145 $user2->id
4148 $conversationid = $conversation->id;
4150 // Don't throw an error for non existing user, but don't add it as a member.
4151 $this->assertNull(\core_message\api::add_members_to_conversation([0], $conversationid));
4152 $this->assertEquals(2,
4153 \core_message\api::count_conversation_members($conversationid));
4157 * Test add_members_to_conversation for current conversation member.
4159 public function test_add_members_to_current_conversation_member() {
4160 $user1 = self::getDataGenerator()->create_user();
4161 $user2 = self::getDataGenerator()->create_user();
4163 $conversation = \core_message\api::create_conversation(
4164 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4166 $user1->id,
4167 $user2->id
4170 $conversationid = $conversation->id;
4172 // Don't add as a member a user that is already conversation member.
4173 $this->assertNull(\core_message\api::add_members_to_conversation([$user1->id], $conversationid));
4174 $this->assertEquals(2,
4175 \core_message\api::count_conversation_members($conversationid));
4179 * Test add_members_to_conversation for multiple users.
4181 public function test_add_members_for_multiple_users() {
4182 $user1 = self::getDataGenerator()->create_user();
4183 $user2 = self::getDataGenerator()->create_user();
4184 $user3 = self::getDataGenerator()->create_user();
4185 $user4 = self::getDataGenerator()->create_user();
4187 $conversation = \core_message\api::create_conversation(
4188 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4190 $user1->id,
4191 $user2->id
4194 $conversationid = $conversation->id;
4196 $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
4197 $this->assertEquals(4,
4198 \core_message\api::count_conversation_members($conversationid));
4202 * Test add_members_to_conversation for multiple users, included non existing and current conversation members
4204 public function test_add_members_for_multiple_not_valid_users() {
4205 $user1 = self::getDataGenerator()->create_user();
4206 $user2 = self::getDataGenerator()->create_user();
4207 $user3 = self::getDataGenerator()->create_user();
4209 $conversation = \core_message\api::create_conversation(
4210 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4212 $user1->id,
4213 $user2->id
4216 $conversationid = $conversation->id;
4218 // Don't throw errors, but don't add as members users don't exist or are already conversation members.
4219 $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
4220 $this->assertEquals(3,
4221 \core_message\api::count_conversation_members($conversationid));
4225 * Test remove_members_from_conversation for individual conversation.
4227 public function test_remove_members_from_individual_conversation() {
4228 $user1 = self::getDataGenerator()->create_user();
4229 $user2 = self::getDataGenerator()->create_user();
4231 $conversation = \core_message\api::create_conversation(
4232 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4234 $user1->id,
4235 $user2->id
4238 $conversationid = $conversation->id;
4240 $this->expectException('moodle_exception');
4241 \core_message\api::remove_members_from_conversation([$user1->id], $conversationid);
4245 * Test remove_members_from_conversation for existing conversation.
4247 public function test_remove_members_from_existing_conversation() {
4248 $user1 = self::getDataGenerator()->create_user();
4249 $user2 = self::getDataGenerator()->create_user();
4251 $conversation = \core_message\api::create_conversation(
4252 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4254 $user1->id,
4255 $user2->id
4258 $conversationid = $conversation->id;
4260 $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id], $conversationid));
4261 $this->assertEquals(1,
4262 \core_message\api::count_conversation_members($conversationid));
4266 * Test remove_members_from_conversation for non existing conversation.
4268 public function test_remove_members_from_no_existing_conversation() {
4269 $user1 = self::getDataGenerator()->create_user();
4271 // Throw dml_missing_record_exception for non existing conversation.
4272 $this->expectException('dml_missing_record_exception');
4273 \core_message\api::remove_members_from_conversation([$user1->id], 0);
4277 * Test remove_members_from_conversation for non existing user.
4279 public function test_remove_members_for_no_existing_user() {
4280 $user1 = self::getDataGenerator()->create_user();
4281 $user2 = self::getDataGenerator()->create_user();
4283 $conversation = \core_message\api::create_conversation(
4284 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4286 $user1->id,
4287 $user2->id
4290 $conversationid = $conversation->id;
4292 $this->assertNull(\core_message\api::remove_members_from_conversation([0], $conversationid));
4293 $this->assertEquals(2,
4294 \core_message\api::count_conversation_members($conversationid));
4298 * Test remove_members_from_conversation for multiple users.
4300 public function test_remove_members_for_multiple_users() {
4301 $user1 = self::getDataGenerator()->create_user();
4302 $user2 = self::getDataGenerator()->create_user();
4303 $user3 = self::getDataGenerator()->create_user();
4304 $user4 = self::getDataGenerator()->create_user();
4306 $conversation = \core_message\api::create_conversation(
4307 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4309 $user1->id,
4310 $user2->id
4313 $conversationid = $conversation->id;
4315 $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
4316 $this->assertNull(\core_message\api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
4317 $this->assertEquals(2,
4318 \core_message\api::count_conversation_members($conversationid));
4322 * Test remove_members_from_conversation for multiple non valid users.
4324 public function test_remove_members_for_multiple_no_valid_users() {
4325 $user1 = self::getDataGenerator()->create_user();
4326 $user2 = self::getDataGenerator()->create_user();
4327 $user3 = self::getDataGenerator()->create_user();
4328 $user4 = self::getDataGenerator()->create_user();
4330 $conversation = \core_message\api::create_conversation(
4331 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4333 $user1->id,
4334 $user2->id
4337 $conversationid = $conversation->id;
4339 $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
4340 $this->assertNull(
4341 \core_message\api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid)
4343 $this->assertEquals(1,
4344 \core_message\api::count_conversation_members($conversationid));
4348 * Test count_conversation_members for empty conversation.
4350 public function test_count_conversation_members_empty_conversation() {
4351 $user1 = self::getDataGenerator()->create_user();
4352 $user2 = self::getDataGenerator()->create_user();
4354 $conversation = \core_message\api::create_conversation(
4355 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4357 $user1->id,
4358 $user2->id
4361 $conversationid = $conversation->id;
4363 $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid));
4365 $this->assertEquals(0,
4366 \core_message\api::count_conversation_members($conversationid));
4370 * Test can create a contact request.
4372 public function test_can_create_contact_request() {
4373 global $CFG;
4375 $user1 = self::getDataGenerator()->create_user();
4376 $user2 = self::getDataGenerator()->create_user();
4378 // Disable messaging.
4379 $CFG->messaging = 0;
4380 $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
4382 // Re-enable messaging.
4383 $CFG->messaging = 1;
4385 // Allow users to message anyone site-wide.
4386 $CFG->messagingallusers = 1;
4387 $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
4389 // Disallow users from messaging anyone site-wide.
4390 $CFG->messagingallusers = 0;
4391 $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
4393 // Put the users in the same course so a contact request should be possible.
4394 $course = self::getDataGenerator()->create_course();
4395 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
4396 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
4397 $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
4401 * Test creating a contact request.
4403 public function test_create_contact_request() {
4404 global $DB;
4406 $user1 = self::getDataGenerator()->create_user();
4407 $user2 = self::getDataGenerator()->create_user();
4409 \core_message\api::create_contact_request($user1->id, $user2->id);
4411 $request = $DB->get_records('message_contact_requests');
4413 $this->assertCount(1, $request);
4415 $request = reset($request);
4417 $this->assertEquals($user1->id, $request->userid);
4418 $this->assertEquals($user2->id, $request->requesteduserid);
4422 * Test confirming a contact request.
4424 public function test_confirm_contact_request() {
4425 global $DB;
4427 $user1 = self::getDataGenerator()->create_user();
4428 $user2 = self::getDataGenerator()->create_user();
4430 \core_message\api::create_contact_request($user1->id, $user2->id);
4432 \core_message\api::confirm_contact_request($user1->id, $user2->id);
4434 $this->assertEquals(0, $DB->count_records('message_contact_requests'));
4436 $contact = $DB->get_records('message_contacts');
4438 $this->assertCount(1, $contact);
4440 $contact = reset($contact);
4442 $this->assertEquals($user1->id, $contact->userid);
4443 $this->assertEquals($user2->id, $contact->contactid);
4447 * Test declining a contact request.
4449 public function test_decline_contact_request() {
4450 global $DB;
4452 $user1 = self::getDataGenerator()->create_user();
4453 $user2 = self::getDataGenerator()->create_user();
4455 \core_message\api::create_contact_request($user1->id, $user2->id);
4457 \core_message\api::decline_contact_request($user1->id, $user2->id);
4459 $this->assertEquals(0, $DB->count_records('message_contact_requests'));
4460 $this->assertEquals(0, $DB->count_records('message_contacts'));
4464 * Test retrieving contact requests.
4466 public function test_get_contact_requests() {
4467 $user1 = self::getDataGenerator()->create_user();
4468 $user2 = self::getDataGenerator()->create_user();
4469 $user3 = self::getDataGenerator()->create_user();
4471 // Block one user, their request should not show up.
4472 \core_message\api::block_user($user1->id, $user3->id);
4474 \core_message\api::create_contact_request($user2->id, $user1->id);
4475 \core_message\api::create_contact_request($user3->id, $user1->id);
4477 $requests = \core_message\api::get_contact_requests($user1->id);
4479 $this->assertCount(1, $requests);
4481 $request = reset($requests);
4483 $this->assertEquals($user2->id, $request->id);
4484 $this->assertEquals(fullname($user2), $request->fullname);
4485 $this->assertObjectHasAttribute('profileimageurl', $request);
4486 $this->assertObjectHasAttribute('profileimageurlsmall', $request);
4487 $this->assertObjectHasAttribute('isonline', $request);
4488 $this->assertObjectHasAttribute('showonlinestatus', $request);
4489 $this->assertObjectHasAttribute('isblocked', $request);
4490 $this->assertObjectHasAttribute('iscontact', $request);
4494 * Test getting contact requests when there are none.
4496 public function test_get_contact_requests_no_requests() {
4497 $this->resetAfterTest();
4499 $user1 = self::getDataGenerator()->create_user();
4501 $requests = \core_message\api::get_contact_requests($user1->id);
4503 $this->assertEmpty($requests);
4507 * Test getting contact requests with limits.
4509 public function test_get_contact_requests_with_limits() {
4510 $this->resetAfterTest();
4512 $user1 = self::getDataGenerator()->create_user();
4513 $user2 = self::getDataGenerator()->create_user();
4514 $user3 = self::getDataGenerator()->create_user();
4516 \core_message\api::create_contact_request($user2->id, $user1->id);
4517 \core_message\api::create_contact_request($user3->id, $user1->id);
4519 $requests = \core_message\api::get_contact_requests($user1->id, 0, 1);
4521 $this->assertCount(1, $requests);
4525 * Test adding contacts.
4527 public function test_add_contact() {
4528 global $DB;
4530 $user1 = self::getDataGenerator()->create_user();
4531 $user2 = self::getDataGenerator()->create_user();
4533 \core_message\api::add_contact($user1->id, $user2->id);
4535 $contact = $DB->get_records('message_contacts');
4537 $this->assertCount(1, $contact);
4539 $contact = reset($contact);
4541 $this->assertEquals($user1->id, $contact->userid);
4542 $this->assertEquals($user2->id, $contact->contactid);
4546 * Test removing contacts.
4548 public function test_remove_contact() {
4549 global $DB;
4551 $user1 = self::getDataGenerator()->create_user();
4552 $user2 = self::getDataGenerator()->create_user();
4554 \core_message\api::add_contact($user1->id, $user2->id);
4555 \core_message\api::remove_contact($user1->id, $user2->id);
4557 $this->assertEquals(0, $DB->count_records('message_contacts'));
4561 * Test blocking users.
4563 public function test_block_user() {
4564 global $DB;
4566 $user1 = self::getDataGenerator()->create_user();
4567 $user2 = self::getDataGenerator()->create_user();
4569 \core_message\api::block_user($user1->id, $user2->id);
4571 $blockedusers = $DB->get_records('message_users_blocked');
4573 $this->assertCount(1, $blockedusers);
4575 $blockeduser = reset($blockedusers);
4577 $this->assertEquals($user1->id, $blockeduser->userid);
4578 $this->assertEquals($user2->id, $blockeduser->blockeduserid);
4582 * Test unblocking users.
4584 public function test_unblock_user() {
4585 global $DB;
4587 $user1 = self::getDataGenerator()->create_user();
4588 $user2 = self::getDataGenerator()->create_user();
4590 \core_message\api::block_user($user1->id, $user2->id);
4591 \core_message\api::unblock_user($user1->id, $user2->id);
4593 $this->assertEquals(0, $DB->count_records('message_users_blocked'));
4597 * Test is contact check.
4599 public function test_is_contact() {
4600 $user1 = self::getDataGenerator()->create_user();
4601 $user2 = self::getDataGenerator()->create_user();
4602 $user3 = self::getDataGenerator()->create_user();
4604 \core_message\api::add_contact($user1->id, $user2->id);
4606 $this->assertTrue(\core_message\api::is_contact($user1->id, $user2->id));
4607 $this->assertTrue(\core_message\api::is_contact($user2->id, $user1->id));
4608 $this->assertFalse(\core_message\api::is_contact($user2->id, $user3->id));
4612 * Test get contact.
4614 public function test_get_contact() {
4615 $user1 = self::getDataGenerator()->create_user();
4616 $user2 = self::getDataGenerator()->create_user();
4618 \core_message\api::add_contact($user1->id, $user2->id);
4620 $contact = \core_message\api::get_contact($user1->id, $user2->id);
4622 $this->assertEquals($user1->id, $contact->userid);
4623 $this->assertEquals($user2->id, $contact->contactid);
4627 * Test is blocked checked.
4629 public function test_is_blocked() {
4630 $user1 = self::getDataGenerator()->create_user();
4631 $user2 = self::getDataGenerator()->create_user();
4633 $this->assertFalse(\core_message\api::is_blocked($user1->id, $user2->id));
4634 $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
4636 \core_message\api::block_user($user1->id, $user2->id);
4638 $this->assertTrue(\core_message\api::is_blocked($user1->id, $user2->id));
4639 $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
4643 * Test the contact request exist check.
4645 public function test_does_contact_request_exist() {
4646 $user1 = self::getDataGenerator()->create_user();
4647 $user2 = self::getDataGenerator()->create_user();
4649 $this->assertFalse(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
4650 $this->assertFalse(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
4652 \core_message\api::create_contact_request($user1->id, $user2->id);
4654 $this->assertTrue(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
4655 $this->assertTrue(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
4659 * Test the user in conversation check.
4661 public function test_is_user_in_conversation() {
4662 $user1 = self::getDataGenerator()->create_user();
4663 $user2 = self::getDataGenerator()->create_user();
4665 $conversation = \core_message\api::create_conversation(
4666 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4668 $user1->id,
4669 $user2->id
4672 $conversationid = $conversation->id;
4674 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $conversationid));
4678 * Test the user in conversation check when they are not.
4680 public function test_is_user_in_conversation_when_not() {
4681 $user1 = self::getDataGenerator()->create_user();
4682 $user2 = self::getDataGenerator()->create_user();
4683 $user3 = self::getDataGenerator()->create_user();
4685 $conversation = \core_message\api::create_conversation(
4686 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4688 $user1->id,
4689 $user2->id
4692 $conversationid = $conversation->id;
4694 $this->assertFalse(\core_message\api::is_user_in_conversation($user3->id, $conversationid));
4698 * Test can create a group conversation.
4700 public function test_can_create_group_conversation() {
4701 global $CFG;
4703 $student = self::getDataGenerator()->create_user();
4704 $teacher = self::getDataGenerator()->create_user();
4705 $course = self::getDataGenerator()->create_course();
4707 $coursecontext = context_course::instance($course->id);
4709 $this->getDataGenerator()->enrol_user($student->id, $course->id);
4710 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
4712 // Disable messaging.
4713 $CFG->messaging = 0;
4714 $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
4716 // Re-enable messaging.
4717 $CFG->messaging = 1;
4719 // Student shouldn't be able to.
4720 $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
4722 // Teacher should.
4723 $this->assertTrue(\core_message\api::can_create_group_conversation($teacher->id, $coursecontext));
4727 * Test creating an individual conversation.
4729 public function test_create_conversation_individual() {
4730 $user1 = self::getDataGenerator()->create_user();
4731 $user2 = self::getDataGenerator()->create_user();
4733 $conversation = \core_message\api::create_conversation(
4734 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4736 $user1->id,
4737 $user2->id
4739 'A conversation name'
4742 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type);
4743 $this->assertEquals('A conversation name', $conversation->name);
4744 $this->assertEquals(\core_message\helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash);
4746 $this->assertCount(2, $conversation->members);
4748 $member1 = array_shift($conversation->members);
4749 $member2 = array_shift($conversation->members);
4751 $this->assertEquals($user1->id, $member1->userid);
4752 $this->assertEquals($conversation->id, $member1->conversationid);
4754 $this->assertEquals($user2->id, $member2->userid);
4755 $this->assertEquals($conversation->id, $member2->conversationid);
4759 * Test creating a group conversation.
4761 public function test_create_conversation_group() {
4762 $user1 = self::getDataGenerator()->create_user();
4763 $user2 = self::getDataGenerator()->create_user();
4764 $user3 = self::getDataGenerator()->create_user();
4766 $conversation = \core_message\api::create_conversation(
4767 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4769 $user1->id,
4770 $user2->id,
4771 $user3->id
4773 'A conversation name'
4776 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type);
4777 $this->assertEquals('A conversation name', $conversation->name);
4778 $this->assertNull($conversation->convhash);
4780 $this->assertCount(3, $conversation->members);
4782 $member1 = array_shift($conversation->members);
4783 $member2 = array_shift($conversation->members);
4784 $member3 = array_shift($conversation->members);
4786 $this->assertEquals($user1->id, $member1->userid);
4787 $this->assertEquals($conversation->id, $member1->conversationid);
4789 $this->assertEquals($user2->id, $member2->userid);
4790 $this->assertEquals($conversation->id, $member2->conversationid);
4792 $this->assertEquals($user3->id, $member3->userid);
4793 $this->assertEquals($conversation->id, $member3->conversationid);
4797 * Test creating an individual conversation with too many members.
4799 public function test_create_conversation_individual_too_many_members() {
4800 $this->expectException('moodle_exception');
4801 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]);
4805 * Test create message conversation with area.
4807 public function test_create_conversation_with_area() {
4808 $contextid = 111;
4809 $itemid = 222;
4810 $name = 'Name of conversation';
4811 $conversation = \core_message\api::create_conversation(
4812 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4814 $name,
4815 \core_message\api::MESSAGE_CONVERSATION_DISABLED,
4816 'core_group',
4817 'groups',
4818 $itemid,
4819 $contextid
4822 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
4823 $this->assertEquals('core_group', $conversation->component);
4824 $this->assertEquals('groups', $conversation->itemtype);
4825 $this->assertEquals($itemid, $conversation->itemid);
4826 $this->assertEquals($contextid, $conversation->contextid);
4830 * Test get_conversation_by_area.
4832 public function test_get_conversation_by_area() {
4833 $contextid = 111;
4834 $itemid = 222;
4835 $name = 'Name of conversation';
4836 $createconversation = \core_message\api::create_conversation(
4837 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4839 $name,
4840 \core_message\api::MESSAGE_CONVERSATION_DISABLED,
4841 'core_group',
4842 'groups',
4843 $itemid,
4844 $contextid
4846 $conversation = \core_message\api::get_conversation_by_area('core_group', 'groups', $itemid, $contextid);
4848 $this->assertEquals($createconversation->id, $conversation->id);
4849 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
4850 $this->assertEquals('core_group', $conversation->component);
4851 $this->assertEquals('groups', $conversation->itemtype);
4852 $this->assertEquals($itemid, $conversation->itemid);
4853 $this->assertEquals($contextid, $conversation->contextid);
4857 * Test enable_conversation.
4859 public function test_enable_conversation() {
4860 global $DB;
4862 $name = 'Name of conversation';
4864 $conversation = \core_message\api::create_conversation(
4865 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4867 $name,
4868 \core_message\api::MESSAGE_CONVERSATION_DISABLED
4871 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
4872 \core_message\api::enable_conversation($conversation->id);
4873 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]);
4874 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_ENABLED, $conversationenabled);
4878 * Test disable_conversation.
4880 public function test_disable_conversation() {
4881 global $DB;
4883 $name = 'Name of conversation';
4885 $conversation = \core_message\api::create_conversation(
4886 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4888 $name,
4889 \core_message\api::MESSAGE_CONVERSATION_ENABLED
4892 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_ENABLED, $conversation->enabled);
4893 \core_message\api::disable_conversation($conversation->id);
4894 $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]);
4895 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_DISABLED, $conversationenabled);
4899 * Test update_conversation_name.
4901 public function test_update_conversation_name() {
4902 global $DB;
4904 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, []);
4906 $newname = 'New name of conversation';
4907 \core_message\api::update_conversation_name($conversation->id, $newname);
4909 $this->assertEquals(
4910 $newname,
4911 $DB->get_field('message_conversations', 'name', ['id' => $conversation->id])
4916 * Test returning members in a conversation with no contact requests.
4918 public function test_get_conversation_members() {
4919 $lastaccess = new stdClass();
4920 $lastaccess->lastaccess = time();
4922 $user1 = self::getDataGenerator()->create_user($lastaccess);
4923 $user2 = self::getDataGenerator()->create_user();
4924 $user3 = self::getDataGenerator()->create_user();
4926 // This user will not be in the conversation, but a contact request will exist for them.
4927 $user4 = self::getDataGenerator()->create_user();
4929 // Add some contact requests.
4930 \core_message\api::create_contact_request($user1->id, $user3->id);
4931 \core_message\api::create_contact_request($user1->id, $user4->id);
4932 \core_message\api::create_contact_request($user2->id, $user3->id);
4934 // User 1 and 2 are already contacts.
4935 \core_message\api::add_contact($user1->id, $user2->id);
4937 // User 1 has blocked user 3.
4938 \core_message\api::block_user($user1->id, $user3->id);
4939 $conversation = \core_message\api::create_conversation(
4940 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
4942 $user1->id,
4943 $user2->id,
4944 $user3->id
4947 $conversationid = $conversation->id;
4948 $members = \core_message\api::get_conversation_members($user1->id, $conversationid, false);
4950 // Sort them by id.
4951 ksort($members);
4952 $this->assertCount(3, $members);
4953 $member1 = array_shift($members);
4954 $member2 = array_shift($members);
4955 $member3 = array_shift($members);
4957 // Confirm the standard fields are OK.
4958 $this->assertEquals($user1->id, $member1->id);
4959 $this->assertEquals(fullname($user1), $member1->fullname);
4960 $this->assertEquals(true, $member1->isonline);
4961 $this->assertEquals(true, $member1->showonlinestatus);
4962 $this->assertEquals(false, $member1->iscontact);
4963 $this->assertEquals(false, $member1->isblocked);
4964 $this->assertObjectHasAttribute('contactrequests', $member1);
4965 $this->assertEmpty($member1->contactrequests);
4967 $this->assertEquals($user2->id, $member2->id);
4968 $this->assertEquals(fullname($user2), $member2->fullname);
4969 $this->assertEquals(false, $member2->isonline);
4970 $this->assertEquals(true, $member2->showonlinestatus);
4971 $this->assertEquals(true, $member2->iscontact);
4972 $this->assertEquals(false, $member2->isblocked);
4973 $this->assertObjectHasAttribute('contactrequests', $member2);
4974 $this->assertEmpty($member2->contactrequests);
4976 $this->assertEquals($user3->id, $member3->id);
4977 $this->assertEquals(fullname($user3), $member3->fullname);
4978 $this->assertEquals(false, $member3->isonline);
4979 $this->assertEquals(true, $member3->showonlinestatus);
4980 $this->assertEquals(false, $member3->iscontact);
4981 $this->assertEquals(true, $member3->isblocked);
4982 $this->assertObjectHasAttribute('contactrequests', $member3);
4983 $this->assertEmpty($member3->contactrequests);
4987 * Test returning members in a conversation with contact requests.
4989 public function test_get_conversation_members_with_contact_requests() {
4990 $lastaccess = new stdClass();
4991 $lastaccess->lastaccess = time();
4993 $user1 = self::getDataGenerator()->create_user($lastaccess);
4994 $user2 = self::getDataGenerator()->create_user();
4995 $user3 = self::getDataGenerator()->create_user();
4997 // This user will not be in the conversation, but a contact request will exist for them.
4998 $user4 = self::getDataGenerator()->create_user();
4999 // Add some contact requests.
5000 \core_message\api::create_contact_request($user1->id, $user2->id);
5001 \core_message\api::create_contact_request($user1->id, $user3->id);
5002 \core_message\api::create_contact_request($user1->id, $user4->id);
5003 \core_message\api::create_contact_request($user2->id, $user3->id);
5005 // User 1 and 2 are already contacts.
5006 \core_message\api::add_contact($user1->id, $user2->id);
5007 // User 1 has blocked user 3.
5008 \core_message\api::block_user($user1->id, $user3->id);
5010 $conversation = \core_message\api::create_conversation(
5011 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
5013 $user1->id,
5014 $user2->id,
5015 $user3->id
5018 $conversationid = $conversation->id;
5020 $members = \core_message\api::get_conversation_members($user1->id, $conversationid, true);
5022 // Sort them by id.
5023 ksort($members);
5025 $this->assertCount(3, $members);
5027 $member1 = array_shift($members);
5028 $member2 = array_shift($members);
5029 $member3 = array_shift($members);
5031 // Confirm the standard fields are OK.
5032 $this->assertEquals($user1->id, $member1->id);
5033 $this->assertEquals(fullname($user1), $member1->fullname);
5034 $this->assertEquals(true, $member1->isonline);
5035 $this->assertEquals(true, $member1->showonlinestatus);
5036 $this->assertEquals(false, $member1->iscontact);
5037 $this->assertEquals(false, $member1->isblocked);
5038 $this->assertCount(2, $member1->contactrequests);
5040 $this->assertEquals($user2->id, $member2->id);
5041 $this->assertEquals(fullname($user2), $member2->fullname);
5042 $this->assertEquals(false, $member2->isonline);
5043 $this->assertEquals(true, $member2->showonlinestatus);
5044 $this->assertEquals(true, $member2->iscontact);
5045 $this->assertEquals(false, $member2->isblocked);
5046 $this->assertCount(1, $member2->contactrequests);
5048 $this->assertEquals($user3->id, $member3->id);
5049 $this->assertEquals(fullname($user3), $member3->fullname);
5050 $this->assertEquals(false, $member3->isonline);
5051 $this->assertEquals(true, $member3->showonlinestatus);
5052 $this->assertEquals(false, $member3->iscontact);
5053 $this->assertEquals(true, $member3->isblocked);
5054 $this->assertCount(1, $member3->contactrequests);
5056 // Confirm the contact requests are OK.
5057 $request1 = array_shift($member1->contactrequests);
5058 $request2 = array_shift($member1->contactrequests);
5060 $this->assertEquals($user1->id, $request1->userid);
5061 $this->assertEquals($user2->id, $request1->requesteduserid);
5063 $this->assertEquals($user1->id, $request2->userid);
5064 $this->assertEquals($user3->id, $request2->requesteduserid);
5066 $request1 = array_shift($member2->contactrequests);
5068 $this->assertEquals($user1->id, $request1->userid);
5069 $this->assertEquals($user2->id, $request1->requesteduserid);
5071 $request1 = array_shift($member3->contactrequests);
5073 $this->assertEquals($user1->id, $request1->userid);
5074 $this->assertEquals($user3->id, $request1->requesteduserid);
5078 * Test verifying that messages can be sent to existing individual conversations.
5080 public function test_send_message_to_conversation_individual_conversation() {
5081 // Get a bunch of conversations, some group, some individual and in different states.
5082 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5083 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5085 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5086 $course = $this->getDataGenerator()->create_course();
5087 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5088 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5089 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5090 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5092 // Redirect messages.
5093 // This marks messages as read, but we can still observe and verify the number of conversation recipients,
5094 // based on the message_viewed events generated as part of marking the message as read for each user.
5095 $this->preventResetByRollback();
5096 $sink = $this->redirectMessages();
5098 // Send a message to an individual conversation.
5099 $sink = $this->redirectEvents();
5100 $message1 = \core_message\api::send_message_to_conversation($user1->id, $ic1->id, 'this is a message', FORMAT_MOODLE);
5101 $events = $sink->get_events();
5103 // Verify the message returned.
5104 $this->assertInstanceOf(\stdClass::class, $message1);
5105 $this->assertObjectHasAttribute('id', $message1);
5106 $this->assertAttributeEquals($user1->id, 'useridfrom', $message1);
5107 $this->assertAttributeEquals('this is a message', 'text', $message1);
5108 $this->assertObjectHasAttribute('timecreated', $message1);
5110 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(),
5111 // however, we can still determine the number and ids of any recipients this way.
5112 $this->assertCount(1, $events);
5113 $userids = array_column($events, 'userid');
5114 $this->assertNotContains($user1->id, $userids);
5115 $this->assertContains($user2->id, $userids);
5119 * Test verifying that messages can be sent to existing group conversations.
5121 public function test_send_message_to_conversation_group_conversation() {
5122 // Get a bunch of conversations, some group, some individual and in different states.
5123 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5124 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5126 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5127 $course = $this->getDataGenerator()->create_course();
5128 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5129 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5130 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5131 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5133 // Redirect messages.
5134 // This marks messages as read, but we can still observe and verify the number of conversation recipients,
5135 // based on the message_viewed events generated as part of marking the message as read for each user.
5136 $this->preventResetByRollback();
5137 $sink = $this->redirectMessages();
5139 // Send a message to a group conversation.
5140 $sink = $this->redirectEvents();
5141 $message1 = \core_message\api::send_message_to_conversation($user1->id, $gc2->id, 'message to the group', FORMAT_MOODLE);
5142 $events = $sink->get_events();
5144 // Verify the message returned.
5145 $this->assertInstanceOf(\stdClass::class, $message1);
5146 $this->assertObjectHasAttribute('id', $message1);
5147 $this->assertAttributeEquals($user1->id, 'useridfrom', $message1);
5148 $this->assertAttributeEquals('message to the group', 'text', $message1);
5149 $this->assertObjectHasAttribute('timecreated', $message1);
5151 // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(),
5152 // however, we can still determine the number and ids of any recipients this way.
5153 $this->assertCount(2, $events);
5154 $userids = array_column($events, 'userid');
5155 $this->assertNotContains($user1->id, $userids);
5156 $this->assertContains($user3->id, $userids);
5157 $this->assertContains($user4->id, $userids);
5161 * Test verifying that messages cannot be sent to conversations that don't exist.
5163 public function test_send_message_to_conversation_non_existent_conversation() {
5164 // Get a bunch of conversations, some group, some individual and in different states.
5165 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5166 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5168 $this->expectException(\moodle_exception::class);
5169 \core_message\api::send_message_to_conversation($user1->id, 0, 'test', FORMAT_MOODLE);
5173 * Test verifying that messages cannot be sent to conversations by users who are not members.
5175 public function test_send_message_to_conversation_non_member() {
5176 // Get a bunch of conversations, some group, some individual and in different states.
5177 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5178 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5180 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5181 $course = $this->getDataGenerator()->create_course();
5182 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5183 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5184 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5185 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5187 $this->expectException(\moodle_exception::class);
5188 \core_message\api::send_message_to_conversation($user3->id, $ic1->id, 'test', FORMAT_MOODLE);
5192 * Test verifying that messages cannot be sent to conversations by users who are not members.
5194 public function test_send_message_to_conversation_blocked_user() {
5195 // Get a bunch of conversations, some group, some individual and in different states.
5196 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5197 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5199 // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5200 $course = $this->getDataGenerator()->create_course();
5201 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5202 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5203 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5204 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5206 // User 1 blocks user 2.
5207 \core_message\api::block_user($user1->id, $user2->id);
5209 // Verify that a message can be sent to any group conversation in which user1 and user2 are members.
5210 $this->assertNotEmpty(\core_message\api::send_message_to_conversation($user1->id, $gc2->id, 'Hey guys', FORMAT_PLAIN));
5212 // User 2 cannot send a message to the conversation with user 1.
5213 $this->expectException(\moodle_exception::class);
5214 \core_message\api::send_message_to_conversation($user2->id, $ic1->id, 'test', FORMAT_MOODLE);
5218 * Comparison function for sorting contacts.
5220 * @param stdClass $a
5221 * @param stdClass $b
5222 * @return bool
5224 protected static function sort_contacts($a, $b) {
5225 return $a->userid > $b->userid;