MDL-63466 core_message: deprecated methods and services
[moodle.git] / message / tests / api_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Test message API.
19  *
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
24  */
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.
36  *
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
41  */
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);
58     }
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);
81     }
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);
101     }
103     /**
104      * Test count_blocked_users.
105      */
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());
123     }
125     /**
126      * Tests searching users in a course.
127      */
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);
178     }
180     /**
181      * Tests searching users.
182      */
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.
262         list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
264         // Check that we retrieved the correct contacts.
265         $this->assertEquals(2, count($contacts));
266         $this->assertEquals($user3->id, $contacts[0]->userid);
267         $this->assertEquals($user2->id, $contacts[1]->userid);
269         // Check that we retrieved the correct courses.
270         $this->assertEquals(2, count($courses));
271         $this->assertEquals($course3->id, $courses[0]->id);
272         $this->assertEquals($course1->id, $courses[1]->id);
274         // Check that we retrieved the correct non-contacts.
275         $this->assertEquals(1, count($noncontacts));
276         $this->assertEquals($user5->id, $noncontacts[0]->userid);
277     }
279     /**
280      * Tests searching messages.
281      */
282     public function test_search_messages() {
283         // Create some users.
284         $user1 = self::getDataGenerator()->create_user();
285         $user2 = self::getDataGenerator()->create_user();
286         $user3 = self::getDataGenerator()->create_user();
288         // The person doing the search.
289         $this->setUser($user1);
291         // Send some messages back and forth.
292         $time = 1;
293         $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
294         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
295         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
296         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
297         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
299         // Block user 3.
300         \core_message\api::block_user($user1->id, $user3->id);
302         // Perform a search.
303         $messages = \core_message\api::search_messages($user1->id, 'o');
305         // Confirm the data is correct.
306         $this->assertEquals(3, count($messages));
308         $message1 = $messages[0];
309         $message2 = $messages[1];
310         $message3 = $messages[2];
312         $this->assertEquals($user2->id, $message1->userid);
313         $this->assertEquals($user2->id, $message1->useridfrom);
314         $this->assertEquals(fullname($user2), $message1->fullname);
315         $this->assertTrue($message1->ismessaging);
316         $this->assertEquals('Word.', $message1->lastmessage);
317         $this->assertNotEmpty($message1->messageid);
318         $this->assertNull($message1->isonline);
319         $this->assertFalse($message1->isread);
320         $this->assertFalse($message1->isblocked);
321         $this->assertNull($message1->unreadcount);
323         $this->assertEquals($user2->id, $message2->userid);
324         $this->assertEquals($user1->id, $message2->useridfrom);
325         $this->assertEquals(fullname($user2), $message2->fullname);
326         $this->assertTrue($message2->ismessaging);
327         $this->assertEquals('Yo!', $message2->lastmessage);
328         $this->assertNotEmpty($message2->messageid);
329         $this->assertNull($message2->isonline);
330         $this->assertTrue($message2->isread);
331         $this->assertFalse($message2->isblocked);
332         $this->assertNull($message2->unreadcount);
334         $this->assertEquals($user3->id, $message3->userid);
335         $this->assertEquals($user3->id, $message3->useridfrom);
336         $this->assertEquals(fullname($user3), $message3->fullname);
337         $this->assertTrue($message3->ismessaging);
338         $this->assertEquals('Don\'t block me.', $message3->lastmessage);
339         $this->assertNotEmpty($message3->messageid);
340         $this->assertNull($message3->isonline);
341         $this->assertFalse($message3->isread);
342         $this->assertTrue($message3->isblocked);
343         $this->assertNull($message3->unreadcount);
344     }
346     /**
347      * Test verifying that favourited conversations can be retrieved.
348      */
349     public function test_get_favourite_conversations() {
350         // Create some users.
351         $user1 = self::getDataGenerator()->create_user();
352         $user2 = self::getDataGenerator()->create_user();
353         $user3 = self::getDataGenerator()->create_user();
354         $user4 = self::getDataGenerator()->create_user();
356         // The person doing the search.
357         $this->setUser($user1);
359         // No conversations yet.
360         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
362         // Create some conversations for user1.
363         $time = 1;
364         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
365         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
366         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
367         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
369         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
370         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
371         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
372         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
374         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
375         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
376         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
378         // Favourite the first 2 conversations for user1.
379         $convoids = [];
380         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
381         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
382         $user1context = context_user::instance($user1->id);
383         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
384         foreach ($convoids as $convoid) {
385             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
386         }
388         // We should have 3 conversations.
389         $this->assertCount(3, \core_message\api::get_conversations($user1->id));
391         // And 2 favourited conversations.
392         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
393         $this->assertCount(2, $conversations);
394     }
396     /**
397      * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
398      */
399     public function test_get_favourite_conversations_limit_offset() {
400         // Create some users.
401         $user1 = self::getDataGenerator()->create_user();
402         $user2 = self::getDataGenerator()->create_user();
403         $user3 = self::getDataGenerator()->create_user();
404         $user4 = self::getDataGenerator()->create_user();
406         // The person doing the search.
407         $this->setUser($user1);
409         // No conversations yet.
410         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
412         // Create some conversations for user1.
413         $time = 1;
414         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
415         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
416         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
417         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
419         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
420         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
421         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
422         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
424         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
425         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
426         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
428         // Favourite the all conversations for user1.
429         $convoids = [];
430         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
431         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
432         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
433         $user1context = context_user::instance($user1->id);
434         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
435         foreach ($convoids as $convoid) {
436             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
437         }
439         // Get all records, using offset 0 and large limit.
440         $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
442         // Now, get 10 conversations starting at the second record. We should see 2 conversations.
443         $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
445         // Now, try to get favourited conversations using an invalid offset.
446         $this->assertCount(0, \core_message\api::get_conversations($user1->id, 4, 10, null, true));
447     }
449     /**
450      * Tests retrieving favourite conversations when a conversation contains a deleted user.
451      */
452     public function test_get_favourite_conversations_with_deleted_user() {
453         // Create some users.
454         $user1 = self::getDataGenerator()->create_user();
455         $user2 = self::getDataGenerator()->create_user();
456         $user3 = self::getDataGenerator()->create_user();
458         // Send some messages back and forth, have some different conversations with different users.
459         $time = 1;
460         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
461         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
462         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
463         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
465         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
466         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
467         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
468         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
470         // Favourite the all conversations for user1.
471         $convoids = [];
472         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
473         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
474         $user1context = context_user::instance($user1->id);
475         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
476         foreach ($convoids as $convoid) {
477             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
478         }
480         // Delete the second user.
481         delete_user($user2);
483         // Retrieve the conversations.
484         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
486         // We should only have one conversation because the other user was deleted.
487         $this->assertCount(1, $conversations);
489         // Confirm the conversation is from the non-deleted user.
490         $conversation = reset($conversations);
491         $this->assertEquals($user3->id, $conversation->userid);
492     }
494     /**
495      * Test confirming that conversations can be marked as favourites.
496      */
497     public function test_set_favourite_conversation() {
498         // Create some users.
499         $user1 = self::getDataGenerator()->create_user();
500         $user2 = self::getDataGenerator()->create_user();
501         $user3 = self::getDataGenerator()->create_user();
503         // Send some messages back and forth, have some different conversations with different users.
504         $time = 1;
505         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
506         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
507         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
508         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
510         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
511         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
512         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
513         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
515         // Favourite the first conversation as user 1.
516         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
517         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
519         // Verify we have a single favourite conversation a user 1.
520         $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
522         // Verify we have no favourites as user2, despite being a member in that conversation.
523         $this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
525         // Try to favourite the same conversation again.
526         $this->expectException(\moodle_exception::class);
527         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
528     }
530     /**
531      * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
532      */
533     public function test_set_favourite_conversation_nonexistent_conversation() {
534         // Create some users.
535         $user1 = self::getDataGenerator()->create_user();
536         // Try to favourite a non-existent conversation.
537         $this->expectException(\moodle_exception::class);
538         \core_message\api::set_favourite_conversation(0, $user1->id);
539     }
541     /**
542      * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
543      */
544     public function test_set_favourite_conversation_non_member() {
545         // Create some users.
546         $user1 = self::getDataGenerator()->create_user();
547         $user2 = self::getDataGenerator()->create_user();
548         $user3 = self::getDataGenerator()->create_user();
550         // Send some messages back and forth, have some different conversations with different users.
551         $time = 1;
552         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
553         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
554         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
555         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
557         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
558         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
559         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
560         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
562         // Try to favourite the first conversation as user 3, who is not a member.
563         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
564         $this->expectException(\moodle_exception::class);
565         \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
566     }
568     /**
569      * Test confirming that those conversations marked as favourites can be unfavourited.
570      */
571     public function test_unset_favourite_conversation() {
572         // Create some users.
573         $user1 = self::getDataGenerator()->create_user();
574         $user2 = self::getDataGenerator()->create_user();
575         $user3 = self::getDataGenerator()->create_user();
577         // Send some messages back and forth, have some different conversations with different users.
578         $time = 1;
579         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
580         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
581         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
582         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
584         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
585         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
586         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
587         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
589         // Favourite the first conversation as user 1 and the second as user 3.
590         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
591         $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
592         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
593         \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
595         // Verify we have a single favourite conversation for both user 1 and user 3.
596         $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
597         $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
599         // Now unfavourite the conversation as user 1.
600         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
602         // Verify we have a single favourite conversation user 3 only, and none for user1.
603         $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
604         $this->assertCount(0, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
606         // Try to favourite the same conversation again as user 1.
607         $this->expectException(\moodle_exception::class);
608         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
609     }
611     /**
612      * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
613      */
614     public function test_unset_favourite_conversation_not_favourite() {
615         // Create some users.
616         $user1 = self::getDataGenerator()->create_user();
617         $user2 = self::getDataGenerator()->create_user();
619         // Send some messages back and forth, have some different conversations with different users.
620         $time = 1;
621         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
622         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
623         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
624         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
626         // Now try to unfavourite the conversation as user 1.
627         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
628         $this->expectException(\moodle_exception::class);
629         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
630     }
632     /**
633      * Test verifying that a non-existent conversation cannot be unset as a favourite.
634      */
635     public function test_unset_favourite_conversation_non_existent_conversation() {
636         // Create some users.
637         $user1 = self::getDataGenerator()->create_user();
639         // Now try to unfavourite the conversation as user 1.
640         $this->expectException(\moodle_exception::class);
641         \core_message\api::unset_favourite_conversation(0, $user1->id);
642     }
644     /**
645      * Tests retrieving conversations.
646      */
647     public function test_get_conversations() {
648         // Create some users.
649         $user1 = self::getDataGenerator()->create_user();
650         $user2 = self::getDataGenerator()->create_user();
651         $user3 = self::getDataGenerator()->create_user();
652         $user4 = self::getDataGenerator()->create_user();
654         // The person doing the search.
655         $this->setUser($user1);
657         // No conversations yet.
658         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
660         // Send some messages back and forth, have some different conversations with different users.
661         $time = 1;
662         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
663         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
664         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
665         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
667         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
668         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
669         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
670         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
672         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
673         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
674         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
676         // Retrieve the conversations.
677         $conversations = \core_message\api::get_conversations($user1->id);
679         // Confirm the data is correct.
680         $this->assertEquals(3, count($conversations));
682         $message1 = array_shift($conversations);
683         $message2 = array_shift($conversations);
684         $message3 = array_shift($conversations);
686         $this->assertEquals($user4->id, $message1->userid);
687         $this->assertEquals($user1->id, $message1->useridfrom);
688         $this->assertTrue($message1->ismessaging);
689         $this->assertEquals('Dope.', $message1->lastmessage);
690         $this->assertEquals($messageid3, $message1->messageid);
691         $this->assertNull($message1->isonline);
692         $this->assertFalse($message1->isread);
693         $this->assertFalse($message1->isblocked);
694         $this->assertEquals(1, $message1->unreadcount);
696         $this->assertEquals($user3->id, $message2->userid);
697         $this->assertEquals($user3->id, $message2->useridfrom);
698         $this->assertTrue($message2->ismessaging);
699         $this->assertEquals('Cool.', $message2->lastmessage);
700         $this->assertEquals($messageid2, $message2->messageid);
701         $this->assertNull($message2->isonline);
702         $this->assertFalse($message2->isread);
703         $this->assertFalse($message2->isblocked);
704         $this->assertEquals(2, $message2->unreadcount);
706         $this->assertEquals($user2->id, $message3->userid);
707         $this->assertEquals($user2->id, $message3->useridfrom);
708         $this->assertTrue($message3->ismessaging);
709         $this->assertEquals('Word.', $message3->lastmessage);
710         $this->assertEquals($messageid1, $message3->messageid);
711         $this->assertNull($message3->isonline);
712         $this->assertFalse($message3->isread);
713         $this->assertFalse($message3->isblocked);
714         $this->assertEquals(2, $message3->unreadcount);
715     }
717     /**
718      * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
719      */
720     public function test_get_conversations_limit_offset() {
721         // Create some users.
722         $user1 = self::getDataGenerator()->create_user();
723         $user2 = self::getDataGenerator()->create_user();
724         $user3 = self::getDataGenerator()->create_user();
725         $user4 = self::getDataGenerator()->create_user();
727         // The person doing the search.
728         $this->setUser($user1);
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         $messageid1 = $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         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
742         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
743         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
744         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
746         // Retrieve the conversations.
747         $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
749         // We should only have one conversation because of the limit.
750         $this->assertCount(1, $conversations);
752         $conversation = array_shift($conversations);
754         $this->assertEquals($user3->id, $conversation->userid);
755         $this->assertEquals($user3->id, $conversation->useridfrom);
756         $this->assertTrue($conversation->ismessaging);
757         $this->assertEquals('Cool.', $conversation->lastmessage);
758         $this->assertEquals($messageid2, $conversation->messageid);
759         $this->assertNull($conversation->isonline);
760         $this->assertFalse($conversation->isread);
761         $this->assertFalse($conversation->isblocked);
762         $this->assertEquals(2, $conversation->unreadcount);
764         // Retrieve the next conversation.
765         $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
767         // We should only have one conversation because of the limit.
768         $this->assertCount(1, $conversations);
770         $conversation = array_shift($conversations);
772         $this->assertEquals($user2->id, $conversation->userid);
773         $this->assertEquals($user2->id, $conversation->useridfrom);
774         $this->assertTrue($conversation->ismessaging);
775         $this->assertEquals('Word.', $conversation->lastmessage);
776         $this->assertEquals($messageid1, $conversation->messageid);
777         $this->assertNull($conversation->isonline);
778         $this->assertFalse($conversation->isread);
779         $this->assertFalse($conversation->isblocked);
780         $this->assertEquals(2, $conversation->unreadcount);
782         // Ask for an offset that doesn't exist.
783         $conversations = \core_message\api::get_conversations($user1->id, 4, 1);
785         // We should not get any conversations back.
786         $this->assertCount(0, $conversations);
787     }
789     /**
790      * Tests retrieving conversations when a conversation contains a deleted user.
791      */
792     public function test_get_conversations_with_deleted_user() {
793         // Create some users.
794         $user1 = self::getDataGenerator()->create_user();
795         $user2 = self::getDataGenerator()->create_user();
796         $user3 = self::getDataGenerator()->create_user();
798         // Send some messages back and forth, have some different conversations with different users.
799         $time = 1;
800         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
801         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
802         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
803         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
805         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
806         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
807         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
808         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
810         // Delete the second user.
811         delete_user($user2);
813         // Retrieve the conversations.
814         $conversations = \core_message\api::get_conversations($user1->id);
816         // We should only have one conversation because the other user was deleted.
817         $this->assertCount(1, $conversations);
819         // Confirm the conversation is from the non-deleted user.
820         $conversation = reset($conversations);
821         $this->assertEquals($user3->id, $conversation->userid);
822     }
824    /**
825     * The data provider for get_conversations_mixed.
826     *
827     * This provides sets of data to for testing.
828     * @return array
829     */
830    public function get_conversations_mixed_provider() {
831        return array(
832             'Test that conversations with messages contacts is correctly ordered.' => array(
833                 'users' => array(
834                     'user1',
835                     'user2',
836                     'user3',
837                 ),
838                 'contacts' => array(
839                 ),
840                 'messages' => array(
841                     array(
842                         'from'          => 'user1',
843                         'to'            => 'user2',
844                         'state'         => 'unread',
845                         'subject'       => 'S1',
846                     ),
847                     array(
848                         'from'          => 'user2',
849                         'to'            => 'user1',
850                         'state'         => 'unread',
851                         'subject'       => 'S2',
852                     ),
853                     array(
854                         'from'          => 'user1',
855                         'to'            => 'user2',
856                         'state'         => 'unread',
857                         'timecreated'   => 0,
858                         'subject'       => 'S3',
859                     ),
860                     array(
861                         'from'          => 'user1',
862                         'to'            => 'user3',
863                         'state'         => 'read',
864                         'timemodifier'  => 1,
865                         'subject'       => 'S4',
866                     ),
867                     array(
868                         'from'          => 'user3',
869                         'to'            => 'user1',
870                         'state'         => 'read',
871                         'timemodifier'  => 1,
872                         'subject'       => 'S5',
873                     ),
874                     array(
875                         'from'          => 'user1',
876                         'to'            => 'user3',
877                         'state'         => 'read',
878                         'timecreated'   => 0,
879                         'subject'       => 'S6',
880                     ),
881                 ),
882                 'expectations' => array(
883                     'user1' => array(
884                         // User1 has conversed most recently with user3. The most recent message is M5.
885                         array(
886                             'messageposition'   => 0,
887                             'with'              => 'user3',
888                             'subject'           => 'S5',
889                             'unreadcount'       => 0,
890                         ),
891                         // User1 has also conversed with user2. The most recent message is S2.
892                         array(
893                             'messageposition'   => 1,
894                             'with'              => 'user2',
895                             'subject'           => 'S2',
896                             'unreadcount'       => 1,
897                         ),
898                     ),
899                     'user2' => array(
900                         // User2 has only conversed with user1. Their most recent shared message was S2.
901                         array(
902                             'messageposition'   => 0,
903                             'with'              => 'user1',
904                             'subject'           => 'S2',
905                             'unreadcount'       => 2,
906                         ),
907                     ),
908                     'user3' => array(
909                         // User3 has only conversed with user1. Their most recent shared message was S5.
910                         array(
911                             'messageposition'   => 0,
912                             'with'              => 'user1',
913                             'subject'           => 'S5',
914                             'unreadcount'       => 0,
915                         ),
916                     ),
917                 ),
918             ),
919             'Test that users with contacts and messages to self work as expected' => array(
920                 'users' => array(
921                     'user1',
922                     'user2',
923                     'user3',
924                 ),
925                 'contacts' => array(
926                     'user1' => array(
927                         'user2' => 0,
928                         'user3' => 0,
929                     ),
930                     'user2' => array(
931                         'user3' => 0,
932                     ),
933                 ),
934                 'messages' => array(
935                     array(
936                         'from'          => 'user1',
937                         'to'            => 'user1',
938                         'state'         => 'unread',
939                         'subject'       => 'S1',
940                     ),
941                     array(
942                         'from'          => 'user1',
943                         'to'            => 'user1',
944                         'state'         => 'unread',
945                         'subject'       => 'S2',
946                     ),
947                 ),
948                 'expectations' => array(
949                     'user1' => array(
950                         // User1 has conversed most recently with user1. The most recent message is S2.
951                         array(
952                             'messageposition'   => 0,
953                             'with'              => 'user1',
954                             'subject'           => 'S2',
955                             'unreadcount'       => 0, // Messages sent to and from the same user are counted as read.
956                         ),
957                     ),
958                 ),
959             ),
960             'Test conversations with a single user, where some messages are read and some are not.' => array(
961                 'users' => array(
962                     'user1',
963                     'user2',
964                 ),
965                 'contacts' => array(
966                 ),
967                 'messages' => array(
968                     array(
969                         'from'          => 'user1',
970                         'to'            => 'user2',
971                         'state'         => 'read',
972                         'subject'       => 'S1',
973                     ),
974                     array(
975                         'from'          => 'user2',
976                         'to'            => 'user1',
977                         'state'         => 'read',
978                         'subject'       => 'S2',
979                     ),
980                     array(
981                         'from'          => 'user1',
982                         'to'            => 'user2',
983                         'state'         => 'unread',
984                         'timemodifier'  => 1,
985                         'subject'       => 'S3',
986                     ),
987                     array(
988                         'from'          => 'user1',
989                         'to'            => 'user2',
990                         'state'         => 'unread',
991                         'timemodifier'  => 1,
992                         'subject'       => 'S4',
993                     ),
994                 ),
995                 'expectations' => array(
996                     // The most recent message between user1 and user2 was S4.
997                     'user1' => array(
998                         array(
999                             'messageposition'   => 0,
1000                             'with'              => 'user2',
1001                             'subject'           => 'S4',
1002                             'unreadcount'       => 0,
1003                         ),
1004                     ),
1005                     'user2' => array(
1006                         // The most recent message between user1 and user2 was S4.
1007                         array(
1008                             'messageposition'   => 0,
1009                             'with'              => 'user1',
1010                             'subject'           => 'S4',
1011                             'unreadcount'       => 2,
1012                         ),
1013                     ),
1014                 ),
1015             ),
1016             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1017             'are out of order' => array(
1018             // This can happen through a combination of factors including multi-master DB replication with messages
1019             // read somehow (e.g. API).
1020                 'users' => array(
1021                     'user1',
1022                     'user2',
1023                 ),
1024                 'contacts' => array(
1025                 ),
1026                 'messages' => array(
1027                     array(
1028                         'from'          => 'user1',
1029                         'to'            => 'user2',
1030                         'state'         => 'read',
1031                         'subject'       => 'S1',
1032                         'timemodifier'  => 1,
1033                     ),
1034                     array(
1035                         'from'          => 'user2',
1036                         'to'            => 'user1',
1037                         'state'         => 'read',
1038                         'subject'       => 'S2',
1039                         'timemodifier'  => 2,
1040                     ),
1041                     array(
1042                         'from'          => 'user1',
1043                         'to'            => 'user2',
1044                         'state'         => 'unread',
1045                         'subject'       => 'S3',
1046                     ),
1047                     array(
1048                         'from'          => 'user1',
1049                         'to'            => 'user2',
1050                         'state'         => 'unread',
1051                         'subject'       => 'S4',
1052                     ),
1053                 ),
1054                 'expectations' => array(
1055                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1056                     'user1' => array(
1057                         array(
1058                             'messageposition'   => 0,
1059                             'with'              => 'user2',
1060                             'subject'           => 'S2',
1061                             'unreadcount'       => 0,
1062                         ),
1063                     ),
1064                     'user2' => array(
1065                         array(
1066                             'messageposition'   => 0,
1067                             'with'              => 'user1',
1068                             'subject'           => 'S2',
1069                             'unreadcount'       => 2
1070                         ),
1071                     ),
1072                 ),
1073             ),
1074             'Test unread message count is correct for both users' => array(
1075                 'users' => array(
1076                     'user1',
1077                     'user2',
1078                 ),
1079                 'contacts' => array(
1080                 ),
1081                 'messages' => array(
1082                     array(
1083                         'from'          => 'user1',
1084                         'to'            => 'user2',
1085                         'state'         => 'read',
1086                         'subject'       => 'S1',
1087                         'timemodifier'  => 1,
1088                     ),
1089                     array(
1090                         'from'          => 'user2',
1091                         'to'            => 'user1',
1092                         'state'         => 'read',
1093                         'subject'       => 'S2',
1094                         'timemodifier'  => 2,
1095                     ),
1096                     array(
1097                         'from'          => 'user1',
1098                         'to'            => 'user2',
1099                         'state'         => 'read',
1100                         'subject'       => 'S3',
1101                         'timemodifier'  => 3,
1102                     ),
1103                     array(
1104                         'from'          => 'user1',
1105                         'to'            => 'user2',
1106                         'state'         => 'read',
1107                         'subject'       => 'S4',
1108                         'timemodifier'  => 4,
1109                     ),
1110                     array(
1111                         'from'          => 'user1',
1112                         'to'            => 'user2',
1113                         'state'         => 'unread',
1114                         'subject'       => 'S5',
1115                         'timemodifier'  => 5,
1116                     ),
1117                     array(
1118                         'from'          => 'user2',
1119                         'to'            => 'user1',
1120                         'state'         => 'unread',
1121                         'subject'       => 'S6',
1122                         'timemodifier'  => 6,
1123                     ),
1124                     array(
1125                         'from'          => 'user1',
1126                         'to'            => 'user2',
1127                         'state'         => 'unread',
1128                         'subject'       => 'S7',
1129                         'timemodifier'  => 7,
1130                     ),
1131                     array(
1132                         'from'          => 'user1',
1133                         'to'            => 'user2',
1134                         'state'         => 'unread',
1135                         'subject'       => 'S8',
1136                         'timemodifier'  => 8,
1137                     ),
1138                 ),
1139                 'expectations' => array(
1140                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1141                     'user1' => array(
1142                         array(
1143                             'messageposition'   => 0,
1144                             'with'              => 'user2',
1145                             'subject'           => 'S8',
1146                             'unreadcount'       => 1,
1147                         ),
1148                     ),
1149                     'user2' => array(
1150                         array(
1151                             'messageposition'   => 0,
1152                             'with'              => 'user1',
1153                             'subject'           => 'S8',
1154                             'unreadcount'       => 3,
1155                         ),
1156                     ),
1157                 ),
1158             ),
1159         );
1160     }
1162     /**
1163      * Test get_conversations with a mixture of messages.
1164      *
1165      * @dataProvider get_conversations_mixed_provider
1166      * @param array $usersdata The list of users to create for this test.
1167      * @param array $messagesdata The list of messages to create.
1168      * @param array $expectations The list of expected outcomes.
1169      */
1170     public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1171         global $DB;
1173         // Create all of the users.
1174         $users = array();
1175         foreach ($usersdata as $username) {
1176             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1177         }
1179         foreach ($contacts as $username => $contact) {
1180             foreach ($contact as $contactname => $blocked) {
1181                 $record = new stdClass();
1182                 $record->userid     = $users[$username]->id;
1183                 $record->contactid  = $users[$contactname]->id;
1184                 $record->blocked    = $blocked;
1185                 $record->id = $DB->insert_record('message_contacts', $record);
1186             }
1187         }
1189         $defaulttimecreated = time();
1190         foreach ($messagesdata as $messagedata) {
1191             $from       = $users[$messagedata['from']];
1192             $to         = $users[$messagedata['to']];
1193             $subject    = $messagedata['subject'];
1195             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
1196                 $messageid = $this->send_fake_message($from, $to, $subject);
1197             } else {
1198                 // If there is no state, or the state is not 'unread', assume the message is read.
1199                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
1200             }
1202             $updatemessage = new stdClass();
1203             $updatemessage->id = $messageid;
1204             if (isset($messagedata['timecreated'])) {
1205                 $updatemessage->timecreated = $messagedata['timecreated'];
1206             } else if (isset($messagedata['timemodifier'])) {
1207                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
1208             } else {
1209                 $updatemessage->timecreated = $defaulttimecreated;
1210             }
1212             $DB->update_record('messages', $updatemessage);
1213         }
1215         foreach ($expectations as $username => $data) {
1216             // Get the recent conversations for the specified user.
1217             $user = $users[$username];
1218             $conversations = array_values(\core_message\api::get_conversations($user->id));
1219             foreach ($data as $expectation) {
1220                 $otheruser = $users[$expectation['with']];
1221                 $conversation = $conversations[$expectation['messageposition']];
1222                 $this->assertEquals($otheruser->id, $conversation->userid);
1223                 $this->assertEquals($expectation['subject'], $conversation->lastmessage);
1224                 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
1225             }
1226         }
1227     }
1229     /**
1230      * Tests retrieving contacts.
1231      */
1232     public function test_get_contacts() {
1233         // Create some users.
1234         $user1 = self::getDataGenerator()->create_user();
1236         // Set as the user.
1237         $this->setUser($user1);
1239         $user2 = new stdClass();
1240         $user2->firstname = 'User';
1241         $user2->lastname = 'A';
1242         $user2 = self::getDataGenerator()->create_user($user2);
1244         $user3 = new stdClass();
1245         $user3->firstname = 'User';
1246         $user3->lastname = 'B';
1247         $user3 = self::getDataGenerator()->create_user($user3);
1249         $user4 = new stdClass();
1250         $user4->firstname = 'User';
1251         $user4->lastname = 'C';
1252         $user4 = self::getDataGenerator()->create_user($user4);
1254         $user5 = new stdClass();
1255         $user5->firstname = 'User';
1256         $user5->lastname = 'D';
1257         $user5 = self::getDataGenerator()->create_user($user5);
1259         // Add some users as contacts.
1260         \core_message\api::add_contact($user1->id, $user2->id);
1261         \core_message\api::add_contact($user1->id, $user3->id);
1262         \core_message\api::add_contact($user1->id, $user4->id);
1264         // Retrieve the contacts.
1265         $contacts = \core_message\api::get_contacts($user1->id);
1267         // Confirm the data is correct.
1268         $this->assertEquals(3, count($contacts));
1269         usort($contacts, ['static', 'sort_contacts']);
1271         $contact1 = $contacts[0];
1272         $contact2 = $contacts[1];
1273         $contact3 = $contacts[2];
1275         $this->assertEquals($user2->id, $contact1->userid);
1276         $this->assertEmpty($contact1->useridfrom);
1277         $this->assertFalse($contact1->ismessaging);
1278         $this->assertNull($contact1->lastmessage);
1279         $this->assertNull($contact1->messageid);
1280         $this->assertNull($contact1->isonline);
1281         $this->assertFalse($contact1->isread);
1282         $this->assertFalse($contact1->isblocked);
1283         $this->assertNull($contact1->unreadcount);
1285         $this->assertEquals($user3->id, $contact2->userid);
1286         $this->assertEmpty($contact2->useridfrom);
1287         $this->assertFalse($contact2->ismessaging);
1288         $this->assertNull($contact2->lastmessage);
1289         $this->assertNull($contact2->messageid);
1290         $this->assertNull($contact2->isonline);
1291         $this->assertFalse($contact2->isread);
1292         $this->assertFalse($contact2->isblocked);
1293         $this->assertNull($contact2->unreadcount);
1295         $this->assertEquals($user4->id, $contact3->userid);
1296         $this->assertEmpty($contact3->useridfrom);
1297         $this->assertFalse($contact3->ismessaging);
1298         $this->assertNull($contact3->lastmessage);
1299         $this->assertNull($contact3->messageid);
1300         $this->assertNull($contact3->isonline);
1301         $this->assertFalse($contact3->isread);
1302         $this->assertFalse($contact3->isblocked);
1303         $this->assertNull($contact3->unreadcount);
1304     }
1306     /**
1307      * Tests retrieving messages.
1308      */
1309     public function test_get_messages() {
1310         // Create some users.
1311         $user1 = self::getDataGenerator()->create_user();
1312         $user2 = self::getDataGenerator()->create_user();
1314         // The person doing the search.
1315         $this->setUser($user1);
1317         // Send some messages back and forth.
1318         $time = 1;
1319         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1320         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1321         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1322         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1324         // Retrieve the messages.
1325         $messages = \core_message\api::get_messages($user1->id, $user2->id);
1326         $this->assertDebuggingCalledCount(3);
1328         // Confirm the message data is correct.
1329         $this->assertEquals(4, count($messages));
1331         $message1 = $messages[0];
1332         $message2 = $messages[1];
1333         $message3 = $messages[2];
1334         $message4 = $messages[3];
1336         $this->assertEquals($user1->id, $message1->useridfrom);
1337         $this->assertEquals($user2->id, $message1->useridto);
1338         $this->assertTrue($message1->displayblocktime);
1339         $this->assertContains('Yo!', $message1->text);
1341         $this->assertEquals($user2->id, $message2->useridfrom);
1342         $this->assertEquals($user1->id, $message2->useridto);
1343         $this->assertFalse($message2->displayblocktime);
1344         $this->assertContains('Sup mang?', $message2->text);
1346         $this->assertEquals($user1->id, $message3->useridfrom);
1347         $this->assertEquals($user2->id, $message3->useridto);
1348         $this->assertFalse($message3->displayblocktime);
1349         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1351         $this->assertEquals($user2->id, $message4->useridfrom);
1352         $this->assertEquals($user1->id, $message4->useridto);
1353         $this->assertFalse($message4->displayblocktime);
1354         $this->assertContains('Word.', $message4->text);
1355     }
1357     /**
1358      * Tests retrieving conversation messages.
1359      */
1360     public function test_get_conversation_messages() {
1361         // Create some users.
1362         $user1 = self::getDataGenerator()->create_user();
1363         $user2 = self::getDataGenerator()->create_user();
1365         // Create conversation.
1366         $conversation = \core_message\api::create_conversation(
1367             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1368             [$user1->id, $user2->id]
1369         );
1371         // The person doing the search.
1372         $this->setUser($user1);
1374         // Send some messages back and forth.
1375         $time = 1;
1376         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1377         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1378         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1379         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1381         // Retrieve the messages.
1382         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1384         // Confirm the conversation id is correct.
1385         $this->assertEquals($conversation->id, $convmessages['id']);
1387         // Confirm the message data is correct.
1388         $messages = $convmessages['messages'];
1389         $this->assertEquals(4, count($messages));
1390         $message1 = $messages[0];
1391         $message2 = $messages[1];
1392         $message3 = $messages[2];
1393         $message4 = $messages[3];
1395         $this->assertEquals($user1->id, $message1->useridfrom);
1396         $this->assertContains('Yo!', $message1->text);
1398         $this->assertEquals($user2->id, $message2->useridfrom);
1399         $this->assertContains('Sup mang?', $message2->text);
1401         $this->assertEquals($user1->id, $message3->useridfrom);
1402         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1404         $this->assertEquals($user1->id, $message4->useridfrom);
1405         $this->assertContains('Word.', $message4->text);
1407         // Confirm the members data is correct.
1408         $members = $convmessages['members'];
1409         $this->assertEquals(2, count($members));
1410     }
1412     /**
1413      * Tests retrieving group conversation messages.
1414      */
1415     public function test_get_group_conversation_messages() {
1416         // Create some users.
1417         $user1 = self::getDataGenerator()->create_user();
1418         $user2 = self::getDataGenerator()->create_user();
1419         $user3 = self::getDataGenerator()->create_user();
1420         $user4 = self::getDataGenerator()->create_user();
1422         // Create group conversation.
1423         $conversation = \core_message\api::create_conversation(
1424             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1425             [$user1->id, $user2->id, $user3->id, $user4->id]
1426         );
1428         // The person doing the search.
1429         $this->setUser($user1);
1431         // Send some messages back and forth.
1432         $time = 1;
1433         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1434         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1435         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1436         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1437         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
1439         // Retrieve the messages.
1440         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1442         // Confirm the conversation id is correct.
1443         $this->assertEquals($conversation->id, $convmessages['id']);
1445         // Confirm the message data is correct.
1446         $messages = $convmessages['messages'];
1447         $this->assertEquals(5, count($messages));
1449         $message1 = $messages[0];
1450         $message2 = $messages[1];
1451         $message3 = $messages[2];
1452         $message4 = $messages[3];
1453         $message5 = $messages[4];
1455         $this->assertEquals($user1->id, $message1->useridfrom);
1456         $this->assertContains('Yo!', $message1->text);
1458         $this->assertEquals($user2->id, $message2->useridfrom);
1459         $this->assertContains('Sup mang?', $message2->text);
1461         $this->assertEquals($user3->id, $message3->useridfrom);
1462         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1464         $this->assertEquals($user1->id, $message4->useridfrom);
1465         $this->assertContains('Word.', $message4->text);
1467         $this->assertEquals($user2->id, $message5->useridfrom);
1468         $this->assertContains('Yeah!', $message5->text);
1470         // Confirm the members data is correct.
1471         $members = $convmessages['members'];
1472         $this->assertEquals(3, count($members));
1473     }
1475     /**
1476      * Test retrieving conversation messages by providing a minimum timecreated value.
1477      */
1478     public function test_get_conversation_messages_time_from_only() {
1479         // Create some users.
1480         $user1 = self::getDataGenerator()->create_user();
1481         $user2 = self::getDataGenerator()->create_user();
1482         $user3 = self::getDataGenerator()->create_user();
1483         $user4 = self::getDataGenerator()->create_user();
1485         // Create group conversation.
1486         $conversation = \core_message\api::create_conversation(
1487             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1488             [$user1->id, $user2->id, $user3->id, $user4->id]
1489         );
1491         // The person doing the search.
1492         $this->setUser($user1);
1494         // Send some messages back and forth.
1495         $time = 1;
1496         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1497         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1498         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1499         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1501         // Retrieve the messages from $time, which should be all of them.
1502         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
1504         // Confirm the conversation id is correct.
1505         $this->assertEquals($conversation->id, $convmessages['id']);
1507         // Confirm the message data is correct.
1508         $messages = $convmessages['messages'];
1509         $this->assertEquals(4, count($messages));
1511         $message1 = $messages[0];
1512         $message2 = $messages[1];
1513         $message3 = $messages[2];
1514         $message4 = $messages[3];
1516         $this->assertContains('Message 1', $message1->text);
1517         $this->assertContains('Message 2', $message2->text);
1518         $this->assertContains('Message 3', $message3->text);
1519         $this->assertContains('Message 4', $message4->text);
1521         // Confirm the members data is correct.
1522         $members = $convmessages['members'];
1523         $this->assertEquals(3, count($members));
1525         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1526         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1527             'timecreated ASC', $time + 3);
1529         // Confirm the conversation id is correct.
1530         $this->assertEquals($conversation->id, $convmessages['id']);
1532         // Confirm the message data is correct.
1533         $messages = $convmessages['messages'];
1534         $this->assertEquals(2, count($messages));
1536         $message1 = $messages[0];
1537         $message2 = $messages[1];
1539         $this->assertContains('Message 3', $message1->text);
1540         $this->assertContains('Message 4', $message2->text);
1542         // Confirm the members data is correct.
1543         $members = $convmessages['members'];
1544         $this->assertEquals(2, count($members));
1545     }
1547     /**
1548      * Test retrieving conversation messages by providing a maximum timecreated value.
1549      */
1550     public function test_get_conversation_messages_time_to_only() {
1551         // Create some users.
1552         $user1 = self::getDataGenerator()->create_user();
1553         $user2 = self::getDataGenerator()->create_user();
1554         $user3 = self::getDataGenerator()->create_user();
1555         $user4 = self::getDataGenerator()->create_user();
1557         // Create group conversation.
1558         $conversation = \core_message\api::create_conversation(
1559             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1560             [$user1->id, $user2->id, $user3->id, $user4->id]
1561         );
1563         // The person doing the search.
1564         $this->setUser($user1);
1566         // Send some messages back and forth.
1567         $time = 1;
1568         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1569         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1570         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1571         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1573         // Retrieve the messages up until $time + 4, which should be all of them.
1574         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1575             0, $time + 4);
1577         // Confirm the conversation id is correct.
1578         $this->assertEquals($conversation->id, $convmessages['id']);
1580         // Confirm the message data is correct.
1581         $messages = $convmessages['messages'];
1582         $this->assertEquals(4, count($messages));
1584         $message1 = $messages[0];
1585         $message2 = $messages[1];
1586         $message3 = $messages[2];
1587         $message4 = $messages[3];
1589         $this->assertContains('Message 1', $message1->text);
1590         $this->assertContains('Message 2', $message2->text);
1591         $this->assertContains('Message 3', $message3->text);
1592         $this->assertContains('Message 4', $message4->text);
1594         // Confirm the members data is correct.
1595         $members = $convmessages['members'];
1596         $this->assertEquals(3, count($members));
1598         // Retrieve the messages up until $time + 2, which should be the first two.
1599         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1600             0, $time + 2);
1602         // Confirm the conversation id is correct.
1603         $this->assertEquals($conversation->id, $convmessages['id']);
1605         // Confirm the message data is correct.
1606         $messages = $convmessages['messages'];
1607         $this->assertEquals(2, count($messages));
1609         $message1 = $messages[0];
1610         $message2 = $messages[1];
1612         $this->assertContains('Message 1', $message1->text);
1613         $this->assertContains('Message 2', $message2->text);
1615         // Confirm the members data is correct.
1616         $members = $convmessages['members'];
1617         $this->assertEquals(2, count($members));
1618     }
1620     /**
1621      * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
1622      */
1623     public function test_get_conversation_messages_time_from_and_to() {
1624         // Create some users.
1625         $user1 = self::getDataGenerator()->create_user();
1626         $user2 = self::getDataGenerator()->create_user();
1627         $user3 = self::getDataGenerator()->create_user();
1628         $user4 = self::getDataGenerator()->create_user();
1630         // Create group conversation.
1631         $conversation = \core_message\api::create_conversation(
1632             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1633             [$user1->id, $user2->id, $user3->id, $user4->id]
1634         );
1636         // The person doing the search.
1637         $this->setUser($user1);
1639         // Send some messages back and forth.
1640         $time = 1;
1641         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1642         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1643         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1644         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1646         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1647         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1648             'timecreated ASC', $time + 2, $time + 3);
1650         // Confirm the conversation id is correct.
1651         $this->assertEquals($conversation->id, $convmessages['id']);
1653         // Confirm the message data is correct.
1654         $messages = $convmessages['messages'];
1655         $this->assertEquals(2, count($messages));
1657         $message1 = $messages[0];
1658         $message2 = $messages[1];
1660         $this->assertContains('Message 2', $message1->text);
1661         $this->assertContains('Message 3', $message2->text);
1663         // Confirm the members data is correct.
1664         $members = $convmessages['members'];
1665         $this->assertEquals(2, count($members));
1666     }
1669     /**
1670      * Test retrieving conversation messages by providing a limitfrom value.
1671      */
1672     public function test_get_conversation_messages_limitfrom_only() {
1673         // Create some users.
1674         $user1 = self::getDataGenerator()->create_user();
1675         $user2 = self::getDataGenerator()->create_user();
1676         $user3 = self::getDataGenerator()->create_user();
1677         $user4 = self::getDataGenerator()->create_user();
1679         // Create group conversation.
1680         $conversation = \core_message\api::create_conversation(
1681             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1682             [$user1->id, $user2->id, $user3->id, $user4->id]
1683         );
1685         // The person doing the search.
1686         $this->setUser($user1);
1688         // Send some messages back and forth.
1689         $time = 1;
1690         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1691         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1692         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1693         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1695         // Retrieve the messages from $time, which should be all of them.
1696         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
1698         // Confirm the conversation id is correct.
1699         $messages = $convmessages['messages'];
1700         $this->assertEquals($conversation->id, $convmessages['id']);
1702         // Confirm the message data is correct.
1703         $this->assertEquals(2, count($messages));
1705         $message1 = $messages[0];
1706         $message2 = $messages[1];
1708         $this->assertContains('Message 3', $message1->text);
1709         $this->assertContains('Message 4', $message2->text);
1711         // Confirm the members data is correct.
1712         $members = $convmessages['members'];
1713         $this->assertEquals(2, count($members));
1714     }
1716     /**
1717      * Test retrieving conversation messages by providing a limitnum value.
1718      */
1719     public function test_get_conversation_messages_limitnum() {
1720         // Create some users.
1721         $user1 = self::getDataGenerator()->create_user();
1722         $user2 = self::getDataGenerator()->create_user();
1723         $user3 = self::getDataGenerator()->create_user();
1724         $user4 = self::getDataGenerator()->create_user();
1726         // Create group conversation.
1727         $conversation = \core_message\api::create_conversation(
1728             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1729             [$user1->id, $user2->id, $user3->id, $user4->id]
1730         );
1732         // The person doing the search.
1733         $this->setUser($user1);
1735         // Send some messages back and forth.
1736         $time = 1;
1737         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1738         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1739         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1740         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1742         // Retrieve the messages from $time, which should be all of them.
1743         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
1745         // Confirm the conversation id is correct.
1746         $messages = $convmessages['messages'];
1747         $this->assertEquals($conversation->id, $convmessages['id']);
1749         // Confirm the message data is correct.
1750         $messages = $convmessages['messages'];
1751         $this->assertEquals(1, count($messages));
1753         $message1 = $messages[0];
1755         $this->assertContains('Message 3', $message1->text);
1757         // Confirm the members data is correct.
1758         $members = $convmessages['members'];
1759         $this->assertEquals(1, count($members));
1760     }
1762     /**
1763      * Tests retrieving most recent message.
1764      */
1765     public function test_get_most_recent_message() {
1766         // Create some users.
1767         $user1 = self::getDataGenerator()->create_user();
1768         $user2 = self::getDataGenerator()->create_user();
1770         // The person doing the search.
1771         $this->setUser($user1);
1773         // Send some messages back and forth.
1774         $time = 1;
1775         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1776         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1777         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1778         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1780         // Retrieve the most recent messages.
1781         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1782         $this->assertDebuggingCalledCount(3);
1784         // Check the results are correct.
1785         $this->assertEquals($user2->id, $message->useridfrom);
1786         $this->assertEquals($user1->id, $message->useridto);
1787         $this->assertContains('Word.', $message->text);
1788     }
1790     /**
1791      * Tests retrieving most recent conversation message.
1792      */
1793     public function test_get_most_recent_conversation_message() {
1794         // Create some users.
1795         $user1 = self::getDataGenerator()->create_user();
1796         $user2 = self::getDataGenerator()->create_user();
1797         $user3 = self::getDataGenerator()->create_user();
1799         // Create group conversation.
1800         $conversation = \core_message\api::create_conversation(
1801             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1802             [$user1->id, $user2->id, $user3->id]
1803         );
1805         // The person getting the most recent conversation message.
1806         $this->setUser($user1);
1808         // Send some messages back and forth.
1809         $time = 1;
1810         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1811         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1812         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1813         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
1815         // Retrieve the most recent messages.
1816         $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
1818         // Check the results are correct.
1819         $this->assertEquals($user2->id, $message->useridfrom);
1820         $this->assertContains('Word.', $message->text);
1821     }
1823     /**
1824      * Tests retrieving a user's profile.
1825      */
1826     public function test_get_profile() {
1827         // Create some users.
1828         $user1 = self::getDataGenerator()->create_user();
1830         $user2 = new stdClass();
1831         $user2->country = 'AU';
1832         $user2->city = 'Perth';
1833         $user2 = self::getDataGenerator()->create_user($user2);
1835         // The person doing the search.
1836         $this->setUser($user1);
1838         // Get the profile.
1839         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1841         $this->assertEquals($user2->id, $profile->userid);
1842         $this->assertEmpty($profile->email);
1843         $this->assertEmpty($profile->country);
1844         $this->assertEmpty($profile->city);
1845         $this->assertEquals(fullname($user2), $profile->fullname);
1846         $this->assertNull($profile->isonline);
1847         $this->assertFalse($profile->isblocked);
1848         $this->assertFalse($profile->iscontact);
1849     }
1851     /**
1852      * Tests retrieving a user's profile.
1853      */
1854     public function test_get_profile_as_admin() {
1855         // The person doing the search.
1856         $this->setAdminUser();
1858         // Create some users.
1859         $user1 = self::getDataGenerator()->create_user();
1861         $user2 = new stdClass();
1862         $user2->country = 'AU';
1863         $user2->city = 'Perth';
1864         $user2 = self::getDataGenerator()->create_user($user2);
1866         // Get the profile.
1867         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1869         $this->assertEquals($user2->id, $profile->userid);
1870         $this->assertEquals($user2->email, $profile->email);
1871         $this->assertEquals($user2->country, $profile->country);
1872         $this->assertEquals($user2->city, $profile->city);
1873         $this->assertEquals(fullname($user2), $profile->fullname);
1874         $this->assertFalse($profile->isonline);
1875         $this->assertFalse($profile->isblocked);
1876         $this->assertFalse($profile->iscontact);
1877     }
1879     /**
1880      * Tests checking if a user can mark all messages as read.
1881      */
1882     public function test_can_mark_all_messages_as_read() {
1883         // Set as the admin.
1884         $this->setAdminUser();
1886         // Create some users.
1887         $user1 = self::getDataGenerator()->create_user();
1888         $user2 = self::getDataGenerator()->create_user();
1889         $user3 = self::getDataGenerator()->create_user();
1891         // Send some messages back and forth.
1892         $time = 1;
1893         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1894         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1895         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1896         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1898         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1900         // The admin can do anything.
1901         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1903         // Set as the user 1.
1904         $this->setUser($user1);
1906         // The user can mark the messages as he is in the conversation.
1907         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1909         // User 1 can not mark the messages read for user 2.
1910         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
1912         // This user is not a part of the conversation.
1913         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
1914     }
1916     /**
1917      * Tests checking if a user can delete a conversation.
1918      */
1919     public function test_can_delete_conversation() {
1920         // Set as the admin.
1921         $this->setAdminUser();
1923         // Create some users.
1924         $user1 = self::getDataGenerator()->create_user();
1925         $user2 = self::getDataGenerator()->create_user();
1927         // Send some messages back and forth.
1928         $time = 1;
1929         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1930         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1931         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1932         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1934         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1936         // The admin can do anything.
1937         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1939         // Set as the user 1.
1940         $this->setUser($user1);
1942         // They can delete their own messages.
1943         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1945         // They can't delete someone elses.
1946         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
1947     }
1949     /**
1950      * Tests deleting a conversation.
1951      */
1952     public function test_delete_conversation() {
1953         global $DB;
1955         // Create some users.
1956         $user1 = self::getDataGenerator()->create_user();
1957         $user2 = self::getDataGenerator()->create_user();
1959         // The person doing the search.
1960         $this->setUser($user1);
1962         // Send some messages back and forth.
1963         $time = 1;
1964         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1965         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1966         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1967         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1969         // Delete the conversation as user 1.
1970         \core_message\api::delete_conversation($user1->id, $user2->id);
1971         $this->assertDebuggingCalled();
1973         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1974         $this->assertCount(4, $muas);
1975         // Sort by id.
1976         ksort($muas);
1978         $mua1 = array_shift($muas);
1979         $mua2 = array_shift($muas);
1980         $mua3 = array_shift($muas);
1981         $mua4 = array_shift($muas);
1983         $this->assertEquals($user1->id, $mua1->userid);
1984         $this->assertEquals($m1id, $mua1->messageid);
1985         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1987         $this->assertEquals($user1->id, $mua2->userid);
1988         $this->assertEquals($m2id, $mua2->messageid);
1989         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1991         $this->assertEquals($user1->id, $mua3->userid);
1992         $this->assertEquals($m3id, $mua3->messageid);
1993         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1995         $this->assertEquals($user1->id, $mua4->userid);
1996         $this->assertEquals($m4id, $mua4->messageid);
1997         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1998     }
2000     /**
2001      * Tests deleting a conversation by conversation id.
2002      */
2003     public function test_delete_conversation_by_id() {
2004         global $DB;
2006         // Create some users.
2007         $user1 = self::getDataGenerator()->create_user();
2008         $user2 = self::getDataGenerator()->create_user();
2010         // The person doing the search.
2011         $this->setUser($user1);
2013         // Send some messages back and forth.
2014         $time = 1;
2015         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2016         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2017         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2018         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2020         // Delete the conversation as user 1.
2021         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2022         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2024         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2025         $this->assertCount(4, $muas);
2026         // Sort by id.
2027         ksort($muas);
2029         $mua1 = array_shift($muas);
2030         $mua2 = array_shift($muas);
2031         $mua3 = array_shift($muas);
2032         $mua4 = array_shift($muas);
2034         $this->assertEquals($user1->id, $mua1->userid);
2035         $this->assertEquals($m1id, $mua1->messageid);
2036         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2038         $this->assertEquals($user1->id, $mua2->userid);
2039         $this->assertEquals($m2id, $mua2->messageid);
2040         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2042         $this->assertEquals($user1->id, $mua3->userid);
2043         $this->assertEquals($m3id, $mua3->messageid);
2044         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2046         $this->assertEquals($user1->id, $mua4->userid);
2047         $this->assertEquals($m4id, $mua4->messageid);
2048         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2049     }
2051     /**
2052      * Tests counting unread conversations.
2053      */
2054     public function test_count_unread_conversations() {
2055         $this->resetAfterTest(true);
2057         // Create some users.
2058         $user1 = self::getDataGenerator()->create_user();
2059         $user2 = self::getDataGenerator()->create_user();
2060         $user3 = self::getDataGenerator()->create_user();
2061         $user4 = self::getDataGenerator()->create_user();
2063         // The person wanting the conversation count.
2064         $this->setUser($user1);
2066         // Send some messages back and forth, have some different conversations with different users.
2067         $this->send_fake_message($user1, $user2, 'Yo!');
2068         $this->send_fake_message($user2, $user1, 'Sup mang?');
2069         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2070         $this->send_fake_message($user2, $user1, 'Word.');
2072         $this->send_fake_message($user1, $user3, 'Booyah');
2073         $this->send_fake_message($user3, $user1, 'Whaaat?');
2074         $this->send_fake_message($user1, $user3, 'Nothing.');
2075         $this->send_fake_message($user3, $user1, 'Cool.');
2077         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2078         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2079         $this->send_fake_message($user1, $user4, 'Dope.');
2081         // Check the amount for the current user.
2082         $this->assertEquals(3, core_message\api::count_unread_conversations());
2084         // Check the amount for the second user.
2085         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2086     }
2088     /**
2089      * Tests deleting a conversation.
2090      */
2091     public function test_get_all_message_preferences() {
2092         $user = self::getDataGenerator()->create_user();
2093         $this->setUser($user);
2095         // Set a couple of preferences to test.
2096         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2097         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2099         $processors = get_message_processors();
2100         $providers = message_get_providers_for_user($user->id);
2101         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2103         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2104         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2105     }
2107     /**
2108      * Tests the user can post a message.
2109      */
2110     public function test_can_post_message() {
2111         // Create some users.
2112         $user1 = self::getDataGenerator()->create_user();
2113         $user2 = self::getDataGenerator()->create_user();
2115         // Set as the first user.
2116         $this->setUser($user1);
2118         // With the default privacy setting, users can't message them.
2119         $this->assertFalse(\core_message\api::can_post_message($user2));
2121         // Enrol users to the same course.
2122         $course = $this->getDataGenerator()->create_course();
2123         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2124         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2125         // After enrolling users to the course, they should be able to message them with the default privacy setting.
2126         $this->assertTrue(\core_message\api::can_post_message($user2));
2127     }
2129     /**
2130      * Tests the user can't post a message without proper capability.
2131      */
2132     public function test_can_post_message_without_sendmessage_cap() {
2133         global $DB;
2135         // Create some users.
2136         $user1 = self::getDataGenerator()->create_user();
2137         $user2 = self::getDataGenerator()->create_user();
2139         // Set as the user 1.
2140         $this->setUser($user1);
2142         // Remove the capability to send a message.
2143         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
2144         unassign_capability('moodle/site:sendmessage', $roleids['user'],
2145             context_system::instance());
2147         // Check that we can not post a message without the capability.
2148         $this->assertFalse(\core_message\api::can_post_message($user2));
2149     }
2151     /**
2152      * Tests the user can post a message when they are contact.
2153      */
2154     public function test_can_post_message_when_contact() {
2155         // Create some users.
2156         $user1 = self::getDataGenerator()->create_user();
2157         $user2 = self::getDataGenerator()->create_user();
2159         // Set as the first user.
2160         $this->setUser($user1);
2162         // Check that we can not send user2 a message.
2163         $this->assertFalse(\core_message\api::can_post_message($user2));
2165         // Add users as contacts.
2166         \core_message\api::add_contact($user1->id, $user2->id);
2168         // Check that the return result is now true.
2169         $this->assertTrue(\core_message\api::can_post_message($user2));
2170     }
2172     /**
2173      * Tests the user can't post a message if they are not a contact and the user
2174      * has requested messages only from contacts.
2175      */
2176     public function test_can_post_message_when_not_contact() {
2177         // Create some users.
2178         $user1 = self::getDataGenerator()->create_user();
2179         $user2 = self::getDataGenerator()->create_user();
2181         // Set as the first user.
2182         $this->setUser($user1);
2184         // Set the second user's preference to not receive messages from non-contacts.
2185         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2187         // Check that we can not send user 2 a message.
2188         $this->assertFalse(\core_message\api::can_post_message($user2));
2189     }
2191     /**
2192      * Tests the user can't post a message if they are blocked.
2193      */
2194     public function test_can_post_message_when_blocked() {
2195         // Create some users.
2196         $user1 = self::getDataGenerator()->create_user();
2197         $user2 = self::getDataGenerator()->create_user();
2199         // Set the user.
2200         $this->setUser($user1);
2202         // Block the second user.
2203         \core_message\api::block_user($user1->id, $user2->id);
2205         // Check that the second user can no longer send the first user a message.
2206         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
2207     }
2209     /**
2210      * Tests the user can post a message when site-wide messaging setting is enabled,
2211      * even if they are not a contact and are not members of the same course.
2212      */
2213     public function test_can_post_message_site_messaging_setting() {
2214         // Create some users.
2215         $user1 = self::getDataGenerator()->create_user();
2216         $user2 = self::getDataGenerator()->create_user();
2218         // Set as the first user.
2219         $this->setUser($user1);
2221         // By default, user only can be messaged by contacts and members of any of his/her courses.
2222         $this->assertFalse(\core_message\api::can_post_message($user2));
2224         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2225         set_config('messagingallusers', true);
2227         // Set the second user's preference to receive messages from everybody.
2228         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
2230         // Check that we can send user2 a message.
2231         $this->assertTrue(\core_message\api::can_post_message($user2));
2233         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
2234         // and members sharing a course with her.
2235         set_config('messagingallusers', false);
2237         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
2238         $this->assertFalse(\core_message\api::can_post_message($user2));
2240         // Enrol users to the same course.
2241         $course = $this->getDataGenerator()->create_course();
2242         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2243         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2244         // Check that we can send user2 a message because they are sharing a course.
2245         $this->assertTrue(\core_message\api::can_post_message($user2));
2247         // Set the second user's preference to receive messages only from contacts.
2248         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2249         // Check that now the user2 can't be contacted because user1 is not their contact.
2250         $this->assertFalse(\core_message\api::can_post_message($user2));
2252         // Make contacts user1 and user2.
2253         \core_message\api::add_contact($user2->id, $user1->id);
2254         // Check that we can send user2 a message because they are contacts.
2255         $this->assertTrue(\core_message\api::can_post_message($user2));
2256     }
2258     /**
2259      * Tests the user with the messageanyuser capability can post a message.
2260      */
2261     public function test_can_post_message_with_messageanyuser_cap() {
2262         global $DB;
2264         // Create some users.
2265         $teacher1 = self::getDataGenerator()->create_user();
2266         $student1 = self::getDataGenerator()->create_user();
2267         $student2 = self::getDataGenerator()->create_user();
2269         // Create users not enrolled in any course.
2270         $user1 = self::getDataGenerator()->create_user();
2272         // Create a course.
2273         $course1 = $this->getDataGenerator()->create_course();
2275         // Enrol the users in the course.
2276         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
2277         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
2278         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
2280         // Set some student preferences to not receive messages from non-contacts.
2281         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
2283         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
2284         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
2285         // Check that the teacher can't contact user1 because it's not his teacher.
2286         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
2288         // Remove the messageanyuser capability from the course1 for teachers.
2289         $coursecontext = context_course::instance($course1->id);
2290         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
2291         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
2292         $coursecontext->mark_dirty();
2294         // Check that we can't send user1 a message because they are not contacts.
2295         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
2296         // However, teacher can message student2 because they are sharing a course.
2297         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
2298     }
2300     /**
2301      * Tests get_user_privacy_messaging_preference method.
2302      */
2303     public function test_get_user_privacy_messaging_preference() {
2304         // Create some users.
2305         $user1 = self::getDataGenerator()->create_user();
2306         $user2 = self::getDataGenerator()->create_user();
2307         $user3 = self::getDataGenerator()->create_user();
2309         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2310         set_config('messagingallusers', true);
2312         // Set some user preferences.
2313         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
2314         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2316         // Check the returned value for each user.
2317         $this->assertEquals(
2318             \core_message\api::MESSAGE_PRIVACY_SITE,
2319             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2320         );
2321         $this->assertEquals(
2322             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2323             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2324         );
2325         $this->assertEquals(
2326             \core_message\api::MESSAGE_PRIVACY_SITE,
2327             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2328         );
2330         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
2331         set_config('messagingallusers', false);
2333         // Check the returned value for each user.
2334         $this->assertEquals(
2335             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2336             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2337         );
2338         $this->assertEquals(
2339             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2340             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2341         );
2342         $this->assertEquals(
2343             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2344             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2345         );
2346     }
2348     /**
2349      * Tests that when blocking messages from non-contacts is enabled that
2350      * non-contacts trying to send a message return false.
2351      */
2352     public function test_is_user_non_contact_blocked() {
2353         // Create some users.
2354         $user1 = self::getDataGenerator()->create_user();
2355         $user2 = self::getDataGenerator()->create_user();
2357         // Set as the first user.
2358         $this->setUser($user1);
2360         // By default, user only can be messaged by contacts and members of any of his/her courses.
2361         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2362         $this->assertDebuggingCalled();
2364         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
2365         // messages from everybody.
2366         set_config('messagingallusers', true);
2367         // Check that the return result is now false because any site user can contact him/her.
2368         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2369         $this->assertDebuggingCalled();
2371         // Set the second user's preference to not receive messages from non-contacts.
2372         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2373         // Check that the return result is still true (because is even more restricted).
2374         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2375         $this->assertDebuggingCalled();
2377         // Add the first user as a contact for the second user.
2378         \core_message\api::add_contact($user2->id, $user1->id);
2380         // Check that the return result is now false.
2381         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2382         $this->assertDebuggingCalled();
2384         // Set the second user's preference to receive messages from course members.
2385         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
2386         // Check that the return result is still false (because $user1 is still his/her contact).
2387         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2388         $this->assertDebuggingCalled();
2389     }
2391     /**
2392      * Tests that we return true when a user is blocked, or false
2393      * if they are not blocked.
2394      */
2395     public function test_is_user_blocked() {
2396         // Create some users.
2397         $user1 = self::getDataGenerator()->create_user();
2398         $user2 = self::getDataGenerator()->create_user();
2400         // Set the user.
2401         $this->setUser($user1);
2403         // User shouldn't be blocked.
2404         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2405         $this->assertDebuggingCalled();
2407         // Block the user.
2408         \core_message\api::block_user($user1->id, $user2->id);
2410         // User should be blocked.
2411         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
2412         $this->assertDebuggingCalled();
2414         // Unblock the user.
2415         \core_message\api::unblock_user($user1->id, $user2->id);
2416         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2417         $this->assertDebuggingCalled();
2418     }
2420     /**
2421      * Tests that the admin is not blocked even if someone has chosen to block them.
2422      */
2423     public function test_is_user_blocked_as_admin() {
2424         // Create a user.
2425         $user1 = self::getDataGenerator()->create_user();
2427         // Set the user.
2428         $this->setUser($user1);
2430         // Block the admin user.
2431         \core_message\api::block_user($user1->id, 2);
2433         // Now change to the admin user.
2434         $this->setAdminUser();
2436         // As the admin you should still be able to send messages to the user.
2437         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
2438         $this->assertDebuggingCalled();
2439     }
2441     /*
2442      * Tes get_message_processor api.
2443      */
2444     public function test_get_message_processor() {
2445         $processors = get_message_processors(true);
2446         if (empty($processors)) {
2447             $this->markTestSkipped("No message processors found");
2448         }
2450         $name = key($processors);
2451         $processor = current($processors);
2452         $testprocessor = \core_message\api::get_message_processor($name);
2453         $this->assertEquals($processor->name, $testprocessor->name);
2454         $this->assertEquals($processor->enabled, $testprocessor->enabled);
2455         $this->assertEquals($processor->available, $testprocessor->available);
2456         $this->assertEquals($processor->configured, $testprocessor->configured);
2458         // Disable processor and test.
2459         \core_message\api::update_processor_status($testprocessor, 0);
2460         $testprocessor = \core_message\api::get_message_processor($name, true);
2461         $this->assertEmpty($testprocessor);
2462         $testprocessor = \core_message\api::get_message_processor($name);
2463         $this->assertEquals($processor->name, $testprocessor->name);
2464         $this->assertEquals(0, $testprocessor->enabled);
2466         // Enable again and test.
2467         \core_message\api::update_processor_status($testprocessor, 1);
2468         $testprocessor = \core_message\api::get_message_processor($name, true);
2469         $this->assertEquals($processor->name, $testprocessor->name);
2470         $this->assertEquals(1, $testprocessor->enabled);
2471         $testprocessor = \core_message\api::get_message_processor($name);
2472         $this->assertEquals($processor->name, $testprocessor->name);
2473         $this->assertEquals(1, $testprocessor->enabled);
2474     }
2476     /**
2477      * Test method update_processor_status.
2478      */
2479     public function test_update_processor_status() {
2480         $processors = get_message_processors();
2481         if (empty($processors)) {
2482             $this->markTestSkipped("No message processors found");
2483         }
2484         $name = key($processors);
2485         $testprocessor = current($processors);
2487         // Enable.
2488         \core_message\api::update_processor_status($testprocessor, 1);
2489         $testprocessor = \core_message\api::get_message_processor($name);
2490         $this->assertEquals(1, $testprocessor->enabled);
2492         // Disable.
2493         \core_message\api::update_processor_status($testprocessor, 0);
2494         $testprocessor = \core_message\api::get_message_processor($name);
2495         $this->assertEquals(0, $testprocessor->enabled);
2497         // Enable again.
2498         \core_message\api::update_processor_status($testprocessor, 1);
2499         $testprocessor = \core_message\api::get_message_processor($name);
2500         $this->assertEquals(1, $testprocessor->enabled);
2501     }
2503     /**
2504      * Test method is_user_enabled.
2505      */
2506     public function is_user_enabled() {
2507         $processors = get_message_processors();
2508         if (empty($processors)) {
2509             $this->markTestSkipped("No message processors found");
2510         }
2511         $name = key($processors);
2512         $testprocessor = current($processors);
2514         // Enable.
2515         \core_message\api::update_processor_status($testprocessor, 1);
2516         $status = \core_message\api::is_processor_enabled($name);
2517         $this->assertEquals(1, $status);
2519         // Disable.
2520         \core_message\api::update_processor_status($testprocessor, 0);
2521         $status = \core_message\api::is_processor_enabled($name);
2522         $this->assertEquals(0, $status);
2524         // Enable again.
2525         \core_message\api::update_processor_status($testprocessor, 1);
2526         $status = \core_message\api::is_processor_enabled($name);
2527         $this->assertEquals(1, $status);
2528     }
2530     /**
2531      * Test retrieving messages by providing a minimum timecreated value.
2532      */
2533     public function test_get_messages_time_from_only() {
2534         // Create some users.
2535         $user1 = self::getDataGenerator()->create_user();
2536         $user2 = self::getDataGenerator()->create_user();
2538         // The person doing the search.
2539         $this->setUser($user1);
2541         // Send some messages back and forth.
2542         $time = 1;
2543         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2544         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2545         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2546         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2548         // Retrieve the messages from $time, which should be all of them.
2549         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
2550         $this->assertDebuggingCalledCount(3);
2552         // Confirm the message data is correct.
2553         $this->assertEquals(4, count($messages));
2555         $message1 = $messages[0];
2556         $message2 = $messages[1];
2557         $message3 = $messages[2];
2558         $message4 = $messages[3];
2560         $this->assertContains('Message 1', $message1->text);
2561         $this->assertContains('Message 2', $message2->text);
2562         $this->assertContains('Message 3', $message3->text);
2563         $this->assertContains('Message 4', $message4->text);
2565         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2566         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
2567         $this->assertDebuggingCalledCount(3);
2569         // Confirm the message data is correct.
2570         $this->assertEquals(2, count($messages));
2572         $message1 = $messages[0];
2573         $message2 = $messages[1];
2575         $this->assertContains('Message 3', $message1->text);
2576         $this->assertContains('Message 4', $message2->text);
2577     }
2579     /**
2580      * Test retrieving messages by providing a maximum timecreated value.
2581      */
2582     public function test_get_messages_time_to_only() {
2583         // Create some users.
2584         $user1 = self::getDataGenerator()->create_user();
2585         $user2 = self::getDataGenerator()->create_user();
2587         // The person doing the search.
2588         $this->setUser($user1);
2590         // Send some messages back and forth.
2591         $time = 1;
2592         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2593         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2594         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2595         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2597         // Retrieve the messages up until $time + 4, which should be all of them.
2598         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
2599         $this->assertDebuggingCalledCount(3);
2601         // Confirm the message data is correct.
2602         $this->assertEquals(4, count($messages));
2604         $message1 = $messages[0];
2605         $message2 = $messages[1];
2606         $message3 = $messages[2];
2607         $message4 = $messages[3];
2609         $this->assertContains('Message 1', $message1->text);
2610         $this->assertContains('Message 2', $message2->text);
2611         $this->assertContains('Message 3', $message3->text);
2612         $this->assertContains('Message 4', $message4->text);
2614         // Retrieve the messages up until $time + 2, which should be the first two.
2615         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
2616         $this->assertDebuggingCalledCount(3);
2618         // Confirm the message data is correct.
2619         $this->assertEquals(2, count($messages));
2621         $message1 = $messages[0];
2622         $message2 = $messages[1];
2624         $this->assertContains('Message 1', $message1->text);
2625         $this->assertContains('Message 2', $message2->text);
2626     }
2628     /**
2629      * Test retrieving messages by providing a minimum and maximum timecreated value.
2630      */
2631     public function test_get_messages_time_from_and_to() {
2632         // Create some users.
2633         $user1 = self::getDataGenerator()->create_user();
2634         $user2 = self::getDataGenerator()->create_user();
2636         // The person doing the search.
2637         $this->setUser($user1);
2639         // Send some messages back and forth.
2640         $time = 1;
2641         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2642         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2643         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2644         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2646         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2647         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
2648         $this->assertDebuggingCalledCount(3);
2650         // Confirm the message data is correct.
2651         $this->assertEquals(2, count($messages));
2653         $message1 = $messages[0];
2654         $message2 = $messages[1];
2656         $this->assertContains('Message 2', $message1->text);
2657         $this->assertContains('Message 3', $message2->text);
2658     }
2660     /**
2661      * Test returning blocked users.
2662      */
2663     public function test_get_blocked_users() {
2664         global $USER;
2666         // Set this user as the admin.
2667         $this->setAdminUser();
2669         // Create a user to add to the admin's contact list.
2670         $user1 = $this->getDataGenerator()->create_user();
2671         $user2 = $this->getDataGenerator()->create_user();
2673         // Add users to the admin's contact list.
2674         \core_message\api::block_user($USER->id, $user2->id);
2676         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2678         // Block other user.
2679         \core_message\api::block_user($USER->id, $user1->id);
2680         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
2682         // Test deleting users.
2683         delete_user($user1);
2684         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2685     }
2687     /**
2688      * Test returning contacts with unread message count.
2689      */
2690     public function test_get_contacts_with_unread_message_count() {
2691         global $DB;
2693         $user1 = self::getDataGenerator()->create_user();
2694         $user2 = self::getDataGenerator()->create_user();
2695         $user3 = self::getDataGenerator()->create_user();
2696         $user4 = self::getDataGenerator()->create_user();
2698         // Add the users to each of their contacts.
2699         \core_message\api::add_contact($user1->id, $user2->id);
2700         \core_message\api::add_contact($user2->id, $user3->id);
2702         $this->send_fake_message($user1, $user2);
2703         $this->send_fake_message($user1, $user2);
2704         $this->send_fake_message($user1, $user2);
2705         $message4id = $this->send_fake_message($user1, $user2);
2707         $this->send_fake_message($user3, $user2);
2708         $message6id = $this->send_fake_message($user3, $user2);
2709         $this->send_fake_message($user3, $user2);
2710         $this->send_fake_message($user3, $user2);
2711         $this->send_fake_message($user3, $user2);
2713         // Send a message that should never be included as the user is not a contact.
2714         $this->send_fake_message($user4, $user2);
2716         // Get the contacts and the unread message count.
2717         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2719         // Confirm the size is correct.
2720         $this->assertCount(2, $messages);
2721         ksort($messages);
2723         $messageinfo1 = array_shift($messages);
2724         $messageinfo2 = array_shift($messages);
2726         $this->assertEquals($user1->id, $messageinfo1->id);
2727         $this->assertEquals(4, $messageinfo1->messagecount);
2728         $this->assertEquals($user3->id, $messageinfo2->id);
2729         $this->assertEquals(5, $messageinfo2->messagecount);
2731         // Mark some of the messages as read.
2732         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2733         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2734         \core_message\api::mark_message_as_read($user2->id, $m4);
2735         \core_message\api::mark_message_as_read($user2->id, $m6);
2737         // Get the contacts and the unread message count.
2738         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2740         // Confirm the size is correct.
2741         $this->assertCount(2, $messages);
2742         ksort($messages);
2744         // Confirm read messages are not included.
2745         $messageinfo1 = array_shift($messages);
2746         $messageinfo2 = array_shift($messages);
2747         $this->assertEquals($user1->id, $messageinfo1->id);
2748         $this->assertEquals(3, $messageinfo1->messagecount);
2749         $this->assertEquals($user3->id, $messageinfo2->id);
2750         $this->assertEquals(4, $messageinfo2->messagecount);
2752         // Now, let's populate the database with messages from user2 to user 1.
2753         $this->send_fake_message($user2, $user1);
2754         $this->send_fake_message($user2, $user1);
2755         $messageid = $this->send_fake_message($user2, $user1);
2757         // Send a message that should never be included as the user is not a contact.
2758         $this->send_fake_message($user4, $user1);
2760         // Get the contacts and the unread message count.
2761         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2763         // Confirm the size is correct.
2764         $this->assertCount(1, $messages);
2765         $messageinfo1 = array_shift($messages);
2766         $this->assertEquals($user2->id, $messageinfo1->id);
2767         $this->assertEquals(3, $messageinfo1->messagecount);
2769         // Mark the last message as read.
2770         $m = $DB->get_record('messages', ['id' => $messageid]);
2771         \core_message\api::mark_message_as_read($user1->id, $m);
2773         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2775         // Confirm the size is correct.
2776         $this->assertCount(1, $messages);
2778         // Confirm read messages are not included.
2779         $messageinfo1 = array_shift($messages);
2780         $this->assertEquals($user2->id, $messageinfo1->id);
2781         $this->assertEquals(2, $messageinfo1->messagecount);
2782     }
2784     /**
2785      * Test returning contacts with unread message count when there are no messages.
2786      */
2787     public function test_get_contacts_with_unread_message_count_no_messages() {
2788         $user1 = self::getDataGenerator()->create_user();
2789         $user2 = self::getDataGenerator()->create_user();
2791         // Add the users to each of their contacts.
2792         \core_message\api::add_contact($user2->id, $user1->id);
2794         // Check we get the correct message count.
2795         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2797         // Confirm the size is correct.
2798         $this->assertCount(1, $messages);
2800         $messageinfo = array_shift($messages);
2802         $this->assertEquals($user1->id, $messageinfo->id);
2803         $this->assertEquals(0, $messageinfo->messagecount);
2804     }
2806     /**
2807      * Test returning non-contacts with unread message count.
2808      */
2809     public function test_get_non_contacts_with_unread_message_count() {
2810         global $DB;
2812         $user1 = self::getDataGenerator()->create_user();
2813         $user2 = self::getDataGenerator()->create_user();
2814         $user3 = self::getDataGenerator()->create_user();
2815         $user4 = self::getDataGenerator()->create_user();
2817         // Add a user to the contact list of the users we are testing this function with.
2818         \core_message\api::add_contact($user1->id, $user4->id);
2819         \core_message\api::add_contact($user2->id, $user4->id);
2821         $this->send_fake_message($user1, $user2);
2822         $this->send_fake_message($user1, $user2);
2823         $this->send_fake_message($user1, $user2);
2824         $message4id = $this->send_fake_message($user1, $user2);
2826         $this->send_fake_message($user3, $user2);
2827         $message6id = $this->send_fake_message($user3, $user2);
2828         $this->send_fake_message($user3, $user2);
2829         $this->send_fake_message($user3, $user2);
2830         $this->send_fake_message($user3, $user2);
2832         // Send a message that should never be included as the user is a contact.
2833         $this->send_fake_message($user4, $user2);
2835         // Get the non-contacts and the unread message count.
2836         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2838         // Check we get the correct message count.
2839         ksort($messages);
2840         $this->assertCount(2, $messages);
2841         $messageinfo1 = array_shift($messages);
2842         $messageinfo2 = array_shift($messages);
2843         $this->assertEquals($user1->id, $messageinfo1->id);
2844         $this->assertEquals(4, $messageinfo1->messagecount);
2845         $this->assertEquals($user3->id, $messageinfo2->id);
2846         $this->assertEquals(5, $messageinfo2->messagecount);
2848         // Mark some of the messages as read.
2849         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2850         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2851         \core_message\api::mark_message_as_read($user2->id, $m4);
2852         \core_message\api::mark_message_as_read($user2->id, $m6);
2854         // Get the non-contacts and the unread message count.
2855         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2857         // Check the marked message is not returned in the message count.
2858         ksort($messages);
2859         $this->assertCount(2, $messages);
2860         $messageinfo1 = array_shift($messages);
2861         $messageinfo2 = array_shift($messages);
2862         $this->assertEquals($user1->id, $messageinfo1->id);
2863         $this->assertEquals(3, $messageinfo1->messagecount);
2864         $this->assertEquals($user3->id, $messageinfo2->id);
2865         $this->assertEquals(4, $messageinfo2->messagecount);
2867         // Now, let's populate the database with messages from user2 to user 1.
2868         $this->send_fake_message($user2, $user1);
2869         $this->send_fake_message($user2, $user1);
2870         $messageid = $this->send_fake_message($user2, $user1);
2872         // Send a message that should never be included as the user is a contact.
2873         $this->send_fake_message($user4, $user1);
2875         // Get the non-contacts and the unread message count.
2876         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2878         // Confirm the size is correct.
2879         $this->assertCount(1, $messages);
2880         $messageinfo1 = array_shift($messages);
2881         $this->assertEquals($user2->id, $messageinfo1->id);
2882         $this->assertEquals(3, $messageinfo1->messagecount);
2884         // Mark the last message as read.
2885         $m = $DB->get_record('messages', ['id' => $messageid]);
2886         \core_message\api::mark_message_as_read($user1->id, $m);
2888         // Get the non-contacts and the unread message count.
2889         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2891         // Check the marked message is not returned in the message count.
2892         $this->assertCount(1, $messages);
2893         $messageinfo1 = array_shift($messages);
2894         $this->assertEquals($user2->id, $messageinfo1->id);
2895         $this->assertEquals(2, $messageinfo1->messagecount);
2896     }
2898     /**
2899      * Test marking a message as read.
2900      */
2901     public function test_mark_message_as_read() {
2902         global $DB;
2904         $user1 = self::getDataGenerator()->create_user();
2905         $user2 = self::getDataGenerator()->create_user();
2907         $this->send_fake_message($user1, $user2);
2908         $m2id = $this->send_fake_message($user1, $user2);
2909         $this->send_fake_message($user2, $user1);
2910         $m4id = $this->send_fake_message($user2, $user1);
2912         $m2 = $DB->get_record('messages', ['id' => $m2id]);
2913         $m4 = $DB->get_record('messages', ['id' => $m4id]);
2914         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
2915         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
2917         // Confirm there are two user actions.
2918         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
2919         $this->assertEquals(2, count($muas));
2921         // Confirm they are correct.
2922         $mua1 = array_shift($muas);
2923         $mua2 = array_shift($muas);
2925         // Confirm first action.
2926         $this->assertEquals($user2->id, $mua1->userid);
2927         $this->assertEquals($m2id, $mua1->messageid);
2928         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
2929         $this->assertEquals(11, $mua1->timecreated);
2931         // Confirm second action.
2932         $this->assertEquals($user1->id, $mua2->userid);
2933         $this->assertEquals($m4id, $mua2->messageid);
2934         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
2935         $this->assertEquals(12, $mua2->timecreated);
2936     }
2938     /**
2939      * Test marking a notification as read.
2940      */
2941     public function test_mark_notification_as_read() {
2942         global $DB;
2944         $user1 = self::getDataGenerator()->create_user();
2945         $user2 = self::getDataGenerator()->create_user();
2947         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
2948         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
2949         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
2950         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
2952         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2953         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2955         \core_message\api::mark_notification_as_read($n2, 11);
2956         \core_message\api::mark_notification_as_read($n4, 12);
2958         // Retrieve the notifications.
2959         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2960         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2962         // Confirm they have been marked as read.
2963         $this->assertEquals(11, $n2->timeread);
2964         $this->assertEquals(12, $n4->timeread);
2965     }
2967     /**
2968      * Test a conversation is not returned if there is none.
2969      */
2970     public function test_get_conversation_between_users_no_conversation() {
2971         $user1 = self::getDataGenerator()->create_user();
2972         $user2 = self::getDataGenerator()->create_user();
2974         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2975     }
2977     /**
2978      * Test we can return a conversation that exists between users.
2979      */
2980     public function test_get_conversation_between_users_with_existing_conversation() {
2981         $user1 = self::getDataGenerator()->create_user();
2982         $user2 = self::getDataGenerator()->create_user();
2984         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2985         $this->assertDebuggingCalled();
2987         $this->assertEquals($conversationid,
2988             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2989     }
2991     /**
2992      * Test count_conversation_members for non existing conversation.
2993      */
2994     public function test_count_conversation_members_no_existing_conversation() {
2995         $this->assertEquals(0,
2996             \core_message\api::count_conversation_members(0));
2997     }
2999     /**
3000      * Test count_conversation_members for existing conversation.
3001      */
3002     public function test_count_conversation_members_existing_conversation() {
3003         $user1 = self::getDataGenerator()->create_user();
3004         $user2 = self::getDataGenerator()->create_user();
3006         $conversation = \core_message\api::create_conversation(
3007             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3008             [
3009                 $user1->id,
3010                 $user2->id
3011             ]
3012         );
3013         $conversationid = $conversation->id;
3015         $this->assertEquals(2,
3016             \core_message\api::count_conversation_members($conversationid));
3017     }
3019     /**
3020      * Test add_members_to_conversation for an individual conversation.
3021      */
3022     public function test_add_members_to_individual_conversation() {
3023         $user1 = self::getDataGenerator()->create_user();
3024         $user2 = self::getDataGenerator()->create_user();
3025         $user3 = self::getDataGenerator()->create_user();
3027         $conversation = \core_message\api::create_conversation(
3028             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3029             [
3030                 $user1->id,
3031                 $user2->id
3032             ]
3033         );
3034         $conversationid = $conversation->id;
3036         $this->expectException('moodle_exception');
3037         \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
3038     }
3040     /**
3041      * Test add_members_to_conversation for existing conversation.
3042      */
3043     public function test_add_members_to_existing_conversation() {
3044         $user1 = self::getDataGenerator()->create_user();
3045         $user2 = self::getDataGenerator()->create_user();
3046         $user3 = self::getDataGenerator()->create_user();
3048         $conversation = \core_message\api::create_conversation(
3049             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3050             [
3051                 $user1->id,
3052                 $user2->id
3053             ]
3054         );
3055         $conversationid = $conversation->id;
3057         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3058         $this->assertEquals(3,
3059             \core_message\api::count_conversation_members($conversationid));
3060     }
3062     /**
3063      * Test add_members_to_conversation for non existing conversation.
3064      */
3065     public function test_add_members_to_no_existing_conversation() {
3066         $user1 = self::getDataGenerator()->create_user();
3068         // Throw dml_missing_record_exception for non existing conversation.
3069         $this->expectException('dml_missing_record_exception');
3070         \core_message\api::add_members_to_conversation([$user1->id], 0);
3071     }
3073     /**
3074      * Test add_member_to_conversation for non existing user.
3075      */
3076     public function test_add_members_to_no_existing_user() {
3077         $user1 = self::getDataGenerator()->create_user();
3078         $user2 = self::getDataGenerator()->create_user();
3080         $conversation = \core_message\api::create_conversation(
3081             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3082             [
3083                 $user1->id,
3084                 $user2->id
3085             ]
3086         );
3087         $conversationid = $conversation->id;
3089         // Don't throw an error for non existing user, but don't add it as a member.
3090         $this->assertNull(\core_message\api::add_members_to_conversation([0], $conversationid));
3091         $this->assertEquals(2,
3092             \core_message\api::count_conversation_members($conversationid));
3093     }
3095     /**
3096      * Test add_members_to_conversation for current conversation member.
3097      */
3098     public function test_add_members_to_current_conversation_member() {
3099         $user1 = self::getDataGenerator()->create_user();
3100         $user2 = self::getDataGenerator()->create_user();
3102         $conversation = \core_message\api::create_conversation(
3103             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3104             [
3105                 $user1->id,
3106                 $user2->id
3107             ]
3108         );
3109         $conversationid = $conversation->id;
3111         // Don't add as a member a user that is already conversation member.
3112         $this->assertNull(\core_message\api::add_members_to_conversation([$user1->id], $conversationid));
3113         $this->assertEquals(2,
3114             \core_message\api::count_conversation_members($conversationid));
3115     }
3117     /**
3118      * Test add_members_to_conversation for multiple users.
3119      */
3120     public function test_add_members_for_multiple_users() {
3121         $user1 = self::getDataGenerator()->create_user();
3122         $user2 = self::getDataGenerator()->create_user();
3123         $user3 = self::getDataGenerator()->create_user();
3124         $user4 = self::getDataGenerator()->create_user();
3126         $conversation = \core_message\api::create_conversation(
3127             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3128             [
3129                 $user1->id,
3130                 $user2->id
3131             ]
3132         );
3133         $conversationid = $conversation->id;
3135         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3136         $this->assertEquals(4,
3137             \core_message\api::count_conversation_members($conversationid));
3138     }
3140     /**
3141      * Test add_members_to_conversation for multiple users, included non existing and current conversation members
3142      */
3143     public function test_add_members_for_multiple_not_valid_users() {
3144         $user1 = self::getDataGenerator()->create_user();
3145         $user2 = self::getDataGenerator()->create_user();
3146         $user3 = self::getDataGenerator()->create_user();
3148         $conversation = \core_message\api::create_conversation(
3149             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3150             [
3151                 $user1->id,
3152                 $user2->id
3153             ]
3154         );
3155         $conversationid = $conversation->id;
3157         // Don't throw errors, but don't add as members users don't exist or are already conversation members.
3158         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
3159         $this->assertEquals(3,
3160             \core_message\api::count_conversation_members($conversationid));
3161     }
3163     /**
3164      * Test remove_members_from_conversation for individual conversation.
3165      */
3166     public function test_remove_members_from_individual_conversation() {
3167         $user1 = self::getDataGenerator()->create_user();
3168         $user2 = self::getDataGenerator()->create_user();
3170         $conversation = \core_message\api::create_conversation(
3171             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3172             [
3173                 $user1->id,
3174                 $user2->id
3175             ]
3176         );
3177         $conversationid = $conversation->id;
3179         $this->expectException('moodle_exception');
3180         \core_message\api::remove_members_from_conversation([$user1->id], $conversationid);
3181     }
3183     /**
3184      * Test remove_members_from_conversation for existing conversation.
3185      */
3186     public function test_remove_members_from_existing_conversation() {
3187         $user1 = self::getDataGenerator()->create_user();
3188         $user2 = self::getDataGenerator()->create_user();
3190         $conversation = \core_message\api::create_conversation(
3191             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3192             [
3193                 $user1->id,
3194                 $user2->id
3195             ]
3196         );
3197         $conversationid = $conversation->id;
3199         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id], $conversationid));
3200         $this->assertEquals(1,
3201             \core_message\api::count_conversation_members($conversationid));
3202     }
3204     /**
3205      * Test remove_members_from_conversation for non existing conversation.
3206      */
3207     public function test_remove_members_from_no_existing_conversation() {
3208         $user1 = self::getDataGenerator()->create_user();
3210         // Throw dml_missing_record_exception for non existing conversation.
3211         $this->expectException('dml_missing_record_exception');
3212         \core_message\api::remove_members_from_conversation([$user1->id], 0);
3213     }
3215     /**
3216      * Test remove_members_from_conversation for non existing user.
3217      */
3218     public function test_remove_members_for_no_existing_user() {
3219         $user1 = self::getDataGenerator()->create_user();
3220         $user2 = self::getDataGenerator()->create_user();
3222         $conversation = \core_message\api::create_conversation(
3223             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3224             [
3225                 $user1->id,
3226                 $user2->id
3227             ]
3228         );
3229         $conversationid = $conversation->id;
3231         $this->assertNull(\core_message\api::remove_members_from_conversation([0], $conversationid));
3232         $this->assertEquals(2,
3233             \core_message\api::count_conversation_members($conversationid));
3234     }
3236     /**
3237      * Test remove_members_from_conversation for multiple users.
3238      */
3239     public function test_remove_members_for_multiple_users() {
3240         $user1 = self::getDataGenerator()->create_user();
3241         $user2 = self::getDataGenerator()->create_user();
3242         $user3 = self::getDataGenerator()->create_user();
3243         $user4 = self::getDataGenerator()->create_user();
3245         $conversation = \core_message\api::create_conversation(
3246             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3247             [
3248                 $user1->id,
3249                 $user2->id
3250             ]
3251         );
3252         $conversationid = $conversation->id;
3254         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3255         $this->assertNull(\core_message\api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
3256         $this->assertEquals(2,
3257             \core_message\api::count_conversation_members($conversationid));
3258     }
3260     /**
3261      * Test remove_members_from_conversation for multiple non valid users.
3262      */
3263     public function test_remove_members_for_multiple_no_valid_users() {
3264         $user1 = self::getDataGenerator()->create_user();
3265         $user2 = self::getDataGenerator()->create_user();
3266         $user3 = self::getDataGenerator()->create_user();
3267         $user4 = self::getDataGenerator()->create_user();
3269         $conversation = \core_message\api::create_conversation(
3270             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3271             [
3272                 $user1->id,
3273                 $user2->id
3274             ]
3275         );
3276         $conversationid = $conversation->id;
3278         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3279         $this->assertNull(
3280             \core_message\api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid)
3281         );
3282         $this->assertEquals(1,
3283             \core_message\api::count_conversation_members($conversationid));
3284     }
3286     /**
3287      * Test count_conversation_members for empty conversation.
3288      */
3289     public function test_count_conversation_members_empty_conversation() {
3290         $user1 = self::getDataGenerator()->create_user();
3291         $user2 = self::getDataGenerator()->create_user();
3293         $conversation = \core_message\api::create_conversation(
3294             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3295             [
3296                 $user1->id,
3297                 $user2->id
3298             ]
3299         );
3300         $conversationid = $conversation->id;
3302         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid));
3304         $this->assertEquals(0,
3305             \core_message\api::count_conversation_members($conversationid));
3306     }
3308     /**
3309      * Test can create a contact request.
3310      */
3311     public function test_can_create_contact_request() {
3312         global $CFG;
3314         $user1 = self::getDataGenerator()->create_user();
3315         $user2 = self::getDataGenerator()->create_user();
3317         // Disable messaging.
3318         $CFG->messaging = 0;
3319         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
3321         // Re-enable messaging.
3322         $CFG->messaging = 1;
3324         // Allow users to message anyone site-wide.
3325         $CFG->messagingallusers = 1;
3326         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
3328         // Disallow users from messaging anyone site-wide.
3329         $CFG->messagingallusers = 0;
3330         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
3332         // Put the users in the same course so a contact request should be possible.
3333         $course = self::getDataGenerator()->create_course();
3334         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3335         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3336         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
3337     }
3339     /**
3340      * Test creating a contact request.
3341      */
3342     public function test_create_contact_request() {
3343         global $DB;
3345         $user1 = self::getDataGenerator()->create_user();
3346         $user2 = self::getDataGenerator()->create_user();
3348         \core_message\api::create_contact_request($user1->id, $user2->