0f1d3df9eed857f0652b1b9cf7cb886fde2eb042
[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);
1327         // Confirm the message data is correct.
1328         $this->assertEquals(4, count($messages));
1330         $message1 = $messages[0];
1331         $message2 = $messages[1];
1332         $message3 = $messages[2];
1333         $message4 = $messages[3];
1335         $this->assertEquals($user1->id, $message1->useridfrom);
1336         $this->assertEquals($user2->id, $message1->useridto);
1337         $this->assertTrue($message1->displayblocktime);
1338         $this->assertContains('Yo!', $message1->text);
1340         $this->assertEquals($user2->id, $message2->useridfrom);
1341         $this->assertEquals($user1->id, $message2->useridto);
1342         $this->assertFalse($message2->displayblocktime);
1343         $this->assertContains('Sup mang?', $message2->text);
1345         $this->assertEquals($user1->id, $message3->useridfrom);
1346         $this->assertEquals($user2->id, $message3->useridto);
1347         $this->assertFalse($message3->displayblocktime);
1348         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1350         $this->assertEquals($user2->id, $message4->useridfrom);
1351         $this->assertEquals($user1->id, $message4->useridto);
1352         $this->assertFalse($message4->displayblocktime);
1353         $this->assertContains('Word.', $message4->text);
1354     }
1356     /**
1357      * Tests retrieving conversation messages.
1358      */
1359     public function test_get_conversation_messages() {
1360         // Create some users.
1361         $user1 = self::getDataGenerator()->create_user();
1362         $user2 = self::getDataGenerator()->create_user();
1364         // Create conversation.
1365         $conversation = \core_message\api::create_conversation(
1366             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1367             [$user1->id, $user2->id]
1368         );
1370         // The person doing the search.
1371         $this->setUser($user1);
1373         // Send some messages back and forth.
1374         $time = 1;
1375         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1376         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1377         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1378         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1380         // Retrieve the messages.
1381         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1383         // Confirm the conversation id is correct.
1384         $this->assertEquals($conversation->id, $convmessages['id']);
1386         // Confirm the message data is correct.
1387         $messages = $convmessages['messages'];
1388         $this->assertEquals(4, count($messages));
1389         $message1 = $messages[0];
1390         $message2 = $messages[1];
1391         $message3 = $messages[2];
1392         $message4 = $messages[3];
1394         $this->assertEquals($user1->id, $message1->useridfrom);
1395         $this->assertContains('Yo!', $message1->text);
1397         $this->assertEquals($user2->id, $message2->useridfrom);
1398         $this->assertContains('Sup mang?', $message2->text);
1400         $this->assertEquals($user1->id, $message3->useridfrom);
1401         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1403         $this->assertEquals($user1->id, $message4->useridfrom);
1404         $this->assertContains('Word.', $message4->text);
1406         // Confirm the members data is correct.
1407         $members = $convmessages['members'];
1408         $this->assertEquals(2, count($members));
1409     }
1411     /**
1412      * Tests retrieving group conversation messages.
1413      */
1414     public function test_get_group_conversation_messages() {
1415         // Create some users.
1416         $user1 = self::getDataGenerator()->create_user();
1417         $user2 = self::getDataGenerator()->create_user();
1418         $user3 = self::getDataGenerator()->create_user();
1419         $user4 = self::getDataGenerator()->create_user();
1421         // Create group conversation.
1422         $conversation = \core_message\api::create_conversation(
1423             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1424             [$user1->id, $user2->id, $user3->id, $user4->id]
1425         );
1427         // The person doing the search.
1428         $this->setUser($user1);
1430         // Send some messages back and forth.
1431         $time = 1;
1432         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1433         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1434         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1435         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1436         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
1438         // Retrieve the messages.
1439         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1441         // Confirm the conversation id is correct.
1442         $this->assertEquals($conversation->id, $convmessages['id']);
1444         // Confirm the message data is correct.
1445         $messages = $convmessages['messages'];
1446         $this->assertEquals(5, count($messages));
1448         $message1 = $messages[0];
1449         $message2 = $messages[1];
1450         $message3 = $messages[2];
1451         $message4 = $messages[3];
1452         $message5 = $messages[4];
1454         $this->assertEquals($user1->id, $message1->useridfrom);
1455         $this->assertContains('Yo!', $message1->text);
1457         $this->assertEquals($user2->id, $message2->useridfrom);
1458         $this->assertContains('Sup mang?', $message2->text);
1460         $this->assertEquals($user3->id, $message3->useridfrom);
1461         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1463         $this->assertEquals($user1->id, $message4->useridfrom);
1464         $this->assertContains('Word.', $message4->text);
1466         $this->assertEquals($user2->id, $message5->useridfrom);
1467         $this->assertContains('Yeah!', $message5->text);
1469         // Confirm the members data is correct.
1470         $members = $convmessages['members'];
1471         $this->assertEquals(3, count($members));
1472     }
1474     /**
1475      * Test retrieving conversation messages by providing a minimum timecreated value.
1476      */
1477     public function test_get_conversation_messages_time_from_only() {
1478         // Create some users.
1479         $user1 = self::getDataGenerator()->create_user();
1480         $user2 = self::getDataGenerator()->create_user();
1481         $user3 = self::getDataGenerator()->create_user();
1482         $user4 = self::getDataGenerator()->create_user();
1484         // Create group conversation.
1485         $conversation = \core_message\api::create_conversation(
1486             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1487             [$user1->id, $user2->id, $user3->id, $user4->id]
1488         );
1490         // The person doing the search.
1491         $this->setUser($user1);
1493         // Send some messages back and forth.
1494         $time = 1;
1495         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1496         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1497         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1498         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1500         // Retrieve the messages from $time, which should be all of them.
1501         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
1503         // Confirm the conversation id is correct.
1504         $this->assertEquals($conversation->id, $convmessages['id']);
1506         // Confirm the message data is correct.
1507         $messages = $convmessages['messages'];
1508         $this->assertEquals(4, count($messages));
1510         $message1 = $messages[0];
1511         $message2 = $messages[1];
1512         $message3 = $messages[2];
1513         $message4 = $messages[3];
1515         $this->assertContains('Message 1', $message1->text);
1516         $this->assertContains('Message 2', $message2->text);
1517         $this->assertContains('Message 3', $message3->text);
1518         $this->assertContains('Message 4', $message4->text);
1520         // Confirm the members data is correct.
1521         $members = $convmessages['members'];
1522         $this->assertEquals(3, count($members));
1524         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1525         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1526             'timecreated ASC', $time + 3);
1528         // Confirm the conversation id is correct.
1529         $this->assertEquals($conversation->id, $convmessages['id']);
1531         // Confirm the message data is correct.
1532         $messages = $convmessages['messages'];
1533         $this->assertEquals(2, count($messages));
1535         $message1 = $messages[0];
1536         $message2 = $messages[1];
1538         $this->assertContains('Message 3', $message1->text);
1539         $this->assertContains('Message 4', $message2->text);
1541         // Confirm the members data is correct.
1542         $members = $convmessages['members'];
1543         $this->assertEquals(2, count($members));
1544     }
1546     /**
1547      * Test retrieving conversation messages by providing a maximum timecreated value.
1548      */
1549     public function test_get_conversation_messages_time_to_only() {
1550         // Create some users.
1551         $user1 = self::getDataGenerator()->create_user();
1552         $user2 = self::getDataGenerator()->create_user();
1553         $user3 = self::getDataGenerator()->create_user();
1554         $user4 = self::getDataGenerator()->create_user();
1556         // Create group conversation.
1557         $conversation = \core_message\api::create_conversation(
1558             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1559             [$user1->id, $user2->id, $user3->id, $user4->id]
1560         );
1562         // The person doing the search.
1563         $this->setUser($user1);
1565         // Send some messages back and forth.
1566         $time = 1;
1567         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1568         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1569         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1570         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1572         // Retrieve the messages up until $time + 4, which should be all of them.
1573         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1574             0, $time + 4);
1576         // Confirm the conversation id is correct.
1577         $this->assertEquals($conversation->id, $convmessages['id']);
1579         // Confirm the message data is correct.
1580         $messages = $convmessages['messages'];
1581         $this->assertEquals(4, count($messages));
1583         $message1 = $messages[0];
1584         $message2 = $messages[1];
1585         $message3 = $messages[2];
1586         $message4 = $messages[3];
1588         $this->assertContains('Message 1', $message1->text);
1589         $this->assertContains('Message 2', $message2->text);
1590         $this->assertContains('Message 3', $message3->text);
1591         $this->assertContains('Message 4', $message4->text);
1593         // Confirm the members data is correct.
1594         $members = $convmessages['members'];
1595         $this->assertEquals(3, count($members));
1597         // Retrieve the messages up until $time + 2, which should be the first two.
1598         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1599             0, $time + 2);
1601         // Confirm the conversation id is correct.
1602         $this->assertEquals($conversation->id, $convmessages['id']);
1604         // Confirm the message data is correct.
1605         $messages = $convmessages['messages'];
1606         $this->assertEquals(2, count($messages));
1608         $message1 = $messages[0];
1609         $message2 = $messages[1];
1611         $this->assertContains('Message 1', $message1->text);
1612         $this->assertContains('Message 2', $message2->text);
1614         // Confirm the members data is correct.
1615         $members = $convmessages['members'];
1616         $this->assertEquals(2, count($members));
1617     }
1619     /**
1620      * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
1621      */
1622     public function test_get_conversation_messages_time_from_and_to() {
1623         // Create some users.
1624         $user1 = self::getDataGenerator()->create_user();
1625         $user2 = self::getDataGenerator()->create_user();
1626         $user3 = self::getDataGenerator()->create_user();
1627         $user4 = self::getDataGenerator()->create_user();
1629         // Create group conversation.
1630         $conversation = \core_message\api::create_conversation(
1631             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1632             [$user1->id, $user2->id, $user3->id, $user4->id]
1633         );
1635         // The person doing the search.
1636         $this->setUser($user1);
1638         // Send some messages back and forth.
1639         $time = 1;
1640         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1641         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1642         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1643         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1645         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1646         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1647             'timecreated ASC', $time + 2, $time + 3);
1649         // Confirm the conversation id is correct.
1650         $this->assertEquals($conversation->id, $convmessages['id']);
1652         // Confirm the message data is correct.
1653         $messages = $convmessages['messages'];
1654         $this->assertEquals(2, count($messages));
1656         $message1 = $messages[0];
1657         $message2 = $messages[1];
1659         $this->assertContains('Message 2', $message1->text);
1660         $this->assertContains('Message 3', $message2->text);
1662         // Confirm the members data is correct.
1663         $members = $convmessages['members'];
1664         $this->assertEquals(2, count($members));
1665     }
1668     /**
1669      * Test retrieving conversation messages by providing a limitfrom value.
1670      */
1671     public function test_get_conversation_messages_limitfrom_only() {
1672         // Create some users.
1673         $user1 = self::getDataGenerator()->create_user();
1674         $user2 = self::getDataGenerator()->create_user();
1675         $user3 = self::getDataGenerator()->create_user();
1676         $user4 = self::getDataGenerator()->create_user();
1678         // Create group conversation.
1679         $conversation = \core_message\api::create_conversation(
1680             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1681             [$user1->id, $user2->id, $user3->id, $user4->id]
1682         );
1684         // The person doing the search.
1685         $this->setUser($user1);
1687         // Send some messages back and forth.
1688         $time = 1;
1689         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1690         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1691         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1692         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1694         // Retrieve the messages from $time, which should be all of them.
1695         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
1697         // Confirm the conversation id is correct.
1698         $messages = $convmessages['messages'];
1699         $this->assertEquals($conversation->id, $convmessages['id']);
1701         // Confirm the message data is correct.
1702         $this->assertEquals(2, count($messages));
1704         $message1 = $messages[0];
1705         $message2 = $messages[1];
1707         $this->assertContains('Message 3', $message1->text);
1708         $this->assertContains('Message 4', $message2->text);
1710         // Confirm the members data is correct.
1711         $members = $convmessages['members'];
1712         $this->assertEquals(2, count($members));
1713     }
1715     /**
1716      * Test retrieving conversation messages by providing a limitnum value.
1717      */
1718     public function test_get_conversation_messages_limitnum() {
1719         // Create some users.
1720         $user1 = self::getDataGenerator()->create_user();
1721         $user2 = self::getDataGenerator()->create_user();
1722         $user3 = self::getDataGenerator()->create_user();
1723         $user4 = self::getDataGenerator()->create_user();
1725         // Create group conversation.
1726         $conversation = \core_message\api::create_conversation(
1727             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1728             [$user1->id, $user2->id, $user3->id, $user4->id]
1729         );
1731         // The person doing the search.
1732         $this->setUser($user1);
1734         // Send some messages back and forth.
1735         $time = 1;
1736         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1737         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1738         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1739         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1741         // Retrieve the messages from $time, which should be all of them.
1742         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
1744         // Confirm the conversation id is correct.
1745         $messages = $convmessages['messages'];
1746         $this->assertEquals($conversation->id, $convmessages['id']);
1748         // Confirm the message data is correct.
1749         $messages = $convmessages['messages'];
1750         $this->assertEquals(1, count($messages));
1752         $message1 = $messages[0];
1754         $this->assertContains('Message 3', $message1->text);
1756         // Confirm the members data is correct.
1757         $members = $convmessages['members'];
1758         $this->assertEquals(1, count($members));
1759     }
1761     /**
1762      * Tests retrieving most recent message.
1763      */
1764     public function test_get_most_recent_message() {
1765         // Create some users.
1766         $user1 = self::getDataGenerator()->create_user();
1767         $user2 = self::getDataGenerator()->create_user();
1769         // The person doing the search.
1770         $this->setUser($user1);
1772         // Send some messages back and forth.
1773         $time = 1;
1774         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1775         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1776         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1777         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1779         // Retrieve the most recent messages.
1780         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1782         // Check the results are correct.
1783         $this->assertEquals($user2->id, $message->useridfrom);
1784         $this->assertEquals($user1->id, $message->useridto);
1785         $this->assertContains('Word.', $message->text);
1786     }
1788     /**
1789      * Tests retrieving most recent conversation message.
1790      */
1791     public function test_get_most_recent_conversation_message() {
1792         // Create some users.
1793         $user1 = self::getDataGenerator()->create_user();
1794         $user2 = self::getDataGenerator()->create_user();
1795         $user3 = self::getDataGenerator()->create_user();
1797         // Create group conversation.
1798         $conversation = \core_message\api::create_conversation(
1799             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1800             [$user1->id, $user2->id, $user3->id]
1801         );
1803         // The person getting the most recent conversation message.
1804         $this->setUser($user1);
1806         // Send some messages back and forth.
1807         $time = 1;
1808         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1809         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1810         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1811         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
1813         // Retrieve the most recent messages.
1814         $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
1816         // Check the results are correct.
1817         $this->assertEquals($user2->id, $message->useridfrom);
1818         $this->assertContains('Word.', $message->text);
1819     }
1821     /**
1822      * Tests retrieving a user's profile.
1823      */
1824     public function test_get_profile() {
1825         // Create some users.
1826         $user1 = self::getDataGenerator()->create_user();
1828         $user2 = new stdClass();
1829         $user2->country = 'AU';
1830         $user2->city = 'Perth';
1831         $user2 = self::getDataGenerator()->create_user($user2);
1833         // The person doing the search.
1834         $this->setUser($user1);
1836         // Get the profile.
1837         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1839         $this->assertEquals($user2->id, $profile->userid);
1840         $this->assertEmpty($profile->email);
1841         $this->assertEmpty($profile->country);
1842         $this->assertEmpty($profile->city);
1843         $this->assertEquals(fullname($user2), $profile->fullname);
1844         $this->assertNull($profile->isonline);
1845         $this->assertFalse($profile->isblocked);
1846         $this->assertFalse($profile->iscontact);
1847     }
1849     /**
1850      * Tests retrieving a user's profile.
1851      */
1852     public function test_get_profile_as_admin() {
1853         // The person doing the search.
1854         $this->setAdminUser();
1856         // Create some users.
1857         $user1 = self::getDataGenerator()->create_user();
1859         $user2 = new stdClass();
1860         $user2->country = 'AU';
1861         $user2->city = 'Perth';
1862         $user2 = self::getDataGenerator()->create_user($user2);
1864         // Get the profile.
1865         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1867         $this->assertEquals($user2->id, $profile->userid);
1868         $this->assertEquals($user2->email, $profile->email);
1869         $this->assertEquals($user2->country, $profile->country);
1870         $this->assertEquals($user2->city, $profile->city);
1871         $this->assertEquals(fullname($user2), $profile->fullname);
1872         $this->assertFalse($profile->isonline);
1873         $this->assertFalse($profile->isblocked);
1874         $this->assertFalse($profile->iscontact);
1875     }
1877     /**
1878      * Tests checking if a user can mark all messages as read.
1879      */
1880     public function test_can_mark_all_messages_as_read() {
1881         // Set as the admin.
1882         $this->setAdminUser();
1884         // Create some users.
1885         $user1 = self::getDataGenerator()->create_user();
1886         $user2 = self::getDataGenerator()->create_user();
1887         $user3 = self::getDataGenerator()->create_user();
1889         // Send some messages back and forth.
1890         $time = 1;
1891         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1892         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1893         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1894         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1896         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1898         // The admin can do anything.
1899         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1901         // Set as the user 1.
1902         $this->setUser($user1);
1904         // The user can mark the messages as he is in the conversation.
1905         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1907         // User 1 can not mark the messages read for user 2.
1908         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
1910         // This user is not a part of the conversation.
1911         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
1912     }
1914     /**
1915      * Tests checking if a user can delete a conversation.
1916      */
1917     public function test_can_delete_conversation() {
1918         // Set as the admin.
1919         $this->setAdminUser();
1921         // Create some users.
1922         $user1 = self::getDataGenerator()->create_user();
1923         $user2 = self::getDataGenerator()->create_user();
1925         // Send some messages back and forth.
1926         $time = 1;
1927         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1928         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1929         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1930         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1932         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1934         // The admin can do anything.
1935         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1937         // Set as the user 1.
1938         $this->setUser($user1);
1940         // They can delete their own messages.
1941         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1943         // They can't delete someone elses.
1944         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
1945     }
1947     /**
1948      * Tests deleting a conversation.
1949      */
1950     public function test_delete_conversation() {
1951         global $DB;
1953         // Create some users.
1954         $user1 = self::getDataGenerator()->create_user();
1955         $user2 = self::getDataGenerator()->create_user();
1957         // The person doing the search.
1958         $this->setUser($user1);
1960         // Send some messages back and forth.
1961         $time = 1;
1962         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1963         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1964         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1965         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1967         // Delete the conversation as user 1.
1968         \core_message\api::delete_conversation($user1->id, $user2->id);
1969         $this->assertDebuggingCalled();
1971         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1972         $this->assertCount(4, $muas);
1973         // Sort by id.
1974         ksort($muas);
1976         $mua1 = array_shift($muas);
1977         $mua2 = array_shift($muas);
1978         $mua3 = array_shift($muas);
1979         $mua4 = array_shift($muas);
1981         $this->assertEquals($user1->id, $mua1->userid);
1982         $this->assertEquals($m1id, $mua1->messageid);
1983         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1985         $this->assertEquals($user1->id, $mua2->userid);
1986         $this->assertEquals($m2id, $mua2->messageid);
1987         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1989         $this->assertEquals($user1->id, $mua3->userid);
1990         $this->assertEquals($m3id, $mua3->messageid);
1991         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1993         $this->assertEquals($user1->id, $mua4->userid);
1994         $this->assertEquals($m4id, $mua4->messageid);
1995         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1996     }
1998     /**
1999      * Tests deleting a conversation by conversation id.
2000      */
2001     public function test_delete_conversation_by_id() {
2002         global $DB;
2004         // Create some users.
2005         $user1 = self::getDataGenerator()->create_user();
2006         $user2 = self::getDataGenerator()->create_user();
2008         // The person doing the search.
2009         $this->setUser($user1);
2011         // Send some messages back and forth.
2012         $time = 1;
2013         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2014         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2015         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2016         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2018         // Delete the conversation as user 1.
2019         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2020         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2022         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2023         $this->assertCount(4, $muas);
2024         // Sort by id.
2025         ksort($muas);
2027         $mua1 = array_shift($muas);
2028         $mua2 = array_shift($muas);
2029         $mua3 = array_shift($muas);
2030         $mua4 = array_shift($muas);
2032         $this->assertEquals($user1->id, $mua1->userid);
2033         $this->assertEquals($m1id, $mua1->messageid);
2034         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2036         $this->assertEquals($user1->id, $mua2->userid);
2037         $this->assertEquals($m2id, $mua2->messageid);
2038         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2040         $this->assertEquals($user1->id, $mua3->userid);
2041         $this->assertEquals($m3id, $mua3->messageid);
2042         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2044         $this->assertEquals($user1->id, $mua4->userid);
2045         $this->assertEquals($m4id, $mua4->messageid);
2046         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2047     }
2049     /**
2050      * Tests counting unread conversations.
2051      */
2052     public function test_count_unread_conversations() {
2053         $this->resetAfterTest(true);
2055         // Create some users.
2056         $user1 = self::getDataGenerator()->create_user();
2057         $user2 = self::getDataGenerator()->create_user();
2058         $user3 = self::getDataGenerator()->create_user();
2059         $user4 = self::getDataGenerator()->create_user();
2061         // The person wanting the conversation count.
2062         $this->setUser($user1);
2064         // Send some messages back and forth, have some different conversations with different users.
2065         $this->send_fake_message($user1, $user2, 'Yo!');
2066         $this->send_fake_message($user2, $user1, 'Sup mang?');
2067         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2068         $this->send_fake_message($user2, $user1, 'Word.');
2070         $this->send_fake_message($user1, $user3, 'Booyah');
2071         $this->send_fake_message($user3, $user1, 'Whaaat?');
2072         $this->send_fake_message($user1, $user3, 'Nothing.');
2073         $this->send_fake_message($user3, $user1, 'Cool.');
2075         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2076         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2077         $this->send_fake_message($user1, $user4, 'Dope.');
2079         // Check the amount for the current user.
2080         $this->assertEquals(3, core_message\api::count_unread_conversations());
2082         // Check the amount for the second user.
2083         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2084     }
2086     /**
2087      * Tests deleting a conversation.
2088      */
2089     public function test_get_all_message_preferences() {
2090         $user = self::getDataGenerator()->create_user();
2091         $this->setUser($user);
2093         // Set a couple of preferences to test.
2094         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2095         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2097         $processors = get_message_processors();
2098         $providers = message_get_providers_for_user($user->id);
2099         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2101         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2102         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2103     }
2105     /**
2106      * Tests the user can post a message.
2107      */
2108     public function test_can_post_message() {
2109         // Create some users.
2110         $user1 = self::getDataGenerator()->create_user();
2111         $user2 = self::getDataGenerator()->create_user();
2113         // Set as the first user.
2114         $this->setUser($user1);
2116         // With the default privacy setting, users can't message them.
2117         $this->assertFalse(\core_message\api::can_post_message($user2));
2119         // Enrol users to the same course.
2120         $course = $this->getDataGenerator()->create_course();
2121         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2122         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2123         // After enrolling users to the course, they should be able to message them with the default privacy setting.
2124         $this->assertTrue(\core_message\api::can_post_message($user2));
2125     }
2127     /**
2128      * Tests the user can't post a message without proper capability.
2129      */
2130     public function test_can_post_message_without_sendmessage_cap() {
2131         global $DB;
2133         // Create some users.
2134         $user1 = self::getDataGenerator()->create_user();
2135         $user2 = self::getDataGenerator()->create_user();
2137         // Set as the user 1.
2138         $this->setUser($user1);
2140         // Remove the capability to send a message.
2141         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
2142         unassign_capability('moodle/site:sendmessage', $roleids['user'],
2143             context_system::instance());
2145         // Check that we can not post a message without the capability.
2146         $this->assertFalse(\core_message\api::can_post_message($user2));
2147     }
2149     /**
2150      * Tests the user can post a message when they are contact.
2151      */
2152     public function test_can_post_message_when_contact() {
2153         // Create some users.
2154         $user1 = self::getDataGenerator()->create_user();
2155         $user2 = self::getDataGenerator()->create_user();
2157         // Set as the first user.
2158         $this->setUser($user1);
2160         // Check that we can not send user2 a message.
2161         $this->assertFalse(\core_message\api::can_post_message($user2));
2163         // Add users as contacts.
2164         \core_message\api::add_contact($user1->id, $user2->id);
2166         // Check that the return result is now true.
2167         $this->assertTrue(\core_message\api::can_post_message($user2));
2168     }
2170     /**
2171      * Tests the user can't post a message if they are not a contact and the user
2172      * has requested messages only from contacts.
2173      */
2174     public function test_can_post_message_when_not_contact() {
2175         // Create some users.
2176         $user1 = self::getDataGenerator()->create_user();
2177         $user2 = self::getDataGenerator()->create_user();
2179         // Set as the first user.
2180         $this->setUser($user1);
2182         // Set the second user's preference to not receive messages from non-contacts.
2183         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2185         // Check that we can not send user 2 a message.
2186         $this->assertFalse(\core_message\api::can_post_message($user2));
2187     }
2189     /**
2190      * Tests the user can't post a message if they are blocked.
2191      */
2192     public function test_can_post_message_when_blocked() {
2193         // Create some users.
2194         $user1 = self::getDataGenerator()->create_user();
2195         $user2 = self::getDataGenerator()->create_user();
2197         // Set the user.
2198         $this->setUser($user1);
2200         // Block the second user.
2201         \core_message\api::block_user($user1->id, $user2->id);
2203         // Check that the second user can no longer send the first user a message.
2204         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
2205     }
2207     /**
2208      * Tests the user can post a message when site-wide messaging setting is enabled,
2209      * even if they are not a contact and are not members of the same course.
2210      */
2211     public function test_can_post_message_site_messaging_setting() {
2212         // Create some users.
2213         $user1 = self::getDataGenerator()->create_user();
2214         $user2 = self::getDataGenerator()->create_user();
2216         // Set as the first user.
2217         $this->setUser($user1);
2219         // By default, user only can be messaged by contacts and members of any of his/her courses.
2220         $this->assertFalse(\core_message\api::can_post_message($user2));
2222         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2223         set_config('messagingallusers', true);
2225         // Set the second user's preference to receive messages from everybody.
2226         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
2228         // Check that we can send user2 a message.
2229         $this->assertTrue(\core_message\api::can_post_message($user2));
2231         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
2232         // and members sharing a course with her.
2233         set_config('messagingallusers', false);
2235         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
2236         $this->assertFalse(\core_message\api::can_post_message($user2));
2238         // Enrol users to the same course.
2239         $course = $this->getDataGenerator()->create_course();
2240         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2241         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2242         // Check that we can send user2 a message because they are sharing a course.
2243         $this->assertTrue(\core_message\api::can_post_message($user2));
2245         // Set the second user's preference to receive messages only from contacts.
2246         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2247         // Check that now the user2 can't be contacted because user1 is not their contact.
2248         $this->assertFalse(\core_message\api::can_post_message($user2));
2250         // Make contacts user1 and user2.
2251         \core_message\api::add_contact($user2->id, $user1->id);
2252         // Check that we can send user2 a message because they are contacts.
2253         $this->assertTrue(\core_message\api::can_post_message($user2));
2254     }
2256     /**
2257      * Tests the user with the messageanyuser capability can post a message.
2258      */
2259     public function test_can_post_message_with_messageanyuser_cap() {
2260         global $DB;
2262         // Create some users.
2263         $teacher1 = self::getDataGenerator()->create_user();
2264         $student1 = self::getDataGenerator()->create_user();
2265         $student2 = self::getDataGenerator()->create_user();
2267         // Create users not enrolled in any course.
2268         $user1 = self::getDataGenerator()->create_user();
2270         // Create a course.
2271         $course1 = $this->getDataGenerator()->create_course();
2273         // Enrol the users in the course.
2274         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
2275         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
2276         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
2278         // Set some student preferences to not receive messages from non-contacts.
2279         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
2281         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
2282         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
2283         // Check that the teacher can't contact user1 because it's not his teacher.
2284         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
2286         // Remove the messageanyuser capability from the course1 for teachers.
2287         $coursecontext = context_course::instance($course1->id);
2288         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
2289         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
2290         $coursecontext->mark_dirty();
2292         // Check that we can't send user1 a message because they are not contacts.
2293         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
2294         // However, teacher can message student2 because they are sharing a course.
2295         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
2296     }
2298     /**
2299      * Tests get_user_privacy_messaging_preference method.
2300      */
2301     public function test_get_user_privacy_messaging_preference() {
2302         // Create some users.
2303         $user1 = self::getDataGenerator()->create_user();
2304         $user2 = self::getDataGenerator()->create_user();
2305         $user3 = self::getDataGenerator()->create_user();
2307         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2308         set_config('messagingallusers', true);
2310         // Set some user preferences.
2311         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
2312         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2314         // Check the returned value for each user.
2315         $this->assertEquals(
2316             \core_message\api::MESSAGE_PRIVACY_SITE,
2317             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2318         );
2319         $this->assertEquals(
2320             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2321             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2322         );
2323         $this->assertEquals(
2324             \core_message\api::MESSAGE_PRIVACY_SITE,
2325             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2326         );
2328         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
2329         set_config('messagingallusers', false);
2331         // Check the returned value for each user.
2332         $this->assertEquals(
2333             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2334             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2335         );
2336         $this->assertEquals(
2337             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2338             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2339         );
2340         $this->assertEquals(
2341             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2342             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2343         );
2344     }
2346     /**
2347      * Tests that when blocking messages from non-contacts is enabled that
2348      * non-contacts trying to send a message return false.
2349      */
2350     public function test_is_user_non_contact_blocked() {
2351         // Create some users.
2352         $user1 = self::getDataGenerator()->create_user();
2353         $user2 = self::getDataGenerator()->create_user();
2355         // Set as the first user.
2356         $this->setUser($user1);
2358         // By default, user only can be messaged by contacts and members of any of his/her courses.
2359         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2360         $this->assertDebuggingCalled();
2362         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
2363         // messages from everybody.
2364         set_config('messagingallusers', true);
2365         // Check that the return result is now false because any site user can contact him/her.
2366         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2367         $this->assertDebuggingCalled();
2369         // Set the second user's preference to not receive messages from non-contacts.
2370         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2371         // Check that the return result is still true (because is even more restricted).
2372         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2373         $this->assertDebuggingCalled();
2375         // Add the first user as a contact for the second user.
2376         \core_message\api::add_contact($user2->id, $user1->id);
2378         // Check that the return result is now false.
2379         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2380         $this->assertDebuggingCalled();
2382         // Set the second user's preference to receive messages from course members.
2383         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
2384         // Check that the return result is still false (because $user1 is still his/her contact).
2385         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2386         $this->assertDebuggingCalled();
2387     }
2389     /**
2390      * Tests that we return true when a user is blocked, or false
2391      * if they are not blocked.
2392      */
2393     public function test_is_user_blocked() {
2394         // Create some users.
2395         $user1 = self::getDataGenerator()->create_user();
2396         $user2 = self::getDataGenerator()->create_user();
2398         // Set the user.
2399         $this->setUser($user1);
2401         // User shouldn't be blocked.
2402         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2403         $this->assertDebuggingCalled();
2405         // Block the user.
2406         \core_message\api::block_user($user1->id, $user2->id);
2408         // User should be blocked.
2409         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
2410         $this->assertDebuggingCalled();
2412         // Unblock the user.
2413         \core_message\api::unblock_user($user1->id, $user2->id);
2414         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2415         $this->assertDebuggingCalled();
2416     }
2418     /**
2419      * Tests that the admin is not blocked even if someone has chosen to block them.
2420      */
2421     public function test_is_user_blocked_as_admin() {
2422         // Create a user.
2423         $user1 = self::getDataGenerator()->create_user();
2425         // Set the user.
2426         $this->setUser($user1);
2428         // Block the admin user.
2429         \core_message\api::block_user($user1->id, 2);
2431         // Now change to the admin user.
2432         $this->setAdminUser();
2434         // As the admin you should still be able to send messages to the user.
2435         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
2436         $this->assertDebuggingCalled();
2437     }
2439     /*
2440      * Tes get_message_processor api.
2441      */
2442     public function test_get_message_processor() {
2443         $processors = get_message_processors(true);
2444         if (empty($processors)) {
2445             $this->markTestSkipped("No message processors found");
2446         }
2448         $name = key($processors);
2449         $processor = current($processors);
2450         $testprocessor = \core_message\api::get_message_processor($name);
2451         $this->assertEquals($processor->name, $testprocessor->name);
2452         $this->assertEquals($processor->enabled, $testprocessor->enabled);
2453         $this->assertEquals($processor->available, $testprocessor->available);
2454         $this->assertEquals($processor->configured, $testprocessor->configured);
2456         // Disable processor and test.
2457         \core_message\api::update_processor_status($testprocessor, 0);
2458         $testprocessor = \core_message\api::get_message_processor($name, true);
2459         $this->assertEmpty($testprocessor);
2460         $testprocessor = \core_message\api::get_message_processor($name);
2461         $this->assertEquals($processor->name, $testprocessor->name);
2462         $this->assertEquals(0, $testprocessor->enabled);
2464         // Enable again and test.
2465         \core_message\api::update_processor_status($testprocessor, 1);
2466         $testprocessor = \core_message\api::get_message_processor($name, true);
2467         $this->assertEquals($processor->name, $testprocessor->name);
2468         $this->assertEquals(1, $testprocessor->enabled);
2469         $testprocessor = \core_message\api::get_message_processor($name);
2470         $this->assertEquals($processor->name, $testprocessor->name);
2471         $this->assertEquals(1, $testprocessor->enabled);
2472     }
2474     /**
2475      * Test method update_processor_status.
2476      */
2477     public function test_update_processor_status() {
2478         $processors = get_message_processors();
2479         if (empty($processors)) {
2480             $this->markTestSkipped("No message processors found");
2481         }
2482         $name = key($processors);
2483         $testprocessor = current($processors);
2485         // Enable.
2486         \core_message\api::update_processor_status($testprocessor, 1);
2487         $testprocessor = \core_message\api::get_message_processor($name);
2488         $this->assertEquals(1, $testprocessor->enabled);
2490         // Disable.
2491         \core_message\api::update_processor_status($testprocessor, 0);
2492         $testprocessor = \core_message\api::get_message_processor($name);
2493         $this->assertEquals(0, $testprocessor->enabled);
2495         // Enable again.
2496         \core_message\api::update_processor_status($testprocessor, 1);
2497         $testprocessor = \core_message\api::get_message_processor($name);
2498         $this->assertEquals(1, $testprocessor->enabled);
2499     }
2501     /**
2502      * Test method is_user_enabled.
2503      */
2504     public function is_user_enabled() {
2505         $processors = get_message_processors();
2506         if (empty($processors)) {
2507             $this->markTestSkipped("No message processors found");
2508         }
2509         $name = key($processors);
2510         $testprocessor = current($processors);
2512         // Enable.
2513         \core_message\api::update_processor_status($testprocessor, 1);
2514         $status = \core_message\api::is_processor_enabled($name);
2515         $this->assertEquals(1, $status);
2517         // Disable.
2518         \core_message\api::update_processor_status($testprocessor, 0);
2519         $status = \core_message\api::is_processor_enabled($name);
2520         $this->assertEquals(0, $status);
2522         // Enable again.
2523         \core_message\api::update_processor_status($testprocessor, 1);
2524         $status = \core_message\api::is_processor_enabled($name);
2525         $this->assertEquals(1, $status);
2526     }
2528     /**
2529      * Test retrieving messages by providing a minimum timecreated value.
2530      */
2531     public function test_get_messages_time_from_only() {
2532         // Create some users.
2533         $user1 = self::getDataGenerator()->create_user();
2534         $user2 = self::getDataGenerator()->create_user();
2536         // The person doing the search.
2537         $this->setUser($user1);
2539         // Send some messages back and forth.
2540         $time = 1;
2541         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2542         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2543         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2544         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2546         // Retrieve the messages from $time, which should be all of them.
2547         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
2549         // Confirm the message data is correct.
2550         $this->assertEquals(4, count($messages));
2552         $message1 = $messages[0];
2553         $message2 = $messages[1];
2554         $message3 = $messages[2];
2555         $message4 = $messages[3];
2557         $this->assertContains('Message 1', $message1->text);
2558         $this->assertContains('Message 2', $message2->text);
2559         $this->assertContains('Message 3', $message3->text);
2560         $this->assertContains('Message 4', $message4->text);
2562         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2563         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
2565         // Confirm the message data is correct.
2566         $this->assertEquals(2, count($messages));
2568         $message1 = $messages[0];
2569         $message2 = $messages[1];
2571         $this->assertContains('Message 3', $message1->text);
2572         $this->assertContains('Message 4', $message2->text);
2573     }
2575     /**
2576      * Test retrieving messages by providing a maximum timecreated value.
2577      */
2578     public function test_get_messages_time_to_only() {
2579         // Create some users.
2580         $user1 = self::getDataGenerator()->create_user();
2581         $user2 = self::getDataGenerator()->create_user();
2583         // The person doing the search.
2584         $this->setUser($user1);
2586         // Send some messages back and forth.
2587         $time = 1;
2588         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2589         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2590         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2591         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2593         // Retrieve the messages up until $time + 4, which should be all of them.
2594         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
2596         // Confirm the message data is correct.
2597         $this->assertEquals(4, count($messages));
2599         $message1 = $messages[0];
2600         $message2 = $messages[1];
2601         $message3 = $messages[2];
2602         $message4 = $messages[3];
2604         $this->assertContains('Message 1', $message1->text);
2605         $this->assertContains('Message 2', $message2->text);
2606         $this->assertContains('Message 3', $message3->text);
2607         $this->assertContains('Message 4', $message4->text);
2609         // Retrieve the messages up until $time + 2, which should be the first two.
2610         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
2612         // Confirm the message data is correct.
2613         $this->assertEquals(2, count($messages));
2615         $message1 = $messages[0];
2616         $message2 = $messages[1];
2618         $this->assertContains('Message 1', $message1->text);
2619         $this->assertContains('Message 2', $message2->text);
2620     }
2622     /**
2623      * Test retrieving messages by providing a minimum and maximum timecreated value.
2624      */
2625     public function test_get_messages_time_from_and_to() {
2626         // Create some users.
2627         $user1 = self::getDataGenerator()->create_user();
2628         $user2 = self::getDataGenerator()->create_user();
2630         // The person doing the search.
2631         $this->setUser($user1);
2633         // Send some messages back and forth.
2634         $time = 1;
2635         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2636         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2637         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2638         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2640         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2641         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
2643         // Confirm the message data is correct.
2644         $this->assertEquals(2, count($messages));
2646         $message1 = $messages[0];
2647         $message2 = $messages[1];
2649         $this->assertContains('Message 2', $message1->text);
2650         $this->assertContains('Message 3', $message2->text);
2651     }
2653     /**
2654      * Test returning blocked users.
2655      */
2656     public function test_get_blocked_users() {
2657         global $USER;
2659         // Set this user as the admin.
2660         $this->setAdminUser();
2662         // Create a user to add to the admin's contact list.
2663         $user1 = $this->getDataGenerator()->create_user();
2664         $user2 = $this->getDataGenerator()->create_user();
2666         // Add users to the admin's contact list.
2667         \core_message\api::block_user($USER->id, $user2->id);
2669         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2671         // Block other user.
2672         \core_message\api::block_user($USER->id, $user1->id);
2673         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
2675         // Test deleting users.
2676         delete_user($user1);
2677         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2678     }
2680     /**
2681      * Test returning contacts with unread message count.
2682      */
2683     public function test_get_contacts_with_unread_message_count() {
2684         global $DB;
2686         $user1 = self::getDataGenerator()->create_user();
2687         $user2 = self::getDataGenerator()->create_user();
2688         $user3 = self::getDataGenerator()->create_user();
2689         $user4 = self::getDataGenerator()->create_user();
2691         // Add the users to each of their contacts.
2692         \core_message\api::add_contact($user1->id, $user2->id);
2693         \core_message\api::add_contact($user2->id, $user3->id);
2695         $this->send_fake_message($user1, $user2);
2696         $this->send_fake_message($user1, $user2);
2697         $this->send_fake_message($user1, $user2);
2698         $message4id = $this->send_fake_message($user1, $user2);
2700         $this->send_fake_message($user3, $user2);
2701         $message6id = $this->send_fake_message($user3, $user2);
2702         $this->send_fake_message($user3, $user2);
2703         $this->send_fake_message($user3, $user2);
2704         $this->send_fake_message($user3, $user2);
2706         // Send a message that should never be included as the user is not a contact.
2707         $this->send_fake_message($user4, $user2);
2709         // Get the contacts and the unread message count.
2710         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2712         // Confirm the size is correct.
2713         $this->assertCount(2, $messages);
2714         ksort($messages);
2716         $messageinfo1 = array_shift($messages);
2717         $messageinfo2 = array_shift($messages);
2719         $this->assertEquals($user1->id, $messageinfo1->id);
2720         $this->assertEquals(4, $messageinfo1->messagecount);
2721         $this->assertEquals($user3->id, $messageinfo2->id);
2722         $this->assertEquals(5, $messageinfo2->messagecount);
2724         // Mark some of the messages as read.
2725         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2726         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2727         \core_message\api::mark_message_as_read($user2->id, $m4);
2728         \core_message\api::mark_message_as_read($user2->id, $m6);
2730         // Get the contacts and the unread message count.
2731         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2733         // Confirm the size is correct.
2734         $this->assertCount(2, $messages);
2735         ksort($messages);
2737         // Confirm read messages are not included.
2738         $messageinfo1 = array_shift($messages);
2739         $messageinfo2 = array_shift($messages);
2740         $this->assertEquals($user1->id, $messageinfo1->id);
2741         $this->assertEquals(3, $messageinfo1->messagecount);
2742         $this->assertEquals($user3->id, $messageinfo2->id);
2743         $this->assertEquals(4, $messageinfo2->messagecount);
2745         // Now, let's populate the database with messages from user2 to user 1.
2746         $this->send_fake_message($user2, $user1);
2747         $this->send_fake_message($user2, $user1);
2748         $messageid = $this->send_fake_message($user2, $user1);
2750         // Send a message that should never be included as the user is not a contact.
2751         $this->send_fake_message($user4, $user1);
2753         // Get the contacts and the unread message count.
2754         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2756         // Confirm the size is correct.
2757         $this->assertCount(1, $messages);
2758         $messageinfo1 = array_shift($messages);
2759         $this->assertEquals($user2->id, $messageinfo1->id);
2760         $this->assertEquals(3, $messageinfo1->messagecount);
2762         // Mark the last message as read.
2763         $m = $DB->get_record('messages', ['id' => $messageid]);
2764         \core_message\api::mark_message_as_read($user1->id, $m);
2766         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2768         // Confirm the size is correct.
2769         $this->assertCount(1, $messages);
2771         // Confirm read messages are not included.
2772         $messageinfo1 = array_shift($messages);
2773         $this->assertEquals($user2->id, $messageinfo1->id);
2774         $this->assertEquals(2, $messageinfo1->messagecount);
2775     }
2777     /**
2778      * Test returning contacts with unread message count when there are no messages.
2779      */
2780     public function test_get_contacts_with_unread_message_count_no_messages() {
2781         $user1 = self::getDataGenerator()->create_user();
2782         $user2 = self::getDataGenerator()->create_user();
2784         // Add the users to each of their contacts.
2785         \core_message\api::add_contact($user2->id, $user1->id);
2787         // Check we get the correct message count.
2788         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2790         // Confirm the size is correct.
2791         $this->assertCount(1, $messages);
2793         $messageinfo = array_shift($messages);
2795         $this->assertEquals($user1->id, $messageinfo->id);
2796         $this->assertEquals(0, $messageinfo->messagecount);
2797     }
2799     /**
2800      * Test returning non-contacts with unread message count.
2801      */
2802     public function test_get_non_contacts_with_unread_message_count() {
2803         global $DB;
2805         $user1 = self::getDataGenerator()->create_user();
2806         $user2 = self::getDataGenerator()->create_user();
2807         $user3 = self::getDataGenerator()->create_user();
2808         $user4 = self::getDataGenerator()->create_user();
2810         // Add a user to the contact list of the users we are testing this function with.
2811         \core_message\api::add_contact($user1->id, $user4->id);
2812         \core_message\api::add_contact($user2->id, $user4->id);
2814         $this->send_fake_message($user1, $user2);
2815         $this->send_fake_message($user1, $user2);
2816         $this->send_fake_message($user1, $user2);
2817         $message4id = $this->send_fake_message($user1, $user2);
2819         $this->send_fake_message($user3, $user2);
2820         $message6id = $this->send_fake_message($user3, $user2);
2821         $this->send_fake_message($user3, $user2);
2822         $this->send_fake_message($user3, $user2);
2823         $this->send_fake_message($user3, $user2);
2825         // Send a message that should never be included as the user is a contact.
2826         $this->send_fake_message($user4, $user2);
2828         // Get the non-contacts and the unread message count.
2829         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2831         // Check we get the correct message count.
2832         ksort($messages);
2833         $this->assertCount(2, $messages);
2834         $messageinfo1 = array_shift($messages);
2835         $messageinfo2 = array_shift($messages);
2836         $this->assertEquals($user1->id, $messageinfo1->id);
2837         $this->assertEquals(4, $messageinfo1->messagecount);
2838         $this->assertEquals($user3->id, $messageinfo2->id);
2839         $this->assertEquals(5, $messageinfo2->messagecount);
2841         // Mark some of the messages as read.
2842         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2843         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2844         \core_message\api::mark_message_as_read($user2->id, $m4);
2845         \core_message\api::mark_message_as_read($user2->id, $m6);
2847         // Get the non-contacts and the unread message count.
2848         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2850         // Check the marked message is not returned in the message count.
2851         ksort($messages);
2852         $this->assertCount(2, $messages);
2853         $messageinfo1 = array_shift($messages);
2854         $messageinfo2 = array_shift($messages);
2855         $this->assertEquals($user1->id, $messageinfo1->id);
2856         $this->assertEquals(3, $messageinfo1->messagecount);
2857         $this->assertEquals($user3->id, $messageinfo2->id);
2858         $this->assertEquals(4, $messageinfo2->messagecount);
2860         // Now, let's populate the database with messages from user2 to user 1.
2861         $this->send_fake_message($user2, $user1);
2862         $this->send_fake_message($user2, $user1);
2863         $messageid = $this->send_fake_message($user2, $user1);
2865         // Send a message that should never be included as the user is a contact.
2866         $this->send_fake_message($user4, $user1);
2868         // Get the non-contacts and the unread message count.
2869         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2871         // Confirm the size is correct.
2872         $this->assertCount(1, $messages);
2873         $messageinfo1 = array_shift($messages);
2874         $this->assertEquals($user2->id, $messageinfo1->id);
2875         $this->assertEquals(3, $messageinfo1->messagecount);
2877         // Mark the last message as read.
2878         $m = $DB->get_record('messages', ['id' => $messageid]);
2879         \core_message\api::mark_message_as_read($user1->id, $m);
2881         // Get the non-contacts and the unread message count.
2882         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2884         // Check the marked message is not returned in the message count.
2885         $this->assertCount(1, $messages);
2886         $messageinfo1 = array_shift($messages);
2887         $this->assertEquals($user2->id, $messageinfo1->id);
2888         $this->assertEquals(2, $messageinfo1->messagecount);
2889     }
2891     /**
2892      * Test marking a message as read.
2893      */
2894     public function test_mark_message_as_read() {
2895         global $DB;
2897         $user1 = self::getDataGenerator()->create_user();
2898         $user2 = self::getDataGenerator()->create_user();
2900         $this->send_fake_message($user1, $user2);
2901         $m2id = $this->send_fake_message($user1, $user2);
2902         $this->send_fake_message($user2, $user1);
2903         $m4id = $this->send_fake_message($user2, $user1);
2905         $m2 = $DB->get_record('messages', ['id' => $m2id]);
2906         $m4 = $DB->get_record('messages', ['id' => $m4id]);
2907         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
2908         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
2910         // Confirm there are two user actions.
2911         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
2912         $this->assertEquals(2, count($muas));
2914         // Confirm they are correct.
2915         $mua1 = array_shift($muas);
2916         $mua2 = array_shift($muas);
2918         // Confirm first action.
2919         $this->assertEquals($user2->id, $mua1->userid);
2920         $this->assertEquals($m2id, $mua1->messageid);
2921         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
2922         $this->assertEquals(11, $mua1->timecreated);
2924         // Confirm second action.
2925         $this->assertEquals($user1->id, $mua2->userid);
2926         $this->assertEquals($m4id, $mua2->messageid);
2927         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
2928         $this->assertEquals(12, $mua2->timecreated);
2929     }
2931     /**
2932      * Test marking a notification as read.
2933      */
2934     public function test_mark_notification_as_read() {
2935         global $DB;
2937         $user1 = self::getDataGenerator()->create_user();
2938         $user2 = self::getDataGenerator()->create_user();
2940         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
2941         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
2942         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
2943         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
2945         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2946         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2948         \core_message\api::mark_notification_as_read($n2, 11);
2949         \core_message\api::mark_notification_as_read($n4, 12);
2951         // Retrieve the notifications.
2952         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2953         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2955         // Confirm they have been marked as read.
2956         $this->assertEquals(11, $n2->timeread);
2957         $this->assertEquals(12, $n4->timeread);
2958     }
2960     /**
2961      * Test a conversation is not returned if there is none.
2962      */
2963     public function test_get_conversation_between_users_no_conversation() {
2964         $user1 = self::getDataGenerator()->create_user();
2965         $user2 = self::getDataGenerator()->create_user();
2967         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2968     }
2970     /**
2971      * Test we can return a conversation that exists between users.
2972      */
2973     public function test_get_conversation_between_users_with_existing_conversation() {
2974         $user1 = self::getDataGenerator()->create_user();
2975         $user2 = self::getDataGenerator()->create_user();
2977         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2978         $this->assertDebuggingCalled();
2980         $this->assertEquals($conversationid,
2981             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2982     }
2984     /**
2985      * Test count_conversation_members for non existing conversation.
2986      */
2987     public function test_count_conversation_members_no_existing_conversation() {
2988         $this->assertEquals(0,
2989             \core_message\api::count_conversation_members(0));
2990     }
2992     /**
2993      * Test count_conversation_members for existing conversation.
2994      */
2995     public function test_count_conversation_members_existing_conversation() {
2996         $user1 = self::getDataGenerator()->create_user();
2997         $user2 = self::getDataGenerator()->create_user();
2999         $conversation = \core_message\api::create_conversation(
3000             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3001             [
3002                 $user1->id,
3003                 $user2->id
3004             ]
3005         );
3006         $conversationid = $conversation->id;
3008         $this->assertEquals(2,
3009             \core_message\api::count_conversation_members($conversationid));
3010     }
3012     /**
3013      * Test add_members_to_conversation for an individual conversation.
3014      */
3015     public function test_add_members_to_individual_conversation() {
3016         $user1 = self::getDataGenerator()->create_user();
3017         $user2 = self::getDataGenerator()->create_user();
3018         $user3 = self::getDataGenerator()->create_user();
3020         $conversation = \core_message\api::create_conversation(
3021             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3022             [
3023                 $user1->id,
3024                 $user2->id
3025             ]
3026         );
3027         $conversationid = $conversation->id;
3029         $this->expectException('moodle_exception');
3030         \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
3031     }
3033     /**
3034      * Test add_members_to_conversation for existing conversation.
3035      */
3036     public function test_add_members_to_existing_conversation() {
3037         $user1 = self::getDataGenerator()->create_user();
3038         $user2 = self::getDataGenerator()->create_user();
3039         $user3 = self::getDataGenerator()->create_user();
3041         $conversation = \core_message\api::create_conversation(
3042             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3043             [
3044                 $user1->id,
3045                 $user2->id
3046             ]
3047         );
3048         $conversationid = $conversation->id;
3050         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3051         $this->assertEquals(3,
3052             \core_message\api::count_conversation_members($conversationid));
3053     }
3055     /**
3056      * Test add_members_to_conversation for non existing conversation.
3057      */
3058     public function test_add_members_to_no_existing_conversation() {
3059         $user1 = self::getDataGenerator()->create_user();
3061         // Throw dml_missing_record_exception for non existing conversation.
3062         $this->expectException('dml_missing_record_exception');
3063         \core_message\api::add_members_to_conversation([$user1->id], 0);
3064     }
3066     /**
3067      * Test add_member_to_conversation for non existing user.
3068      */
3069     public function test_add_members_to_no_existing_user() {
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_GROUP,
3075             [
3076                 $user1->id,
3077                 $user2->id
3078             ]
3079         );
3080         $conversationid = $conversation->id;
3082         // Don't throw an error for non existing user, but don't add it as a member.
3083         $this->assertNull(\core_message\api::add_members_to_conversation([0], $conversationid));
3084         $this->assertEquals(2,
3085             \core_message\api::count_conversation_members($conversationid));
3086     }
3088     /**
3089      * Test add_members_to_conversation for current conversation member.
3090      */
3091     public function test_add_members_to_current_conversation_member() {
3092         $user1 = self::getDataGenerator()->create_user();
3093         $user2 = self::getDataGenerator()->create_user();
3095         $conversation = \core_message\api::create_conversation(
3096             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3097             [
3098                 $user1->id,
3099                 $user2->id
3100             ]
3101         );
3102         $conversationid = $conversation->id;
3104         // Don't add as a member a user that is already conversation member.
3105         $this->assertNull(\core_message\api::add_members_to_conversation([$user1->id], $conversationid));
3106         $this->assertEquals(2,
3107             \core_message\api::count_conversation_members($conversationid));
3108     }
3110     /**
3111      * Test add_members_to_conversation for multiple users.
3112      */
3113     public function test_add_members_for_multiple_users() {
3114         $user1 = self::getDataGenerator()->create_user();
3115         $user2 = self::getDataGenerator()->create_user();
3116         $user3 = self::getDataGenerator()->create_user();
3117         $user4 = self::getDataGenerator()->create_user();
3119         $conversation = \core_message\api::create_conversation(
3120             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3121             [
3122                 $user1->id,
3123                 $user2->id
3124             ]
3125         );
3126         $conversationid = $conversation->id;
3128         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3129         $this->assertEquals(4,
3130             \core_message\api::count_conversation_members($conversationid));
3131     }
3133     /**
3134      * Test add_members_to_conversation for multiple users, included non existing and current conversation members
3135      */
3136     public function test_add_members_for_multiple_not_valid_users() {
3137         $user1 = self::getDataGenerator()->create_user();
3138         $user2 = self::getDataGenerator()->create_user();
3139         $user3 = self::getDataGenerator()->create_user();
3141         $conversation = \core_message\api::create_conversation(
3142             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3143             [
3144                 $user1->id,
3145                 $user2->id
3146             ]
3147         );
3148         $conversationid = $conversation->id;
3150         // Don't throw errors, but don't add as members users don't exist or are already conversation members.
3151         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
3152         $this->assertEquals(3,
3153             \core_message\api::count_conversation_members($conversationid));
3154     }
3156     /**
3157      * Test remove_members_from_conversation for individual conversation.
3158      */
3159     public function test_remove_members_from_individual_conversation() {
3160         $user1 = self::getDataGenerator()->create_user();
3161         $user2 = self::getDataGenerator()->create_user();
3163         $conversation = \core_message\api::create_conversation(
3164             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3165             [
3166                 $user1->id,
3167                 $user2->id
3168             ]
3169         );
3170         $conversationid = $conversation->id;
3172         $this->expectException('moodle_exception');
3173         \core_message\api::remove_members_from_conversation([$user1->id], $conversationid);
3174     }
3176     /**
3177      * Test remove_members_from_conversation for existing conversation.
3178      */
3179     public function test_remove_members_from_existing_conversation() {
3180         $user1 = self::getDataGenerator()->create_user();
3181         $user2 = self::getDataGenerator()->create_user();
3183         $conversation = \core_message\api::create_conversation(
3184             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3185             [
3186                 $user1->id,
3187                 $user2->id
3188             ]
3189         );
3190         $conversationid = $conversation->id;
3192         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id], $conversationid));
3193         $this->assertEquals(1,
3194             \core_message\api::count_conversation_members($conversationid));
3195     }
3197     /**
3198      * Test remove_members_from_conversation for non existing conversation.
3199      */
3200     public function test_remove_members_from_no_existing_conversation() {
3201         $user1 = self::getDataGenerator()->create_user();
3203         // Throw dml_missing_record_exception for non existing conversation.
3204         $this->expectException('dml_missing_record_exception');
3205         \core_message\api::remove_members_from_conversation([$user1->id], 0);
3206     }
3208     /**
3209      * Test remove_members_from_conversation for non existing user.
3210      */
3211     public function test_remove_members_for_no_existing_user() {
3212         $user1 = self::getDataGenerator()->create_user();
3213         $user2 = 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         $this->assertNull(\core_message\api::remove_members_from_conversation([0], $conversationid));
3225         $this->assertEquals(2,
3226             \core_message\api::count_conversation_members($conversationid));
3227     }
3229     /**
3230      * Test remove_members_from_conversation for multiple users.
3231      */
3232     public function test_remove_members_for_multiple_users() {
3233         $user1 = self::getDataGenerator()->create_user();
3234         $user2 = self::getDataGenerator()->create_user();
3235         $user3 = self::getDataGenerator()->create_user();
3236         $user4 = self::getDataGenerator()->create_user();
3238         $conversation = \core_message\api::create_conversation(
3239             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3240             [
3241                 $user1->id,
3242                 $user2->id
3243             ]
3244         );
3245         $conversationid = $conversation->id;
3247         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
3248         $this->assertNull(\core_message\api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
3249         $this->assertEquals(2,
3250             \core_message\api::count_conversation_members($conversationid));
3251     }
3253     /**
3254      * Test remove_members_from_conversation for multiple non valid users.
3255      */
3256     public function test_remove_members_for_multiple_no_valid_users() {
3257         $user1 = self::getDataGenerator()->create_user();
3258         $user2 = self::getDataGenerator()->create_user();
3259         $user3 = self::getDataGenerator()->create_user();
3260         $user4 = self::getDataGenerator()->create_user();
3262         $conversation = \core_message\api::create_conversation(
3263             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3264             [
3265                 $user1->id,
3266                 $user2->id
3267             ]
3268         );
3269         $conversationid = $conversation->id;
3271         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3272         $this->assertNull(
3273             \core_message\api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid)
3274         );
3275         $this->assertEquals(1,
3276             \core_message\api::count_conversation_members($conversationid));
3277     }
3279     /**
3280      * Test count_conversation_members for empty conversation.
3281      */
3282     public function test_count_conversation_members_empty_conversation() {
3283         $user1 = self::getDataGenerator()->create_user();
3284         $user2 = self::getDataGenerator()->create_user();
3286         $conversation = \core_message\api::create_conversation(
3287             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3288             [
3289                 $user1->id,
3290                 $user2->id
3291             ]
3292         );
3293         $conversationid = $conversation->id;
3295         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid));
3297         $this->assertEquals(0,
3298             \core_message\api::count_conversation_members($conversationid));
3299     }
3301     /**
3302      * Test can create a contact request.
3303      */
3304     public function test_can_create_contact_request() {
3305         global $CFG;
3307         $user1 = self::getDataGenerator()->create_user();
3308         $user2 = self::getDataGenerator()->create_user();
3310         // Disable messaging.
3311         $CFG->messaging = 0;
3312         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
3314         // Re-enable messaging.
3315         $CFG->messaging = 1;
3317         // Allow users to message anyone site-wide.
3318         $CFG->messagingallusers = 1;
3319         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
3321         // Disallow users from messaging anyone site-wide.
3322         $CFG->messagingallusers = 0;
3323         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
3325         // Put the users in the same course so a contact request should be possible.
3326         $course = self::getDataGenerator()->create_course();
3327         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3328         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3329         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
3330     }
3332     /**
3333      * Test creating a contact request.
3334      */
3335     public function test_create_contact_request() {
3336         global $DB;
3338         $user1 = self::getDataGenerator()->create_user();
3339         $user2 = self::getDataGenerator()->create_user();
3341         \core_message\api::create_contact_request($user1->id, $user2->id);
3343         $request = $DB->get_records('message_contact_requests');
3345         $this->assertCount(1, $request);
3347         $request = reset($request);
3349         $this->assertEquals($user1->id, $request->userid);
3350         $this->assertEquals($user2->id, $request->requesteduserid);
3351     }
3353     /**
3354      * Test confirming a contact request.
3355      */
3356     public function test_confirm_contact_request() {
3357         global $DB;
3359         $user1 = self::getDataGenerator()->create_user();
3360         $user2 = self::getDataGenerator()->create_user();
3362         \core_message\api::create_contact_request($user1->id, $user2->id);
3364         \core_message\api::confirm_contact_request($user1->id, $user2->id);
3366         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
3368         $contact = $DB->get_records('message_contacts');
3370         $this->assertCount(1, $contact);
3372         $contact = reset($contact);
3374         $this->assertEquals($user1->id, $contact->userid);
3375         $this->assertEquals($user2->id, $contact->contactid);
3376     }
3378     /**
3379      * Test declining a contact request.
3380      */
3381     public function test_decline_contact_request() {
3382         global $DB;
3384         $user1 = self::getDataGenerator()->create_user();
3385         $user2 = self::getDataGenerator()->create_user();
3387         \core_message\api::create_contact_request($user1->id, $user2->id);
3389         \core_message\api::decline_contact_request($user1->id, $user2->id);
3391         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
3392         $this->assertEquals(0, $DB->count_records('message_contacts'));
3393     }
3395     /**
3396      * Test retrieving contact requests.
3397      */
3398     public function test_get_contact_requests() {
3399         $user1 = self::getDataGenerator()->create_user();
3400         $user2 = self::getDataGenerator()->create_user();
3401         $user3 = self::getDataGenerator()->create_user();
3403         // Block one user, their request should not show up.
3404         \core_message\api::block_user($user1->id, $user3->id);
3406         \core_message\api::create_contact_request($user2->id, $user1->id);
3407         \core_message\api::create_contact_request($user3->id, $user1->id);
3409         $requests = \core_message\api::get_contact_requests($user1->id);
3411         $this->assertCount(1, $requests);
3413         $request = reset($requests);
3415         $this->assertEquals($user2->id, $request->id);
3416         $this->assertEquals($user2->picture, $request->picture);
3417         $this->assertEquals($user2->firstname, $request->firstname);
3418         $this->assertEquals($user2->lastname, $request->lastname);
3419         $this->assertEquals($user2->firstnamephonetic, $request->firstnamephonetic);
3420         $this->assertEquals($user2->lastnamephonetic, $request->lastnamephonetic);
3421         $this->assertEquals($user2->middlename, $request->middlename);
3422         $this->assertEquals($user2->alternatename, $request->alternatename);
3423         $this->assertEquals($user2->email, $request->email);
3424     }
3426     /**
3427      * Test adding contacts.
3428      */
3429     public function test_add_contact() {
3430         global $DB;
3432         $user1 = self::getDataGenerator()->create_user();
3433         $user2 = self::getDataGenerator()->create_user();
3435         \core_message\api::add_contact($user1->id, $user2->id);
3437         $contact = $DB->get_records('message_contacts');
3439         $this->assertCount(1, $contact);
3441         $contact = reset($contact);
3443         $this->assertEquals($user1->id, $contact->userid);
3444         $this->assertEquals($user2->id, $contact->contactid);
3445     }
3447     /**
3448      * Test removing contacts.
3449      */
3450     public function test_remove_contact() {
3451         global $DB;
3453         $user1 = self::getDataGenerator()->create_user();
3454         $user2 = self::getDataGenerator()->create_user();
3456         \core_message\api::add_contact($user1->id, $user2->id);
3457         \core_message\api::remove_contact($user1->id, $user2->id);
3459         $this->assertEquals(0, $DB->count_records('message_contacts'));
3460     }
3462     /**
3463      * Test blocking users.
3464      */
3465     public function test_block_user() {
3466         global $DB;
3468         $user1 = self::getDataGenerator()->create_user();
3469         $user2 = self::getDataGenerator()->create_user();
3471         \core_message\api::block_user($user1->id, $user2->id);
3473         $blockedusers = $DB->get_records('message_users_blocked');
3475         $this->assertCount(1, $blockedusers);
3477         $blockeduser = reset($blockedusers);
3479         $this->assertEquals($user1->id, $blockeduser->userid);
3480         $this->assertEquals($user2->id, $blockeduser->blockeduserid);
3481     }
3483     /**
3484      * Test unblocking users.
3485      */
3486     public function test_unblock_user() {
3487         global $DB;
3489         $user1 = self::getDataGenerator()->create_user();
3490         $user2 = self::getDataGenerator()->create_user();
3492         \core_message\api::block_user($user1->id, $user2->id);
3493         \core_message\api::unblock_user($user1->id, $user2->id);
3495         $this->assertEquals(0, $DB->count_records('message_users_blocked'));
3496     }
3498     /**
3499      * Test is contact check.
3500      */
3501     public function test_is_contact() {
3502         $user1 = self::getDataGenerator()->create_user();
3503         $user2 = self::getDataGenerator()->create_user();
3504         $user3 = self::getDataGenerator()->create_user();
3506         \core_message\api::add_contact($user1->id, $user2->id);
3508         $this->assertTrue(\core_message\api::is_contact($user1->id, $user2->id));
3509         $this->assertTrue(\core_message\api::is_contact($user2->id, $user1->id));
3510         $this->assertFalse(\core_message\api::is_contact($user2->id, $user3->id));
3511     }
3513     /**
3514      * Test get contact.
3515      */
3516     public function test_get_contact() {
3517         $user1 = self::getDataGenerator()->create_user();
3518         $user2 = self::getDataGenerator()->create_user();
3520         \core_message\api::add_contact($user1->id, $user2->id);
3522         $contact = \core_message\api::get_contact($user1->id, $user2->id);
3524         $this->assertEquals($user1->id, $contact->userid);
3525         $this->assertEquals($user2->id, $contact->contactid);
3526     }
3528     /**
3529      * Test is blocked checked.
3530      */
3531     public function test_is_blocked() {
3532         $user1 = self::getDataGenerator()->create_user();
3533         $user2 = self::getDataGenerator()->create_user();
3535         $this->assertFalse(\core_message\api::is_blocked($user1->id, $user2->id));
3536         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
3538         \core_message\api::block_user($user1->id, $user2->id);
3540         $this->assertTrue(\core_message\api::is_blocked($user1->id, $user2->id));
3541         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
3542     }
3544     /**
3545      * Test the contact request exist check.
3546      */
3547     public function test_does_contact_request_exist() {
3548         $user1 = self::getDataGenerator()->create_user();
3549         $user2 = self::getDataGenerator()->create_user();
3551         $this->assertFalse(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
3552         $this->assertFalse(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
3554         \core_message\api::create_contact_request($user1->id, $user2->id);
3556         $this->assertTrue(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
3557         $this->assertTrue(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
3558     }
3560     /**
3561      * Test the user in conversation check.
3562      */
3563     public function test_is_user_in_conversation() {
3564         $user1 = self::getDataGenerator()->create_user();
3565         $user2 = self::getDataGenerator()->create_user();
3567         $conversation = \core_message\api::create_conversation(
3568             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3569             [
3570                 $user1->id,
3571                 $user2->id
3572             ]
3573         );
3574         $conversationid = $conversation->id;
3576         $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $conversationid));
3577     }
3579     /**
3580      * Test the user in conversation check when they are not.
3581      */
3582     public function test_is_user_in_conversation_when_not() {
3583         $user1 = self::getDataGenerator()->create_user();
3584         $user2 = self::getDataGenerator()->create_user();
3585         $user3 = self::getDataGenerator()->create_user();
3587         $conversation = \core_message\api::create_conversation(
3588             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3589             [
3590                 $user1->id,
3591                 $user2->id
3592             ]
3593         );
3594         $conversationid = $conversation->id;
3596         $this->assertFalse(\core_message\api::is_user_in_conversation($user3->id, $conversationid));
3597     }
3599     /**
3600      * Test can create a group conversation.
3601      */
3602     public function test_can_create_group_conversation() {
3603         global $CFG;
3605         $student = self::getDataGenerator()->create_user();
3606         $teacher = self::getDataGenerator()->create_user();
3607         $course = self::getDataGenerator()->create_course();
3609         $coursecontext = context_course::instance($course->id);
3611         $this->getDataGenerator()->enrol_user($student->id, $course->id);
3612         $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
3614         // Disable messaging.
3615         $CFG->messaging = 0;
3616         $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
3618         // Re-enable messaging.
3619         $CFG->messaging = 1;
3621         // Student shouldn't be able to.
3622         $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
3624         // Teacher should.
3625         $this->assertTrue(\core_message\api::can_create_group_conversation($teacher->id, $coursecontext));
3626     }
3628     /**
3629      * Test creating an individual conversation.
3630      */
3631     public function test_create_conversation_individual() {
3632         $user1 = self::getDataGenerator()->create_user();
3633         $user2 = self::getDataGenerator()->create_user();
3635         $conversation = \core_message\api::create_conversation(
3636             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3637             [
3638                 $user1->id,
3639                 $user2->id
3640             ],
3641             'A conversation name'
3642         );
3644         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type);
3645         $this->assertEquals('A conversation name', $conversation->name);
3646         $this->assertEquals(\core_message\helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash);
3648         $this->assertCount(2, $conversation->members);
3650         $member1 = array_shift($conversation->members);
3651         $member2 = array_shift($conversation->members);
3653         $this->assertEquals($user1->id, $member1->userid);
3654         $this->assertEquals($conversation->id, $member1->conversationid);
3656         $this->assertEquals($user2->id, $member2->userid);
3657         $this->assertEquals($conversation->id, $member2->conversationid);
3658     }
3660     /**
3661      * Test creating a group conversation.
3662      */
3663     public function test_create_conversation_group() {
3664         $user1 = self::getDataGenerator()->create_user();
3665         $user2 = self::getDataGenerator()->create_user();
3666         $user3 = self::getDataGenerator()->create_user();
3668         $conversation = \core_message\api::create_conversation(
3669             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3670             [
3671                 $user1->id,
3672                 $user2->id,
3673                 $user3->id
3674             ],
3675             'A conversation name'
3676         );
3678         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type);
3679         $this->assertEquals('A conversation name', $conversation->name);
3680         $this->assertNull($conversation->convhash);
3682         $this->assertCount(3, $conversation->members);
3684         $member1 = array_shift($conversation->members);
3685         $member2 = array_shift($conversation->members);
3686         $member3 = array_shift($conversation->members);
3688         $this->assertEquals($user1->id, $member1->userid);
3689         $this->assertEquals($conversation->id, $member1->conversationid);
3691         $this->assertEquals($user2->id, $member2->userid);
3692         $this->assertEquals($conversation->id, $member2->conversationid);
3694         $this->assertEquals($user3->id, $member3->userid);
3695         $this->assertEquals($conversation->id, $member3->conversationid);
3696     }
3698     /**
3699      * Test creating an individual conversation with too many members.
3700      */
3701     public function test_create_conversation_individual_too_many_members() {
3702         $this->expectException('moodle_exception');
3703         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]);
3704     }
3706     /**
3707      * Comparison function for sorting contacts.
3708      *
3709      * @param stdClass $a
3710      * @param stdClass $b
3711      * @return bool
3712      */
3713     protected static function sort_contacts($a, $b) {
3714         return $a->userid > $b->userid;
3715     }