MDL-63725 core_message: added api::get_conversation_members
[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 verifying the sorting param for get_conversation_messages is respected().
1477      */
1478     public function test_get_conversation_messages_sorting() {
1479         // Create some users.
1480         $user1 = self::getDataGenerator()->create_user();
1481         $user2 = self::getDataGenerator()->create_user();
1482         $user3 = self::getDataGenerator()->create_user();
1484         // Create conversations - 1 group and 1 individual.
1485         $conversation = \core_message\api::create_conversation(
1486             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1487             [$user1->id, $user2->id]
1488         );
1489         $conversation2 = \core_message\api::create_conversation(
1490             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1491             [$user1->id, $user2->id, $user3->id]
1492         );
1494         // Send some messages back and forth.
1495         $time = 1;
1496         $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1497         $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1498         $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1499         $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1501         $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
1502         $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
1503         $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
1504         $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
1506         // The person doing the search.
1507         $this->setUser($user1);
1509         // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
1510         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1511         $messages = $convmessages['messages'];
1512         $this->assertEquals($m1id, $messages[0]->id);
1513         $this->assertEquals($m2id, $messages[1]->id);
1514         $this->assertEquals($m3id, $messages[2]->id);
1515         $this->assertEquals($m4id, $messages[3]->id);
1517         // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
1518         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
1519         $messages = $convmessages['messages'];
1520         $this->assertEquals($m1id, $messages[3]->id);
1521         $this->assertEquals($m2id, $messages[2]->id);
1522         $this->assertEquals($m3id, $messages[1]->id);
1523         $this->assertEquals($m4id, $messages[0]->id);
1525         // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
1526         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
1527         $messages = $convmessages['messages'];
1528         $this->assertEquals($gm1id, $messages[0]->id);
1529         $this->assertEquals($gm2id, $messages[1]->id);
1530         $this->assertEquals($gm3id, $messages[2]->id);
1531         $this->assertEquals($gm4id, $messages[3]->id);
1533         // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
1534         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
1535         $messages = $convmessages['messages'];
1536         $this->assertEquals($gm1id, $messages[3]->id);
1537         $this->assertEquals($gm2id, $messages[2]->id);
1538         $this->assertEquals($gm3id, $messages[1]->id);
1539         $this->assertEquals($gm4id, $messages[0]->id);
1540     }
1542     /**
1543      * Test retrieving conversation messages by providing a minimum timecreated value.
1544      */
1545     public function test_get_conversation_messages_time_from_only() {
1546         // Create some users.
1547         $user1 = self::getDataGenerator()->create_user();
1548         $user2 = self::getDataGenerator()->create_user();
1549         $user3 = self::getDataGenerator()->create_user();
1550         $user4 = self::getDataGenerator()->create_user();
1552         // Create group conversation.
1553         $conversation = \core_message\api::create_conversation(
1554             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1555             [$user1->id, $user2->id, $user3->id, $user4->id]
1556         );
1558         // The person doing the search.
1559         $this->setUser($user1);
1561         // Send some messages back and forth.
1562         $time = 1;
1563         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1564         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1565         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1566         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1568         // Retrieve the messages from $time, which should be all of them.
1569         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
1571         // Confirm the conversation id is correct.
1572         $this->assertEquals($conversation->id, $convmessages['id']);
1574         // Confirm the message data is correct.
1575         $messages = $convmessages['messages'];
1576         $this->assertEquals(4, count($messages));
1578         $message1 = $messages[0];
1579         $message2 = $messages[1];
1580         $message3 = $messages[2];
1581         $message4 = $messages[3];
1583         $this->assertContains('Message 1', $message1->text);
1584         $this->assertContains('Message 2', $message2->text);
1585         $this->assertContains('Message 3', $message3->text);
1586         $this->assertContains('Message 4', $message4->text);
1588         // Confirm the members data is correct.
1589         $members = $convmessages['members'];
1590         $this->assertEquals(3, count($members));
1592         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1593         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1594             'timecreated ASC', $time + 3);
1596         // Confirm the conversation id is correct.
1597         $this->assertEquals($conversation->id, $convmessages['id']);
1599         // Confirm the message data is correct.
1600         $messages = $convmessages['messages'];
1601         $this->assertEquals(2, count($messages));
1603         $message1 = $messages[0];
1604         $message2 = $messages[1];
1606         $this->assertContains('Message 3', $message1->text);
1607         $this->assertContains('Message 4', $message2->text);
1609         // Confirm the members data is correct.
1610         $members = $convmessages['members'];
1611         $this->assertEquals(2, count($members));
1612     }
1614     /**
1615      * Test retrieving conversation messages by providing a maximum timecreated value.
1616      */
1617     public function test_get_conversation_messages_time_to_only() {
1618         // Create some users.
1619         $user1 = self::getDataGenerator()->create_user();
1620         $user2 = self::getDataGenerator()->create_user();
1621         $user3 = self::getDataGenerator()->create_user();
1622         $user4 = self::getDataGenerator()->create_user();
1624         // Create group conversation.
1625         $conversation = \core_message\api::create_conversation(
1626             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1627             [$user1->id, $user2->id, $user3->id, $user4->id]
1628         );
1630         // The person doing the search.
1631         $this->setUser($user1);
1633         // Send some messages back and forth.
1634         $time = 1;
1635         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1636         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1637         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1638         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1640         // Retrieve the messages up until $time + 4, which should be all of them.
1641         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1642             0, $time + 4);
1644         // Confirm the conversation id is correct.
1645         $this->assertEquals($conversation->id, $convmessages['id']);
1647         // Confirm the message data is correct.
1648         $messages = $convmessages['messages'];
1649         $this->assertEquals(4, count($messages));
1651         $message1 = $messages[0];
1652         $message2 = $messages[1];
1653         $message3 = $messages[2];
1654         $message4 = $messages[3];
1656         $this->assertContains('Message 1', $message1->text);
1657         $this->assertContains('Message 2', $message2->text);
1658         $this->assertContains('Message 3', $message3->text);
1659         $this->assertContains('Message 4', $message4->text);
1661         // Confirm the members data is correct.
1662         $members = $convmessages['members'];
1663         $this->assertEquals(3, count($members));
1665         // Retrieve the messages up until $time + 2, which should be the first two.
1666         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1667             0, $time + 2);
1669         // Confirm the conversation id is correct.
1670         $this->assertEquals($conversation->id, $convmessages['id']);
1672         // Confirm the message data is correct.
1673         $messages = $convmessages['messages'];
1674         $this->assertEquals(2, count($messages));
1676         $message1 = $messages[0];
1677         $message2 = $messages[1];
1679         $this->assertContains('Message 1', $message1->text);
1680         $this->assertContains('Message 2', $message2->text);
1682         // Confirm the members data is correct.
1683         $members = $convmessages['members'];
1684         $this->assertEquals(2, count($members));
1685     }
1687     /**
1688      * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
1689      */
1690     public function test_get_conversation_messages_time_from_and_to() {
1691         // Create some users.
1692         $user1 = self::getDataGenerator()->create_user();
1693         $user2 = self::getDataGenerator()->create_user();
1694         $user3 = self::getDataGenerator()->create_user();
1695         $user4 = self::getDataGenerator()->create_user();
1697         // Create group conversation.
1698         $conversation = \core_message\api::create_conversation(
1699             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1700             [$user1->id, $user2->id, $user3->id, $user4->id]
1701         );
1703         // The person doing the search.
1704         $this->setUser($user1);
1706         // Send some messages back and forth.
1707         $time = 1;
1708         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1709         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1710         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1711         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1713         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1714         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1715             'timecreated ASC', $time + 2, $time + 3);
1717         // Confirm the conversation id is correct.
1718         $this->assertEquals($conversation->id, $convmessages['id']);
1720         // Confirm the message data is correct.
1721         $messages = $convmessages['messages'];
1722         $this->assertEquals(2, count($messages));
1724         $message1 = $messages[0];
1725         $message2 = $messages[1];
1727         $this->assertContains('Message 2', $message1->text);
1728         $this->assertContains('Message 3', $message2->text);
1730         // Confirm the members data is correct.
1731         $members = $convmessages['members'];
1732         $this->assertEquals(2, count($members));
1733     }
1736     /**
1737      * Test retrieving conversation messages by providing a limitfrom value.
1738      */
1739     public function test_get_conversation_messages_limitfrom_only() {
1740         // Create some users.
1741         $user1 = self::getDataGenerator()->create_user();
1742         $user2 = self::getDataGenerator()->create_user();
1743         $user3 = self::getDataGenerator()->create_user();
1744         $user4 = self::getDataGenerator()->create_user();
1746         // Create group conversation.
1747         $conversation = \core_message\api::create_conversation(
1748             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1749             [$user1->id, $user2->id, $user3->id, $user4->id]
1750         );
1752         // The person doing the search.
1753         $this->setUser($user1);
1755         // Send some messages back and forth.
1756         $time = 1;
1757         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1758         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1759         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1760         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1762         // Retrieve the messages from $time, which should be all of them.
1763         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
1765         // Confirm the conversation id is correct.
1766         $messages = $convmessages['messages'];
1767         $this->assertEquals($conversation->id, $convmessages['id']);
1769         // Confirm the message data is correct.
1770         $this->assertEquals(2, count($messages));
1772         $message1 = $messages[0];
1773         $message2 = $messages[1];
1775         $this->assertContains('Message 3', $message1->text);
1776         $this->assertContains('Message 4', $message2->text);
1778         // Confirm the members data is correct.
1779         $members = $convmessages['members'];
1780         $this->assertEquals(2, count($members));
1781     }
1783     /**
1784      * Test retrieving conversation messages by providing a limitnum value.
1785      */
1786     public function test_get_conversation_messages_limitnum() {
1787         // Create some users.
1788         $user1 = self::getDataGenerator()->create_user();
1789         $user2 = self::getDataGenerator()->create_user();
1790         $user3 = self::getDataGenerator()->create_user();
1791         $user4 = self::getDataGenerator()->create_user();
1793         // Create group conversation.
1794         $conversation = \core_message\api::create_conversation(
1795             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1796             [$user1->id, $user2->id, $user3->id, $user4->id]
1797         );
1799         // The person doing the search.
1800         $this->setUser($user1);
1802         // Send some messages back and forth.
1803         $time = 1;
1804         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1805         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1806         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1807         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1809         // Retrieve the messages from $time, which should be all of them.
1810         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
1812         // Confirm the conversation id is correct.
1813         $messages = $convmessages['messages'];
1814         $this->assertEquals($conversation->id, $convmessages['id']);
1816         // Confirm the message data is correct.
1817         $messages = $convmessages['messages'];
1818         $this->assertEquals(1, count($messages));
1820         $message1 = $messages[0];
1822         $this->assertContains('Message 3', $message1->text);
1824         // Confirm the members data is correct.
1825         $members = $convmessages['members'];
1826         $this->assertEquals(1, count($members));
1827     }
1829     /**
1830      * Tests retrieving most recent message.
1831      */
1832     public function test_get_most_recent_message() {
1833         // Create some users.
1834         $user1 = self::getDataGenerator()->create_user();
1835         $user2 = self::getDataGenerator()->create_user();
1837         // The person doing the search.
1838         $this->setUser($user1);
1840         // Send some messages back and forth.
1841         $time = 1;
1842         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1843         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1844         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1845         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1847         // Retrieve the most recent messages.
1848         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1849         $this->assertDebuggingCalledCount(3);
1851         // Check the results are correct.
1852         $this->assertEquals($user2->id, $message->useridfrom);
1853         $this->assertEquals($user1->id, $message->useridto);
1854         $this->assertContains('Word.', $message->text);
1855     }
1857     /**
1858      * Tests retrieving most recent conversation message.
1859      */
1860     public function test_get_most_recent_conversation_message() {
1861         // Create some users.
1862         $user1 = self::getDataGenerator()->create_user();
1863         $user2 = self::getDataGenerator()->create_user();
1864         $user3 = self::getDataGenerator()->create_user();
1866         // Create group conversation.
1867         $conversation = \core_message\api::create_conversation(
1868             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1869             [$user1->id, $user2->id, $user3->id]
1870         );
1872         // The person getting the most recent conversation message.
1873         $this->setUser($user1);
1875         // Send some messages back and forth.
1876         $time = 1;
1877         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1878         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1879         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1880         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
1882         // Retrieve the most recent messages.
1883         $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
1885         // Check the results are correct.
1886         $this->assertEquals($user2->id, $message->useridfrom);
1887         $this->assertContains('Word.', $message->text);
1888     }
1890     /**
1891      * Tests retrieving a user's profile.
1892      */
1893     public function test_get_profile() {
1894         // Create some users.
1895         $user1 = self::getDataGenerator()->create_user();
1897         $user2 = new stdClass();
1898         $user2->country = 'AU';
1899         $user2->city = 'Perth';
1900         $user2 = self::getDataGenerator()->create_user($user2);
1902         // The person doing the search.
1903         $this->setUser($user1);
1905         // Get the profile.
1906         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1908         $this->assertEquals($user2->id, $profile->userid);
1909         $this->assertEmpty($profile->email);
1910         $this->assertEmpty($profile->country);
1911         $this->assertEmpty($profile->city);
1912         $this->assertEquals(fullname($user2), $profile->fullname);
1913         $this->assertNull($profile->isonline);
1914         $this->assertFalse($profile->isblocked);
1915         $this->assertFalse($profile->iscontact);
1916     }
1918     /**
1919      * Tests retrieving a user's profile.
1920      */
1921     public function test_get_profile_as_admin() {
1922         // The person doing the search.
1923         $this->setAdminUser();
1925         // Create some users.
1926         $user1 = self::getDataGenerator()->create_user();
1928         $user2 = new stdClass();
1929         $user2->country = 'AU';
1930         $user2->city = 'Perth';
1931         $user2 = self::getDataGenerator()->create_user($user2);
1933         // Get the profile.
1934         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1936         $this->assertEquals($user2->id, $profile->userid);
1937         $this->assertEquals($user2->email, $profile->email);
1938         $this->assertEquals($user2->country, $profile->country);
1939         $this->assertEquals($user2->city, $profile->city);
1940         $this->assertEquals(fullname($user2), $profile->fullname);
1941         $this->assertFalse($profile->isonline);
1942         $this->assertFalse($profile->isblocked);
1943         $this->assertFalse($profile->iscontact);
1944     }
1946     /**
1947      * Tests checking if a user can mark all messages as read.
1948      */
1949     public function test_can_mark_all_messages_as_read() {
1950         // Set as the admin.
1951         $this->setAdminUser();
1953         // Create some users.
1954         $user1 = self::getDataGenerator()->create_user();
1955         $user2 = self::getDataGenerator()->create_user();
1956         $user3 = self::getDataGenerator()->create_user();
1958         // Send some messages back and forth.
1959         $time = 1;
1960         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1961         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1962         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1963         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1965         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1967         // The admin can do anything.
1968         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1970         // Set as the user 1.
1971         $this->setUser($user1);
1973         // The user can mark the messages as he is in the conversation.
1974         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1976         // User 1 can not mark the messages read for user 2.
1977         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
1979         // This user is not a part of the conversation.
1980         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
1981     }
1983     /**
1984      * Tests checking if a user can delete a conversation.
1985      */
1986     public function test_can_delete_conversation() {
1987         // Set as the admin.
1988         $this->setAdminUser();
1990         // Create some users.
1991         $user1 = self::getDataGenerator()->create_user();
1992         $user2 = self::getDataGenerator()->create_user();
1994         // Send some messages back and forth.
1995         $time = 1;
1996         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1997         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1998         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1999         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2001         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2003         // The admin can do anything.
2004         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2006         // Set as the user 1.
2007         $this->setUser($user1);
2009         // They can delete their own messages.
2010         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2012         // They can't delete someone elses.
2013         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
2014     }
2016     /**
2017      * Tests deleting a conversation.
2018      */
2019     public function test_delete_conversation() {
2020         global $DB;
2022         // Create some users.
2023         $user1 = self::getDataGenerator()->create_user();
2024         $user2 = self::getDataGenerator()->create_user();
2026         // The person doing the search.
2027         $this->setUser($user1);
2029         // Send some messages back and forth.
2030         $time = 1;
2031         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2032         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2033         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2034         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2036         // Delete the conversation as user 1.
2037         \core_message\api::delete_conversation($user1->id, $user2->id);
2038         $this->assertDebuggingCalled();
2040         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2041         $this->assertCount(4, $muas);
2042         // Sort by id.
2043         ksort($muas);
2045         $mua1 = array_shift($muas);
2046         $mua2 = array_shift($muas);
2047         $mua3 = array_shift($muas);
2048         $mua4 = array_shift($muas);
2050         $this->assertEquals($user1->id, $mua1->userid);
2051         $this->assertEquals($m1id, $mua1->messageid);
2052         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2054         $this->assertEquals($user1->id, $mua2->userid);
2055         $this->assertEquals($m2id, $mua2->messageid);
2056         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2058         $this->assertEquals($user1->id, $mua3->userid);
2059         $this->assertEquals($m3id, $mua3->messageid);
2060         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2062         $this->assertEquals($user1->id, $mua4->userid);
2063         $this->assertEquals($m4id, $mua4->messageid);
2064         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2065     }
2067     /**
2068      * Tests deleting a conversation by conversation id.
2069      */
2070     public function test_delete_conversation_by_id() {
2071         global $DB;
2073         // Create some users.
2074         $user1 = self::getDataGenerator()->create_user();
2075         $user2 = self::getDataGenerator()->create_user();
2077         // The person doing the search.
2078         $this->setUser($user1);
2080         // Send some messages back and forth.
2081         $time = 1;
2082         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2083         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2084         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2085         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2087         // Delete the conversation as user 1.
2088         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2089         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2091         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2092         $this->assertCount(4, $muas);
2093         // Sort by id.
2094         ksort($muas);
2096         $mua1 = array_shift($muas);
2097         $mua2 = array_shift($muas);
2098         $mua3 = array_shift($muas);
2099         $mua4 = array_shift($muas);
2101         $this->assertEquals($user1->id, $mua1->userid);
2102         $this->assertEquals($m1id, $mua1->messageid);
2103         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2105         $this->assertEquals($user1->id, $mua2->userid);
2106         $this->assertEquals($m2id, $mua2->messageid);
2107         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2109         $this->assertEquals($user1->id, $mua3->userid);
2110         $this->assertEquals($m3id, $mua3->messageid);
2111         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2113         $this->assertEquals($user1->id, $mua4->userid);
2114         $this->assertEquals($m4id, $mua4->messageid);
2115         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2116     }
2118     /**
2119      * Tests counting unread conversations.
2120      */
2121     public function test_count_unread_conversations() {
2122         $this->resetAfterTest(true);
2124         // Create some users.
2125         $user1 = self::getDataGenerator()->create_user();
2126         $user2 = self::getDataGenerator()->create_user();
2127         $user3 = self::getDataGenerator()->create_user();
2128         $user4 = self::getDataGenerator()->create_user();
2130         // The person wanting the conversation count.
2131         $this->setUser($user1);
2133         // Send some messages back and forth, have some different conversations with different users.
2134         $this->send_fake_message($user1, $user2, 'Yo!');
2135         $this->send_fake_message($user2, $user1, 'Sup mang?');
2136         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2137         $this->send_fake_message($user2, $user1, 'Word.');
2139         $this->send_fake_message($user1, $user3, 'Booyah');
2140         $this->send_fake_message($user3, $user1, 'Whaaat?');
2141         $this->send_fake_message($user1, $user3, 'Nothing.');
2142         $this->send_fake_message($user3, $user1, 'Cool.');
2144         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2145         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2146         $this->send_fake_message($user1, $user4, 'Dope.');
2148         // Check the amount for the current user.
2149         $this->assertEquals(3, core_message\api::count_unread_conversations());
2151         // Check the amount for the second user.
2152         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2153     }
2155     /**
2156      * Tests deleting a conversation.
2157      */
2158     public function test_get_all_message_preferences() {
2159         $user = self::getDataGenerator()->create_user();
2160         $this->setUser($user);
2162         // Set a couple of preferences to test.
2163         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2164         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2166         $processors = get_message_processors();
2167         $providers = message_get_providers_for_user($user->id);
2168         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2170         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2171         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2172     }
2174     /**
2175      * Tests the user can post a message.
2176      */
2177     public function test_can_post_message() {
2178         // Create some users.
2179         $user1 = self::getDataGenerator()->create_user();
2180         $user2 = self::getDataGenerator()->create_user();
2182         // Set as the first user.
2183         $this->setUser($user1);
2185         // With the default privacy setting, users can't message them.
2186         $this->assertFalse(\core_message\api::can_post_message($user2));
2188         // Enrol users to the same course.
2189         $course = $this->getDataGenerator()->create_course();
2190         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2191         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2192         // After enrolling users to the course, they should be able to message them with the default privacy setting.
2193         $this->assertTrue(\core_message\api::can_post_message($user2));
2194     }
2196     /**
2197      * Tests the user can't post a message without proper capability.
2198      */
2199     public function test_can_post_message_without_sendmessage_cap() {
2200         global $DB;
2202         // Create some users.
2203         $user1 = self::getDataGenerator()->create_user();
2204         $user2 = self::getDataGenerator()->create_user();
2206         // Set as the user 1.
2207         $this->setUser($user1);
2209         // Remove the capability to send a message.
2210         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
2211         unassign_capability('moodle/site:sendmessage', $roleids['user'],
2212             context_system::instance());
2214         // Check that we can not post a message without the capability.
2215         $this->assertFalse(\core_message\api::can_post_message($user2));
2216     }
2218     /**
2219      * Tests the user can post a message when they are contact.
2220      */
2221     public function test_can_post_message_when_contact() {
2222         // Create some users.
2223         $user1 = self::getDataGenerator()->create_user();
2224         $user2 = self::getDataGenerator()->create_user();
2226         // Set as the first user.
2227         $this->setUser($user1);
2229         // Check that we can not send user2 a message.
2230         $this->assertFalse(\core_message\api::can_post_message($user2));
2232         // Add users as contacts.
2233         \core_message\api::add_contact($user1->id, $user2->id);
2235         // Check that the return result is now true.
2236         $this->assertTrue(\core_message\api::can_post_message($user2));
2237     }
2239     /**
2240      * Tests the user can't post a message if they are not a contact and the user
2241      * has requested messages only from contacts.
2242      */
2243     public function test_can_post_message_when_not_contact() {
2244         // Create some users.
2245         $user1 = self::getDataGenerator()->create_user();
2246         $user2 = self::getDataGenerator()->create_user();
2248         // Set as the first user.
2249         $this->setUser($user1);
2251         // Set the second user's preference to not receive messages from non-contacts.
2252         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2254         // Check that we can not send user 2 a message.
2255         $this->assertFalse(\core_message\api::can_post_message($user2));
2256     }
2258     /**
2259      * Tests the user can't post a message if they are blocked.
2260      */
2261     public function test_can_post_message_when_blocked() {
2262         // Create some users.
2263         $user1 = self::getDataGenerator()->create_user();
2264         $user2 = self::getDataGenerator()->create_user();
2266         // Set the user.
2267         $this->setUser($user1);
2269         // Block the second user.
2270         \core_message\api::block_user($user1->id, $user2->id);
2272         // Check that the second user can no longer send the first user a message.
2273         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
2274     }
2276     /**
2277      * Tests the user can post a message when site-wide messaging setting is enabled,
2278      * even if they are not a contact and are not members of the same course.
2279      */
2280     public function test_can_post_message_site_messaging_setting() {
2281         // Create some users.
2282         $user1 = self::getDataGenerator()->create_user();
2283         $user2 = self::getDataGenerator()->create_user();
2285         // Set as the first user.
2286         $this->setUser($user1);
2288         // By default, user only can be messaged by contacts and members of any of his/her courses.
2289         $this->assertFalse(\core_message\api::can_post_message($user2));
2291         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2292         set_config('messagingallusers', true);
2294         // Set the second user's preference to receive messages from everybody.
2295         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
2297         // Check that we can send user2 a message.
2298         $this->assertTrue(\core_message\api::can_post_message($user2));
2300         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
2301         // and members sharing a course with her.
2302         set_config('messagingallusers', false);
2304         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
2305         $this->assertFalse(\core_message\api::can_post_message($user2));
2307         // Enrol users to the same course.
2308         $course = $this->getDataGenerator()->create_course();
2309         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2310         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2311         // Check that we can send user2 a message because they are sharing a course.
2312         $this->assertTrue(\core_message\api::can_post_message($user2));
2314         // Set the second user's preference to receive messages only from contacts.
2315         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2316         // Check that now the user2 can't be contacted because user1 is not their contact.
2317         $this->assertFalse(\core_message\api::can_post_message($user2));
2319         // Make contacts user1 and user2.
2320         \core_message\api::add_contact($user2->id, $user1->id);
2321         // Check that we can send user2 a message because they are contacts.
2322         $this->assertTrue(\core_message\api::can_post_message($user2));
2323     }
2325     /**
2326      * Tests the user with the messageanyuser capability can post a message.
2327      */
2328     public function test_can_post_message_with_messageanyuser_cap() {
2329         global $DB;
2331         // Create some users.
2332         $teacher1 = self::getDataGenerator()->create_user();
2333         $student1 = self::getDataGenerator()->create_user();
2334         $student2 = self::getDataGenerator()->create_user();
2336         // Create users not enrolled in any course.
2337         $user1 = self::getDataGenerator()->create_user();
2339         // Create a course.
2340         $course1 = $this->getDataGenerator()->create_course();
2342         // Enrol the users in the course.
2343         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
2344         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
2345         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
2347         // Set some student preferences to not receive messages from non-contacts.
2348         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
2350         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
2351         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
2352         // Check that the teacher can't contact user1 because it's not his teacher.
2353         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
2355         // Remove the messageanyuser capability from the course1 for teachers.
2356         $coursecontext = context_course::instance($course1->id);
2357         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
2358         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
2359         $coursecontext->mark_dirty();
2361         // Check that we can't send user1 a message because they are not contacts.
2362         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
2363         // However, teacher can message student2 because they are sharing a course.
2364         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
2365     }
2367     /**
2368      * Tests get_user_privacy_messaging_preference method.
2369      */
2370     public function test_get_user_privacy_messaging_preference() {
2371         // Create some users.
2372         $user1 = self::getDataGenerator()->create_user();
2373         $user2 = self::getDataGenerator()->create_user();
2374         $user3 = self::getDataGenerator()->create_user();
2376         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2377         set_config('messagingallusers', true);
2379         // Set some user preferences.
2380         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
2381         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2383         // Check the returned value for each user.
2384         $this->assertEquals(
2385             \core_message\api::MESSAGE_PRIVACY_SITE,
2386             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2387         );
2388         $this->assertEquals(
2389             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2390             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2391         );
2392         $this->assertEquals(
2393             \core_message\api::MESSAGE_PRIVACY_SITE,
2394             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2395         );
2397         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
2398         set_config('messagingallusers', false);
2400         // Check the returned value for each user.
2401         $this->assertEquals(
2402             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2403             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2404         );
2405         $this->assertEquals(
2406             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2407             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2408         );
2409         $this->assertEquals(
2410             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2411             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2412         );
2413     }
2415     /**
2416      * Tests that when blocking messages from non-contacts is enabled that
2417      * non-contacts trying to send a message return false.
2418      */
2419     public function test_is_user_non_contact_blocked() {
2420         // Create some users.
2421         $user1 = self::getDataGenerator()->create_user();
2422         $user2 = self::getDataGenerator()->create_user();
2424         // Set as the first user.
2425         $this->setUser($user1);
2427         // By default, user only can be messaged by contacts and members of any of his/her courses.
2428         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2429         $this->assertDebuggingCalled();
2431         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
2432         // messages from everybody.
2433         set_config('messagingallusers', true);
2434         // Check that the return result is now false because any site user can contact him/her.
2435         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2436         $this->assertDebuggingCalled();
2438         // Set the second user's preference to not receive messages from non-contacts.
2439         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2440         // Check that the return result is still true (because is even more restricted).
2441         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2442         $this->assertDebuggingCalled();
2444         // Add the first user as a contact for the second user.
2445         \core_message\api::add_contact($user2->id, $user1->id);
2447         // Check that the return result is now false.
2448         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2449         $this->assertDebuggingCalled();
2451         // Set the second user's preference to receive messages from course members.
2452         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
2453         // Check that the return result is still false (because $user1 is still his/her contact).
2454         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2455         $this->assertDebuggingCalled();
2456     }
2458     /**
2459      * Tests that we return true when a user is blocked, or false
2460      * if they are not blocked.
2461      */
2462     public function test_is_user_blocked() {
2463         // Create some users.
2464         $user1 = self::getDataGenerator()->create_user();
2465         $user2 = self::getDataGenerator()->create_user();
2467         // Set the user.
2468         $this->setUser($user1);
2470         // User shouldn't be blocked.
2471         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2472         $this->assertDebuggingCalled();
2474         // Block the user.
2475         \core_message\api::block_user($user1->id, $user2->id);
2477         // User should be blocked.
2478         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
2479         $this->assertDebuggingCalled();
2481         // Unblock the user.
2482         \core_message\api::unblock_user($user1->id, $user2->id);
2483         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2484         $this->assertDebuggingCalled();
2485     }
2487     /**
2488      * Tests that the admin is not blocked even if someone has chosen to block them.
2489      */
2490     public function test_is_user_blocked_as_admin() {
2491         // Create a user.
2492         $user1 = self::getDataGenerator()->create_user();
2494         // Set the user.
2495         $this->setUser($user1);
2497         // Block the admin user.
2498         \core_message\api::block_user($user1->id, 2);
2500         // Now change to the admin user.
2501         $this->setAdminUser();
2503         // As the admin you should still be able to send messages to the user.
2504         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
2505         $this->assertDebuggingCalled();
2506     }
2508     /*
2509      * Tes get_message_processor api.
2510      */
2511     public function test_get_message_processor() {
2512         $processors = get_message_processors(true);
2513         if (empty($processors)) {
2514             $this->markTestSkipped("No message processors found");
2515         }
2517         $name = key($processors);
2518         $processor = current($processors);
2519         $testprocessor = \core_message\api::get_message_processor($name);
2520         $this->assertEquals($processor->name, $testprocessor->name);
2521         $this->assertEquals($processor->enabled, $testprocessor->enabled);
2522         $this->assertEquals($processor->available, $testprocessor->available);
2523         $this->assertEquals($processor->configured, $testprocessor->configured);
2525         // Disable processor and test.
2526         \core_message\api::update_processor_status($testprocessor, 0);
2527         $testprocessor = \core_message\api::get_message_processor($name, true);
2528         $this->assertEmpty($testprocessor);
2529         $testprocessor = \core_message\api::get_message_processor($name);
2530         $this->assertEquals($processor->name, $testprocessor->name);
2531         $this->assertEquals(0, $testprocessor->enabled);
2533         // Enable again and test.
2534         \core_message\api::update_processor_status($testprocessor, 1);
2535         $testprocessor = \core_message\api::get_message_processor($name, true);
2536         $this->assertEquals($processor->name, $testprocessor->name);
2537         $this->assertEquals(1, $testprocessor->enabled);
2538         $testprocessor = \core_message\api::get_message_processor($name);
2539         $this->assertEquals($processor->name, $testprocessor->name);
2540         $this->assertEquals(1, $testprocessor->enabled);
2541     }
2543     /**
2544      * Test method update_processor_status.
2545      */
2546     public function test_update_processor_status() {
2547         $processors = get_message_processors();
2548         if (empty($processors)) {
2549             $this->markTestSkipped("No message processors found");
2550         }
2551         $name = key($processors);
2552         $testprocessor = current($processors);
2554         // Enable.
2555         \core_message\api::update_processor_status($testprocessor, 1);
2556         $testprocessor = \core_message\api::get_message_processor($name);
2557         $this->assertEquals(1, $testprocessor->enabled);
2559         // Disable.
2560         \core_message\api::update_processor_status($testprocessor, 0);
2561         $testprocessor = \core_message\api::get_message_processor($name);
2562         $this->assertEquals(0, $testprocessor->enabled);
2564         // Enable again.
2565         \core_message\api::update_processor_status($testprocessor, 1);
2566         $testprocessor = \core_message\api::get_message_processor($name);
2567         $this->assertEquals(1, $testprocessor->enabled);
2568     }
2570     /**
2571      * Test method is_user_enabled.
2572      */
2573     public function is_user_enabled() {
2574         $processors = get_message_processors();
2575         if (empty($processors)) {
2576             $this->markTestSkipped("No message processors found");
2577         }
2578         $name = key($processors);
2579         $testprocessor = current($processors);
2581         // Enable.
2582         \core_message\api::update_processor_status($testprocessor, 1);
2583         $status = \core_message\api::is_processor_enabled($name);
2584         $this->assertEquals(1, $status);
2586         // Disable.
2587         \core_message\api::update_processor_status($testprocessor, 0);
2588         $status = \core_message\api::is_processor_enabled($name);
2589         $this->assertEquals(0, $status);
2591         // Enable again.
2592         \core_message\api::update_processor_status($testprocessor, 1);
2593         $status = \core_message\api::is_processor_enabled($name);
2594         $this->assertEquals(1, $status);
2595     }
2597     /**
2598      * Test retrieving messages by providing a minimum timecreated value.
2599      */
2600     public function test_get_messages_time_from_only() {
2601         // Create some users.
2602         $user1 = self::getDataGenerator()->create_user();
2603         $user2 = self::getDataGenerator()->create_user();
2605         // The person doing the search.
2606         $this->setUser($user1);
2608         // Send some messages back and forth.
2609         $time = 1;
2610         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2611         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2612         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2613         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2615         // Retrieve the messages from $time, which should be all of them.
2616         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
2617         $this->assertDebuggingCalledCount(3);
2619         // Confirm the message data is correct.
2620         $this->assertEquals(4, count($messages));
2622         $message1 = $messages[0];
2623         $message2 = $messages[1];
2624         $message3 = $messages[2];
2625         $message4 = $messages[3];
2627         $this->assertContains('Message 1', $message1->text);
2628         $this->assertContains('Message 2', $message2->text);
2629         $this->assertContains('Message 3', $message3->text);
2630         $this->assertContains('Message 4', $message4->text);
2632         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2633         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
2634         $this->assertDebuggingCalledCount(3);
2636         // Confirm the message data is correct.
2637         $this->assertEquals(2, count($messages));
2639         $message1 = $messages[0];
2640         $message2 = $messages[1];
2642         $this->assertContains('Message 3', $message1->text);
2643         $this->assertContains('Message 4', $message2->text);
2644     }
2646     /**
2647      * Test retrieving messages by providing a maximum timecreated value.
2648      */
2649     public function test_get_messages_time_to_only() {
2650         // Create some users.
2651         $user1 = self::getDataGenerator()->create_user();
2652         $user2 = self::getDataGenerator()->create_user();
2654         // The person doing the search.
2655         $this->setUser($user1);
2657         // Send some messages back and forth.
2658         $time = 1;
2659         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2660         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2661         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2662         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2664         // Retrieve the messages up until $time + 4, which should be all of them.
2665         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
2666         $this->assertDebuggingCalledCount(3);
2668         // Confirm the message data is correct.
2669         $this->assertEquals(4, count($messages));
2671         $message1 = $messages[0];
2672         $message2 = $messages[1];
2673         $message3 = $messages[2];
2674         $message4 = $messages[3];
2676         $this->assertContains('Message 1', $message1->text);
2677         $this->assertContains('Message 2', $message2->text);
2678         $this->assertContains('Message 3', $message3->text);
2679         $this->assertContains('Message 4', $message4->text);
2681         // Retrieve the messages up until $time + 2, which should be the first two.
2682         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
2683         $this->assertDebuggingCalledCount(3);
2685         // Confirm the message data is correct.
2686         $this->assertEquals(2, count($messages));
2688         $message1 = $messages[0];
2689         $message2 = $messages[1];
2691         $this->assertContains('Message 1', $message1->text);
2692         $this->assertContains('Message 2', $message2->text);
2693     }
2695     /**
2696      * Test retrieving messages by providing a minimum and maximum timecreated value.
2697      */
2698     public function test_get_messages_time_from_and_to() {
2699         // Create some users.
2700         $user1 = self::getDataGenerator()->create_user();
2701         $user2 = self::getDataGenerator()->create_user();
2703         // The person doing the search.
2704         $this->setUser($user1);
2706         // Send some messages back and forth.
2707         $time = 1;
2708         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2709         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2710         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2711         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2713         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2714         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
2715         $this->assertDebuggingCalledCount(3);
2717         // Confirm the message data is correct.
2718         $this->assertEquals(2, count($messages));
2720         $message1 = $messages[0];
2721         $message2 = $messages[1];
2723         $this->assertContains('Message 2', $message1->text);
2724         $this->assertContains('Message 3', $message2->text);
2725     }
2727     /**
2728      * Test returning blocked users.
2729      */
2730     public function test_get_blocked_users() {
2731         global $USER;
2733         // Set this user as the admin.
2734         $this->setAdminUser();
2736         // Create a user to add to the admin's contact list.
2737         $user1 = $this->getDataGenerator()->create_user();
2738         $user2 = $this->getDataGenerator()->create_user();
2740         // Add users to the admin's contact list.
2741         \core_message\api::block_user($USER->id, $user2->id);
2743         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2745         // Block other user.
2746         \core_message\api::block_user($USER->id, $user1->id);
2747         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
2749         // Test deleting users.
2750         delete_user($user1);
2751         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2752     }
2754     /**
2755      * Test returning contacts with unread message count.
2756      */
2757     public function test_get_contacts_with_unread_message_count() {
2758         global $DB;
2760         $user1 = self::getDataGenerator()->create_user();
2761         $user2 = self::getDataGenerator()->create_user();
2762         $user3 = self::getDataGenerator()->create_user();
2763         $user4 = self::getDataGenerator()->create_user();
2765         // Add the users to each of their contacts.
2766         \core_message\api::add_contact($user1->id, $user2->id);
2767         \core_message\api::add_contact($user2->id, $user3->id);
2769         $this->send_fake_message($user1, $user2);
2770         $this->send_fake_message($user1, $user2);
2771         $this->send_fake_message($user1, $user2);
2772         $message4id = $this->send_fake_message($user1, $user2);
2774         $this->send_fake_message($user3, $user2);
2775         $message6id = $this->send_fake_message($user3, $user2);
2776         $this->send_fake_message($user3, $user2);
2777         $this->send_fake_message($user3, $user2);
2778         $this->send_fake_message($user3, $user2);
2780         // Send a message that should never be included as the user is not a contact.
2781         $this->send_fake_message($user4, $user2);
2783         // Get the contacts and the unread message count.
2784         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2786         // Confirm the size is correct.
2787         $this->assertCount(2, $messages);
2788         ksort($messages);
2790         $messageinfo1 = array_shift($messages);
2791         $messageinfo2 = array_shift($messages);
2793         $this->assertEquals($user1->id, $messageinfo1->id);
2794         $this->assertEquals(4, $messageinfo1->messagecount);
2795         $this->assertEquals($user3->id, $messageinfo2->id);
2796         $this->assertEquals(5, $messageinfo2->messagecount);
2798         // Mark some of the messages as read.
2799         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2800         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2801         \core_message\api::mark_message_as_read($user2->id, $m4);
2802         \core_message\api::mark_message_as_read($user2->id, $m6);
2804         // Get the contacts and the unread message count.
2805         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2807         // Confirm the size is correct.
2808         $this->assertCount(2, $messages);
2809         ksort($messages);
2811         // Confirm read messages are not included.
2812         $messageinfo1 = array_shift($messages);
2813         $messageinfo2 = array_shift($messages);
2814         $this->assertEquals($user1->id, $messageinfo1->id);
2815         $this->assertEquals(3, $messageinfo1->messagecount);
2816         $this->assertEquals($user3->id, $messageinfo2->id);
2817         $this->assertEquals(4, $messageinfo2->messagecount);
2819         // Now, let's populate the database with messages from user2 to user 1.
2820         $this->send_fake_message($user2, $user1);
2821         $this->send_fake_message($user2, $user1);
2822         $messageid = $this->send_fake_message($user2, $user1);
2824         // Send a message that should never be included as the user is not a contact.
2825         $this->send_fake_message($user4, $user1);
2827         // Get the contacts and the unread message count.
2828         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2830         // Confirm the size is correct.
2831         $this->assertCount(1, $messages);
2832         $messageinfo1 = array_shift($messages);
2833         $this->assertEquals($user2->id, $messageinfo1->id);
2834         $this->assertEquals(3, $messageinfo1->messagecount);
2836         // Mark the last message as read.
2837         $m = $DB->get_record('messages', ['id' => $messageid]);
2838         \core_message\api::mark_message_as_read($user1->id, $m);
2840         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2842         // Confirm the size is correct.
2843         $this->assertCount(1, $messages);
2845         // Confirm read messages are not included.
2846         $messageinfo1 = array_shift($messages);
2847         $this->assertEquals($user2->id, $messageinfo1->id);
2848         $this->assertEquals(2, $messageinfo1->messagecount);
2849     }
2851     /**
2852      * Test returning contacts with unread message count when there are no messages.
2853      */
2854     public function test_get_contacts_with_unread_message_count_no_messages() {
2855         $user1 = self::getDataGenerator()->create_user();
2856         $user2 = self::getDataGenerator()->create_user();
2858         // Add the users to each of their contacts.
2859         \core_message\api::add_contact($user2->id, $user1->id);
2861         // Check we get the correct message count.
2862         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2864         // Confirm the size is correct.
2865         $this->assertCount(1, $messages);
2867         $messageinfo = array_shift($messages);
2869         $this->assertEquals($user1->id, $messageinfo->id);
2870         $this->assertEquals(0, $messageinfo->messagecount);
2871     }
2873     /**
2874      * Test returning non-contacts with unread message count.
2875      */
2876     public function test_get_non_contacts_with_unread_message_count() {
2877         global $DB;
2879         $user1 = self::getDataGenerator()->create_user();
2880         $user2 = self::getDataGenerator()->create_user();
2881         $user3 = self::getDataGenerator()->create_user();
2882         $user4 = self::getDataGenerator()->create_user();
2884         // Add a user to the contact list of the users we are testing this function with.
2885         \core_message\api::add_contact($user1->id, $user4->id);
2886         \core_message\api::add_contact($user2->id, $user4->id);
2888         $this->send_fake_message($user1, $user2);
2889         $this->send_fake_message($user1, $user2);
2890         $this->send_fake_message($user1, $user2);
2891         $message4id = $this->send_fake_message($user1, $user2);
2893         $this->send_fake_message($user3, $user2);
2894         $message6id = $this->send_fake_message($user3, $user2);
2895         $this->send_fake_message($user3, $user2);
2896         $this->send_fake_message($user3, $user2);
2897         $this->send_fake_message($user3, $user2);
2899         // Send a message that should never be included as the user is a contact.
2900         $this->send_fake_message($user4, $user2);
2902         // Get the non-contacts and the unread message count.
2903         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2905         // Check we get the correct message count.
2906         ksort($messages);
2907         $this->assertCount(2, $messages);
2908         $messageinfo1 = array_shift($messages);
2909         $messageinfo2 = array_shift($messages);
2910         $this->assertEquals($user1->id, $messageinfo1->id);
2911         $this->assertEquals(4, $messageinfo1->messagecount);
2912         $this->assertEquals($user3->id, $messageinfo2->id);
2913         $this->assertEquals(5, $messageinfo2->messagecount);
2915         // Mark some of the messages as read.
2916         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2917         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2918         \core_message\api::mark_message_as_read($user2->id, $m4);
2919         \core_message\api::mark_message_as_read($user2->id, $m6);
2921         // Get the non-contacts and the unread message count.
2922         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2924         // Check the marked message is not returned in the message count.
2925         ksort($messages);
2926         $this->assertCount(2, $messages);
2927         $messageinfo1 = array_shift($messages);
2928         $messageinfo2 = array_shift($messages);
2929         $this->assertEquals($user1->id, $messageinfo1->id);
2930         $this->assertEquals(3, $messageinfo1->messagecount);
2931         $this->assertEquals($user3->id, $messageinfo2->id);
2932         $this->assertEquals(4, $messageinfo2->messagecount);
2934         // Now, let's populate the database with messages from user2 to user 1.
2935         $this->send_fake_message($user2, $user1);
2936         $this->send_fake_message($user2, $user1);
2937         $messageid = $this->send_fake_message($user2, $user1);
2939         // Send a message that should never be included as the user is a contact.
2940         $this->send_fake_message($user4, $user1);
2942         // Get the non-contacts and the unread message count.
2943         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2945         // Confirm the size is correct.
2946         $this->assertCount(1, $messages);
2947         $messageinfo1 = array_shift($messages);
2948         $this->assertEquals($user2->id, $messageinfo1->id);
2949         $this->assertEquals(3, $messageinfo1->messagecount);
2951         // Mark the last message as read.
2952         $m = $DB->get_record('messages', ['id' => $messageid]);
2953         \core_message\api::mark_message_as_read($user1->id, $m);
2955         // Get the non-contacts and the unread message count.
2956         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2958         // Check the marked message is not returned in the message count.
2959         $this->assertCount(1, $messages);
2960         $messageinfo1 = array_shift($messages);
2961         $this->assertEquals($user2->id, $messageinfo1->id);
2962         $this->assertEquals(2, $messageinfo1->messagecount);
2963     }
2965     /**
2966      * Test marking a message as read.
2967      */
2968     public function test_mark_message_as_read() {
2969         global $DB;
2971         $user1 = self::getDataGenerator()->create_user();
2972         $user2 = self::getDataGenerator()->create_user();
2974         $this->send_fake_message($user1, $user2);
2975         $m2id = $this->send_fake_message($user1, $user2);
2976         $this->send_fake_message($user2, $user1);
2977         $m4id = $this->send_fake_message($user2, $user1);
2979         $m2 = $DB->get_record('messages', ['id' => $m2id]);
2980         $m4 = $DB->get_record('messages', ['id' => $m4id]);
2981         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
2982         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
2984         // Confirm there are two user actions.
2985         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
2986         $this->assertEquals(2, count($muas));
2988         // Confirm they are correct.
2989         $mua1 = array_shift($muas);
2990         $mua2 = array_shift($muas);
2992         // Confirm first action.
2993         $this->assertEquals($user2->id, $mua1->userid);
2994         $this->assertEquals($m2id, $mua1->messageid);
2995         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
2996         $this->assertEquals(11, $mua1->timecreated);
2998         // Confirm second action.
2999         $this->assertEquals($user1->id, $mua2->userid);
3000         $this->assertEquals($m4id, $mua2->messageid);
3001         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
3002         $this->assertEquals(12, $mua2->timecreated);
3003     }
3005     /**
3006      * Test marking a notification as read.
3007      */
3008     public function test_mark_notification_as_read() {
3009         global $DB;
3011         $user1 = self::getDataGenerator()->create_user();
3012         $user2 = self::getDataGenerator()->create_user();
3014         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
3015         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
3016         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
3017         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
3019         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3020         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3022         \core_message\api::mark_notification_as_read($n2, 11);
3023         \core_message\api::mark_notification_as_read($n4, 12);
3025         // Retrieve the notifications.
3026         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3027         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3029         // Confirm they have been marked as read.
3030         $this->assertEquals(11, $n2->timeread);
3031         $this->assertEquals(12, $n4->timeread);
3032     }
3034     /**
3035      * Test a conversation is not returned if there is none.
3036      */
3037     public function test_get_conversation_between_users_no_conversation() {
3038         $user1 = self::getDataGenerator()->create_user();
3039         $user2 = self::getDataGenerator()->create_user();
3041         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
3042     }
3044     /**
3045      * Test we can return a conversation that exists between users.
3046      */
3047     public function test_get_conversation_between_users_with_existing_conversation() {
3048         $user1 = self::getDataGenerator()->create_user();
3049         $user2 = self::getDataGenerator()->create_user();
3051         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
3052         $this->assertDebuggingCalled();
3054         $this->assertEquals($conversationid,
3055             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
3056     }
3058     /**
3059      * Test count_conversation_members for non existing conversation.
3060      */
3061     public function test_count_conversation_members_no_existing_conversation() {
3062         $this->assertEquals(0,
3063             \core_message\api::count_conversation_members(0));
3064     }
3066     /**
3067      * Test count_conversation_members for existing conversation.
3068      */
3069     public function test_count_conversation_members_existing_conversation() {
3070         $user1 = self::getDataGenerator()->create_user();
3071         $user2 = self::getDataGenerator()->create_user();
3073         $conversation = \core_message\api::create_conversation(
3074             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3075             [
3076                 $user1->id,
3077                 $user2->id
3078             ]
3079         );
3080         $conversationid = $conversation->id;
3082         $this->assertEquals(2,
3083             \core_message\api::count_conversation_members($conversationid));
3084     }
3086     /**
3087      * Test add_members_to_conversation for an individual conversation.
3088      */
3089     public function test_add_members_to_individual_conversation() {
3090         $user1 = self::getDataGenerator()->create_user();
3091         $user2 = self::getDataGenerator()->create_user();
3092         $user3 = self::getDataGenerator()->create_user();
3094         $conversation = \core_message\api::create_conversation(
3095             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3096             [
3097                 $user1->id,
3098                 $user2->id
3099             ]
3100         );
3101         $conversationid = $conversation->id;
3103         $this->expectException('moodle_exception');
3104         \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
3105     }
3107     /**
3108      * Test add_members_to_conversation for existing conversation.
3109      */
3110     public function test_add_members_to_existing_conversation() {
3111         $user1 = self::getDataGenerator()->create_user();
3112         $user2 = self::getDataGenerator()->create_user();
3113         $user3 = self::getDataGenerator()->create_user();
3115         $conversation = \core_message\api::create_conversation(
3116             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3117             [
3118                 $user1->id,
3119                 $user2->id
3120             ]
3121         );
3122         $conversationid = $conversation->id;
3124         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3125         $this->assertEquals(3,
3126             \core_message\api::count_conversation_members($conversationid));
3127     }
3129     /**
3130      * Test add_members_to_conversation for non existing conversation.
3131      */
3132     public function test_add_members_to_no_existing_conversation() {
3133         $user1 = self::getDataGenerator()->create_user();
3135         // Throw dml_missing_record_exception for non existing conversation.
3136         $this->expectException('dml_missing_record_exception');
3137         \core_message\api::add_members_to_conversation([$user1->id], 0);
3138     }
3140     /**
3141      * Test add_member_to_conversation for non existing user.
3142      */
3143     public function test_add_members_to_no_existing_user() {
3144         $user1 = self::getDataGenerator()->create_user();
3145         $user2 = self::getDataGenerator()->create_user();
3147         $conversation = \core_message\api::create_conversation(
3148             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3149             [
3150                 $user1->id,
3151                 $user2->id
3152             ]
3153         );
3154         $conversationid = $conversation->id;
3156         // Don't throw an error for non existing user, but don't add it as a member.
3157         $this->assertNull(\core_message\api::add_members_to_conversation([0], $conversationid));
3158         $this->assertEquals(2,
3159             \core_message\api::count_conversation_members($conversationid));
3160     }
3162     /**
3163      * Test add_members_to_conversation for current conversation member.
3164      */
3165     public function test_add_members_to_current_conversation_member() {
3166         $user1 = self::getDataGenerator()->create_user();
3167         $user2 = self::getDataGenerator()->create_user();
3169         $conversation = \core_message\api::create_conversation(
3170             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3171             [
3172                 $user1->id,
3173                 $user2->id
3174             ]
3175         );
3176         $conversationid = $conversation->id;
3178         // Don't add as a member a user that is already conversation member.
3179         $this->assertNull(\core_message\api::add_members_to_conversation([$user1->id], $conversationid));
3180         $this->assertEquals(2,
3181             \core_message\api::count_conversation_members($conversationid));
3182     }
3184     /**
3185      * Test add_members_to_conversation for multiple users.
3186      */
3187     public function test_add_members_for_multiple_users() {
3188         $user1 = self::getDataGenerator()->create_user();
3189         $user2 = self::getDataGenerator()->create_user();
3190         $user3 = self::getDataGenerator()->create_user();
3191         $user4 = self::getDataGenerator()->create_user();
3193         $conversation = \core_message\api::create_conversation(
3194             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3195             [
3196                 $user1->id,
3197                 $user2->id
3198             ]
3199         );
3200         $conversationid = $conversation->id;
3202         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3203         $this->assertEquals(4,
3204             \core_message\api::count_conversation_members($conversationid));
3205     }
3207     /**
3208      * Test add_members_to_conversation for multiple users, included non existing and current conversation members
3209      */
3210     public function test_add_members_for_multiple_not_valid_users() {
3211         $user1 = self::getDataGenerator()->create_user();
3212         $user2 = self::getDataGenerator()->create_user();
3213         $user3 = self::getDataGenerator()->create_user();
3215         $conversation = \core_message\api::create_conversation(
3216             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3217             [
3218                 $user1->id,
3219                 $user2->id
3220             ]
3221         );
3222         $conversationid = $conversation->id;
3224         // Don't throw errors, but don't add as members users don't exist or are already conversation members.
3225         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
3226         $this->assertEquals(3,
3227             \core_message\api::count_conversation_members($conversationid));
3228     }
3230     /**
3231      * Test remove_members_from_conversation for individual conversation.
3232      */
3233     public function test_remove_members_from_individual_conversation() {
3234         $user1 = self::getDataGenerator()->create_user();
3235         $user2 = self::getDataGenerator()->create_user();
3237         $conversation = \core_message\api::create_conversation(
3238             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3239             [
3240                 $user1->id,
3241                 $user2->id
3242             ]
3243         );
3244         $conversationid = $conversation->id;
3246         $this->expectException('moodle_exception');
3247         \core_message\api::remove_members_from_conversation([$user1->id], $conversationid);
3248     }
3250     /**
3251      * Test remove_members_from_conversation for existing conversation.
3252      */
3253     public function test_remove_members_from_existing_conversation() {
3254         $user1 = self::getDataGenerator()->create_user();
3255         $user2 = self::getDataGenerator()->create_user();
3257         $conversation = \core_message\api::create_conversation(
3258             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3259             [
3260                 $user1->id,
3261                 $user2->id
3262             ]
3263         );
3264         $conversationid = $conversation->id;
3266         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id], $conversationid));
3267         $this->assertEquals(1,
3268             \core_message\api::count_conversation_members($conversationid));
3269     }
3271     /**
3272      * Test remove_members_from_conversation for non existing conversation.
3273      */
3274     public function test_remove_members_from_no_existing_conversation() {
3275         $user1 = self::getDataGenerator()->create_user();
3277         // Throw dml_missing_record_exception for non existing conversation.
3278         $this->expectException('dml_missing_record_exception');
3279         \core_message\api::remove_members_from_conversation([$user1->id], 0);
3280     }
3282     /**
3283      * Test remove_members_from_conversation for non existing user.
3284      */
3285     public function test_remove_members_for_no_existing_user() {
3286         $user1 = self::getDataGenerator()->create_user();
3287         $user2 = self::getDataGenerator()->create_user();
3289         $conversation = \core_message\api::create_conversation(
3290             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3291             [
3292                 $user1->id,
3293                 $user2->id
3294             ]
3295         );
3296         $conversationid = $conversation->id;
3298         $this->assertNull(\core_message\api::remove_members_from_conversation([0], $conversationid));
3299         $this->assertEquals(2,
3300             \core_message\api::count_conversation_members($conversationid));
3301     }
3303     /**
3304      * Test remove_members_from_conversation for multiple users.
3305      */
3306     public function test_remove_members_for_multiple_users() {
3307         $user1 = self::getDataGenerator()->create_user();
3308         $user2 = self::getDataGenerator()->create_user();
3309         $user3 = self::getDataGenerator()->create_user();
3310         $user4 = self::getDataGenerator()->create_user();
3312         $conversation = \core_message\api::create_conversation(
3313             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3314             [
3315                 $user1->id,
3316                 $user2->id
3317             ]
3318         );
3319         $conversationid = $conversation->id;
3321         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3322         $this->assertNull(\core_message\api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
3323         $this->assertEquals(2,
3324             \core_message\api::count_conversation_members($conversationid));
3325     }
3327     /**
3328      * Test remove_members_from_conversation for multiple non valid users.
3329      */
3330     public function test_remove_members_for_multiple_no_valid_users() {
3331         $user1 = self::getDataGenerator()->create_user();
3332         $user2 = self::getDataGenerator()->create_user();
3333         $user3 = self::getDataGenerator()->create_user();
3334         $user4 = self::getDataGenerator()->create_user();
3336         $conversation = \core_message\api::create_conversation(
3337             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3338             [
3339                 $user1->id,
3340                 $user2->id