MDL-63834 core_message: validate conversation type before creating
[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($convoids[1], $conversation->id);
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      * Helper to seed the database with initial state.
646      */
647     protected function create_conversation_test_data() {
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         $time = 1;
656         // Create some conversations. We want:
657         // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
658         // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
659         // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
660         // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
661         // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
663         // Individual conversation, user1 is a member, last message from other user.
664         $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
665             [$user1->id, $user2->id]);
666         testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
667         testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
669         // Individual conversation, user1 is a member, last message from user1.
670         $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
671             [$user1->id, $user3->id]);
672         testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
673         testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
675         // Individual conversation, user1 is not a member.
676         $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
677             [$user2->id, $user3->id]);
678         testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
679         testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
681         // Group conversation, user1 is not a member.
682         $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
683             [$user2->id, $user3->id, $user4->id], 'Project discussions');
684         testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
685         testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
687         // Group conversation, user1 is a member, last message from another user.
688         $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
689             [$user1->id, $user3->id, $user4->id], 'Group chat');
690         testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
691         testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
692         testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
694         // Group conversation, user1 is a member, last message from user1.
695         $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
696             [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
697         testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
698         testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
699         testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
701         // Empty group conversations (x2), user1 is a member.
702         $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
703             [$user1->id, $user2->id, $user3->id], 'Empty group');
704         $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
705             [$user1->id, $user2->id, $user4->id], 'Another empty group');
707         // Empty group conversation, user1 is NOT a member.
708         $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
709             [$user2->id, $user3->id, $user4->id], 'Empty group 3');
711         return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
712     }
714     /**
715      * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
716      */
717     public function test_get_conversations_no_restrictions() {
718         // No conversations should exist yet.
719         $user1 = self::getDataGenerator()->create_user();
720         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
722         // Get a bunch of conversations, some group, some individual and in different states.
723         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
724             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
726         // Get all conversations for user1.
727         $conversations = core_message\api::get_conversations($user1->id);
729         // Verify there are 2 individual conversation, 2 group conversations, and 2 empty group conversations.
730         // The conversations with the most recent messages should be listed first, followed by the empty
731         // conversations, with the most recently created first.
732         $this->assertCount(6, $conversations);
733         $typecounts  = array_count_values(array_column($conversations, 'type'));
734         $this->assertEquals(2, $typecounts[1]);
735         $this->assertEquals(4, $typecounts[2]);
737         // Those conversations having messages should be listed first, ordered by most recent message time.
738         $this->assertEquals($gc3->id, $conversations[0]->id);
739         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
740         $this->assertFalse($conversations[0]->isfavourite);
741         $this->assertCount(1, $conversations[0]->members);
742         $this->assertEquals(4, $conversations[0]->membercount);
743         $this->assertCount(1, $conversations[0]->messages);
744         $this->assertEquals("Message 14", $conversations[0]->messages[0]->text);
745         $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
747         $this->assertEquals($gc2->id, $conversations[1]->id);
748         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
749         $this->assertFalse($conversations[1]->isfavourite);
750         $this->assertCount(1, $conversations[1]->members);
751         $this->assertEquals(3, $conversations[1]->membercount);
752         $this->assertCount(1, $conversations[1]->messages);
753         $this->assertEquals("Message 11", $conversations[1]->messages[0]->text);
754         $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
756         $this->assertEquals($ic2->id, $conversations[2]->id);
757         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
758         $this->assertFalse($conversations[2]->isfavourite);
759         $this->assertCount(1, $conversations[2]->members);
760         $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
761         $this->assertEquals(2, $conversations[2]->membercount);
762         $this->assertCount(1, $conversations[2]->messages);
763         $this->assertEquals("Message 4", $conversations[2]->messages[0]->text);
764         $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
766         $this->assertEquals($ic1->id, $conversations[3]->id);
767         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
768         $this->assertFalse($conversations[3]->isfavourite);
769         $this->assertCount(1, $conversations[3]->members);
770         $this->assertEquals(2, $conversations[3]->membercount);
771         $this->assertCount(1, $conversations[3]->messages);
772         $this->assertEquals("Message 2", $conversations[3]->messages[0]->text);
773         $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
775         // Of the groups without messages, we expect to see the most recently created first.
776         $this->assertEquals($gc5->id, $conversations[4]->id);
777         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
778         $this->assertFalse($conversations[4]->isfavourite);
779         $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
780         $this->assertEquals(3, $conversations[4]->membercount);
781         $this->assertEmpty($conversations[4]->messages);
783         $this->assertEquals($gc4->id, $conversations[5]->id);
784         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
785         $this->assertFalse($conversations[5]->isfavourite);
786         $this->assertCount(0, $conversations[5]->members);
787         $this->assertEquals(3, $conversations[5]->membercount);
788         $this->assertEmpty($conversations[5]->messages);
790         // Verify format of the return structure.
791         foreach ($conversations as $conv) {
792             $this->assertObjectHasAttribute('id', $conv);
793             $this->assertObjectHasAttribute('name', $conv);
794             $this->assertObjectHasAttribute('subname', $conv);
795             $this->assertObjectHasAttribute('type', $conv);
796             $this->assertObjectHasAttribute('isfavourite', $conv);
797             $this->assertObjectHasAttribute('membercount', $conv);
798             $this->assertObjectHasAttribute('isread', $conv);
799             $this->assertObjectHasAttribute('unreadcount', $conv);
800             $this->assertObjectHasAttribute('members', $conv);
801             foreach ($conv->members as $member) {
802                 $this->assertObjectHasAttribute('id', $member);
803                 $this->assertObjectHasAttribute('fullname', $member);
804                 $this->assertObjectHasAttribute('profileimageurl', $member);
805                 $this->assertObjectHasAttribute('profileimageurlsmall', $member);
806                 $this->assertObjectHasAttribute('isonline', $member);
807                 $this->assertObjectHasAttribute('showonlinestatus', $member);
808                 $this->assertObjectHasAttribute('isblocked', $member);
809                 $this->assertObjectHasAttribute('iscontact', $member);
810             }
811             $this->assertObjectHasAttribute('messages', $conv);
812             foreach ($conv->messages as $message) {
813                 $this->assertObjectHasAttribute('id', $message);
814                 $this->assertObjectHasAttribute('useridfrom', $message);
815                 $this->assertObjectHasAttribute('text', $message);
816                 $this->assertObjectHasAttribute('timecreated', $message);
817             }
818         }
819     }
821     /**
822      * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
823      */
824     public function test_get_conversations_limit_offset() {
825         // Get a bunch of conversations, some group, some individual and in different states.
826         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
827             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
829         // Get all conversations for user1, limited to 1 result.
830         $conversations = core_message\api::get_conversations($user1->id, 0, 1);
832         // Verify the first conversation.
833         $this->assertCount(1, $conversations);
834         $conversation = array_shift($conversations);
835         $this->assertEquals($conversation->id, $gc3->id);
837         // Verify the next conversation.
838         $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
839         $this->assertCount(1, $conversations);
840         $this->assertEquals($gc2->id, $conversations[0]->id);
842         // Verify the next conversation.
843         $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
844         $this->assertCount(1, $conversations);
845         $this->assertEquals($ic2->id, $conversations[0]->id);
847         // Skip one and get both empty conversations.
848         $conversations = \core_message\api::get_conversations($user1->id, 4, 2);
849         $this->assertCount(2, $conversations);
850         $this->assertEquals($gc5->id, $conversations[0]->id);
851         $this->assertEmpty($conversations[0]->messages);
852         $this->assertEquals($gc4->id, $conversations[1]->id);
853         $this->assertEmpty($conversations[1]->messages);
855         // Ask for an offset that doesn't exist and verify no conversations are returned.
856         $conversations = \core_message\api::get_conversations($user1->id, 10, 1);
857         $this->assertCount(0, $conversations);
858     }
860     /**
861      * Test verifying the type filtering behaviour of the
862      */
863     public function test_get_conversations_type_filter() {
864         // Get a bunch of conversations, some group, some individual and in different states.
865         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
866             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
868         // Verify we can ask for only individual conversations.
869         $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
870             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
871         $this->assertCount(2, $conversations);
873         // Verify we can ask for only group conversations.
874         $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
875             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP);
876         $this->assertCount(4, $conversations);
878         // Verify an exception is thrown if an unrecognized type is specified.
879         $this->expectException(\moodle_exception::class);
880         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 0);
881     }
883     /**
884      * Tests retrieving conversations when a conversation contains a deleted user.
885      */
886     public function test_get_conversations_with_deleted_user() {
887         // Get a bunch of conversations, some group, some individual and in different states.
888         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
889             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
891         // Delete the second user and retrieve the conversations.
892         // We should have 5, as $ic1 drops off the list.
893         // Group conversations remain albeit with less members.
894         delete_user($user2);
895         $conversations = \core_message\api::get_conversations($user1->id);
896         $this->assertCount(5, $conversations);
897         $this->assertEquals($gc3->id, $conversations[0]->id);
898         $this->assertcount(1, $conversations[0]->members);
899         $this->assertEquals($gc2->id, $conversations[1]->id);
900         $this->assertcount(1, $conversations[1]->members);
901         $this->assertEquals($ic2->id, $conversations[2]->id);
902         $this->assertEquals($gc5->id, $conversations[3]->id);
903         $this->assertEquals($gc4->id, $conversations[4]->id);
905         // Delete a user from a group conversation where that user had sent the most recent message.
906         // This user will still be present in the members array, as will the message in the messages array.
907         delete_user($user4);
908         $conversations = \core_message\api::get_conversations($user1->id);
909         $this->assertCount(5, $conversations);
910         $this->assertEquals($gc2->id, $conversations[1]->id);
911         $this->assertcount(1, $conversations[1]->members);
912         $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
913         $this->assertcount(1, $conversations[1]->messages);
914         $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
916         // Delete the third user and retrieve the conversations.
917         // We should have 4, as $ic1, $ic2 drop off the list.
918         // Group conversations remain albeit with less members.
919         delete_user($user3);
920         $conversations = \core_message\api::get_conversations($user1->id);
921         $this->assertCount(4, $conversations);
922         $this->assertEquals($gc3->id, $conversations[0]->id);
923         $this->assertcount(1, $conversations[0]->members);
924         $this->assertEquals($gc2->id, $conversations[1]->id);
925         $this->assertcount(1, $conversations[1]->members);
926         $this->assertEquals($gc5->id, $conversations[2]->id);
927         $this->assertEquals($gc4->id, $conversations[3]->id);
928     }
930     /**
931      * Test confirming the behaviour of get_conversations() when users delete all messages.
932      */
933     public function test_get_conversations_deleted_messages() {
934         // Get a bunch of conversations, some group, some individual and in different states.
935         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
936             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
938         $conversations = \core_message\api::get_conversations($user1->id);
939         $this->assertCount(6, $conversations);
941         // Delete all messages from a group conversation the user is in - it should be returned.
942         $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $gc2->id));
943         $convmessages = \core_message\api::get_conversation_messages($user1->id, $gc2->id);
944         $messages = $convmessages['messages'];
945         foreach ($messages as $message) {
946             \core_message\api::delete_message($user1->id, $message->id);
947         }
948         $conversations = \core_message\api::get_conversations($user1->id);
949         $this->assertCount(6, $conversations);
950         $this->assertContains($gc2->id, array_column($conversations, 'id'));
952         // Delete all messages from an individual conversation the user is in - it should not be returned.
953         $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $ic1->id));
954         $convmessages = \core_message\api::get_conversation_messages($user1->id, $ic1->id);
955         $messages = $convmessages['messages'];
956         foreach ($messages as $message) {
957             \core_message\api::delete_message($user1->id, $message->id);
958         }
959         $conversations = \core_message\api::get_conversations($user1->id);
960         $this->assertCount(5, $conversations);
961         $this->assertNotContains($ic1->id, array_column($conversations, 'id'));
962     }
964     /**
965      * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
966      */
967     public function test_get_conversations_favourite_conversations() {
968         // Get a bunch of conversations, some group, some individual and in different states.
969         list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
970             $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
972         // Try to get ONLY favourite conversations, when no favourites exist.
973         $this->assertEquals([], \core_message\api::get_conversations($user1->id, 0, 20, null, true));
975         // Try to get NO favourite conversations, when no favourites exist.
976         $this->assertCount(6, \core_message\api::get_conversations($user1->id, 0, 20, null, false));
978         // Mark a few conversations as favourites.
979         \core_message\api::set_favourite_conversation($ic1->id, $user1->id);
980         \core_message\api::set_favourite_conversation($gc2->id, $user1->id);
981         \core_message\api::set_favourite_conversation($gc5->id, $user1->id);
983         // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
984         $conversations = \core_message\api::get_conversations($user1->id);
985         $this->assertCount(6, $conversations);
986         foreach ($conversations as $conv) {
987             if (in_array($conv->id, [$ic1->id, $gc2->id, $gc5->id])) {
988                 $this->assertTrue($conv->isfavourite);
989             }
990         }
992         // Now, get ONLY favourite conversations.
993         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
994         $this->assertCount(3, $conversations);
995         foreach ($conversations as $conv) {
996             $this->assertTrue($conv->isfavourite);
997         }
999         // Now, try ONLY favourites of type 'group'.
1000         $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1001             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1002         $this->assertCount(2, $conversations);
1003         foreach ($conversations as $conv) {
1004             $this->assertTrue($conv->isfavourite);
1005         }
1007         // And NO favourite conversations.
1008         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1009         $this->assertCount(3, $conversations);
1010         foreach ($conversations as $conv) {
1011             $this->assertFalse($conv->isfavourite);
1012         }
1013     }
1015     /**
1016      * Test verifying that group linked conversations are returned and contain a subname matching the course name.
1017      */
1018     public function test_get_conversations_group_linked() {
1019         // Create some users.
1020         $user1 = self::getDataGenerator()->create_user();
1021         $user2 = self::getDataGenerator()->create_user();
1022         $user3 = self::getDataGenerator()->create_user();
1024         $course1 = $this->getDataGenerator()->create_course();
1026         // Create a group with a linked conversation.
1027         $this->setAdminUser();
1028         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1029         $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1030         $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1031         $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
1033         // Add users to group1.
1034         $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1035         $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
1037         $conversations = \core_message\api::get_conversations($user1->id);
1038         $this->assertEquals($course1->shortname, $conversations[0]->subname);
1039     }
1041    /**
1042     * The data provider for get_conversations_mixed.
1043     *
1044     * This provides sets of data to for testing.
1045     * @return array
1046     */
1047    public function get_conversations_mixed_provider() {
1048        return array(
1049             'Test that conversations with messages contacts is correctly ordered.' => array(
1050                 'users' => array(
1051                     'user1',
1052                     'user2',
1053                     'user3',
1054                 ),
1055                 'contacts' => array(
1056                 ),
1057                 'messages' => array(
1058                     array(
1059                         'from'          => 'user1',
1060                         'to'            => 'user2',
1061                         'state'         => 'unread',
1062                         'subject'       => 'S1',
1063                     ),
1064                     array(
1065                         'from'          => 'user2',
1066                         'to'            => 'user1',
1067                         'state'         => 'unread',
1068                         'subject'       => 'S2',
1069                     ),
1070                     array(
1071                         'from'          => 'user1',
1072                         'to'            => 'user2',
1073                         'state'         => 'unread',
1074                         'timecreated'   => 0,
1075                         'subject'       => 'S3',
1076                     ),
1077                     array(
1078                         'from'          => 'user1',
1079                         'to'            => 'user3',
1080                         'state'         => 'read',
1081                         'timemodifier'  => 1,
1082                         'subject'       => 'S4',
1083                     ),
1084                     array(
1085                         'from'          => 'user3',
1086                         'to'            => 'user1',
1087                         'state'         => 'read',
1088                         'timemodifier'  => 1,
1089                         'subject'       => 'S5',
1090                     ),
1091                     array(
1092                         'from'          => 'user1',
1093                         'to'            => 'user3',
1094                         'state'         => 'read',
1095                         'timecreated'   => 0,
1096                         'subject'       => 'S6',
1097                     ),
1098                 ),
1099                 'expectations' => array(
1100                     'user1' => array(
1101                         // User1 has conversed most recently with user3. The most recent message is M5.
1102                         array(
1103                             'messageposition'   => 0,
1104                             'with'              => 'user3',
1105                             'subject'           => 'S5',
1106                             'unreadcount'       => 0,
1107                         ),
1108                         // User1 has also conversed with user2. The most recent message is S2.
1109                         array(
1110                             'messageposition'   => 1,
1111                             'with'              => 'user2',
1112                             'subject'           => 'S2',
1113                             'unreadcount'       => 1,
1114                         ),
1115                     ),
1116                     'user2' => array(
1117                         // User2 has only conversed with user1. Their most recent shared message was S2.
1118                         array(
1119                             'messageposition'   => 0,
1120                             'with'              => 'user1',
1121                             'subject'           => 'S2',
1122                             'unreadcount'       => 2,
1123                         ),
1124                     ),
1125                     'user3' => array(
1126                         // User3 has only conversed with user1. Their most recent shared message was S5.
1127                         array(
1128                             'messageposition'   => 0,
1129                             'with'              => 'user1',
1130                             'subject'           => 'S5',
1131                             'unreadcount'       => 0,
1132                         ),
1133                     ),
1134                 ),
1135             ),
1136             'Test conversations with a single user, where some messages are read and some are not.' => array(
1137                 'users' => array(
1138                     'user1',
1139                     'user2',
1140                 ),
1141                 'contacts' => array(
1142                 ),
1143                 'messages' => array(
1144                     array(
1145                         'from'          => 'user1',
1146                         'to'            => 'user2',
1147                         'state'         => 'read',
1148                         'subject'       => 'S1',
1149                     ),
1150                     array(
1151                         'from'          => 'user2',
1152                         'to'            => 'user1',
1153                         'state'         => 'read',
1154                         'subject'       => 'S2',
1155                     ),
1156                     array(
1157                         'from'          => 'user1',
1158                         'to'            => 'user2',
1159                         'state'         => 'unread',
1160                         'timemodifier'  => 1,
1161                         'subject'       => 'S3',
1162                     ),
1163                     array(
1164                         'from'          => 'user1',
1165                         'to'            => 'user2',
1166                         'state'         => 'unread',
1167                         'timemodifier'  => 1,
1168                         'subject'       => 'S4',
1169                     ),
1170                 ),
1171                 'expectations' => array(
1172                     // The most recent message between user1 and user2 was S4.
1173                     'user1' => array(
1174                         array(
1175                             'messageposition'   => 0,
1176                             'with'              => 'user2',
1177                             'subject'           => 'S4',
1178                             'unreadcount'       => 0,
1179                         ),
1180                     ),
1181                     'user2' => array(
1182                         // The most recent message between user1 and user2 was S4.
1183                         array(
1184                             'messageposition'   => 0,
1185                             'with'              => 'user1',
1186                             'subject'           => 'S4',
1187                             'unreadcount'       => 2,
1188                         ),
1189                     ),
1190                 ),
1191             ),
1192             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1193             'are out of order' => array(
1194             // This can happen through a combination of factors including multi-master DB replication with messages
1195             // read somehow (e.g. API).
1196                 'users' => array(
1197                     'user1',
1198                     'user2',
1199                 ),
1200                 'contacts' => array(
1201                 ),
1202                 'messages' => array(
1203                     array(
1204                         'from'          => 'user1',
1205                         'to'            => 'user2',
1206                         'state'         => 'read',
1207                         'subject'       => 'S1',
1208                         'timemodifier'  => 1,
1209                     ),
1210                     array(
1211                         'from'          => 'user2',
1212                         'to'            => 'user1',
1213                         'state'         => 'read',
1214                         'subject'       => 'S2',
1215                         'timemodifier'  => 2,
1216                     ),
1217                     array(
1218                         'from'          => 'user1',
1219                         'to'            => 'user2',
1220                         'state'         => 'unread',
1221                         'subject'       => 'S3',
1222                     ),
1223                     array(
1224                         'from'          => 'user1',
1225                         'to'            => 'user2',
1226                         'state'         => 'unread',
1227                         'subject'       => 'S4',
1228                     ),
1229                 ),
1230                 'expectations' => array(
1231                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1232                     'user1' => array(
1233                         array(
1234                             'messageposition'   => 0,
1235                             'with'              => 'user2',
1236                             'subject'           => 'S2',
1237                             'unreadcount'       => 0,
1238                         ),
1239                     ),
1240                     'user2' => array(
1241                         array(
1242                             'messageposition'   => 0,
1243                             'with'              => 'user1',
1244                             'subject'           => 'S2',
1245                             'unreadcount'       => 2
1246                         ),
1247                     ),
1248                 ),
1249             ),
1250             'Test unread message count is correct for both users' => array(
1251                 'users' => array(
1252                     'user1',
1253                     'user2',
1254                 ),
1255                 'contacts' => array(
1256                 ),
1257                 'messages' => array(
1258                     array(
1259                         'from'          => 'user1',
1260                         'to'            => 'user2',
1261                         'state'         => 'read',
1262                         'subject'       => 'S1',
1263                         'timemodifier'  => 1,
1264                     ),
1265                     array(
1266                         'from'          => 'user2',
1267                         'to'            => 'user1',
1268                         'state'         => 'read',
1269                         'subject'       => 'S2',
1270                         'timemodifier'  => 2,
1271                     ),
1272                     array(
1273                         'from'          => 'user1',
1274                         'to'            => 'user2',
1275                         'state'         => 'read',
1276                         'subject'       => 'S3',
1277                         'timemodifier'  => 3,
1278                     ),
1279                     array(
1280                         'from'          => 'user1',
1281                         'to'            => 'user2',
1282                         'state'         => 'read',
1283                         'subject'       => 'S4',
1284                         'timemodifier'  => 4,
1285                     ),
1286                     array(
1287                         'from'          => 'user1',
1288                         'to'            => 'user2',
1289                         'state'         => 'unread',
1290                         'subject'       => 'S5',
1291                         'timemodifier'  => 5,
1292                     ),
1293                     array(
1294                         'from'          => 'user2',
1295                         'to'            => 'user1',
1296                         'state'         => 'unread',
1297                         'subject'       => 'S6',
1298                         'timemodifier'  => 6,
1299                     ),
1300                     array(
1301                         'from'          => 'user1',
1302                         'to'            => 'user2',
1303                         'state'         => 'unread',
1304                         'subject'       => 'S7',
1305                         'timemodifier'  => 7,
1306                     ),
1307                     array(
1308                         'from'          => 'user1',
1309                         'to'            => 'user2',
1310                         'state'         => 'unread',
1311                         'subject'       => 'S8',
1312                         'timemodifier'  => 8,
1313                     ),
1314                 ),
1315                 'expectations' => array(
1316                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1317                     'user1' => array(
1318                         array(
1319                             'messageposition'   => 0,
1320                             'with'              => 'user2',
1321                             'subject'           => 'S8',
1322                             'unreadcount'       => 1,
1323                         ),
1324                     ),
1325                     'user2' => array(
1326                         array(
1327                             'messageposition'   => 0,
1328                             'with'              => 'user1',
1329                             'subject'           => 'S8',
1330                             'unreadcount'       => 3,
1331                         ),
1332                     ),
1333                 ),
1334             ),
1335         );
1336     }
1338     /**
1339      * Test get_conversations with a mixture of messages.
1340      *
1341      * @dataProvider get_conversations_mixed_provider
1342      * @param array $usersdata The list of users to create for this test.
1343      * @param array $messagesdata The list of messages to create.
1344      * @param array $expectations The list of expected outcomes.
1345      */
1346     public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1347         global $DB;
1349         // Create all of the users.
1350         $users = array();
1351         foreach ($usersdata as $username) {
1352             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1353         }
1355         foreach ($contacts as $username => $contact) {
1356             foreach ($contact as $contactname => $blocked) {
1357                 $record = new stdClass();
1358                 $record->userid     = $users[$username]->id;
1359                 $record->contactid  = $users[$contactname]->id;
1360                 $record->blocked    = $blocked;
1361                 $record->id = $DB->insert_record('message_contacts', $record);
1362             }
1363         }
1365         $defaulttimecreated = time();
1366         foreach ($messagesdata as $messagedata) {
1367             $from       = $users[$messagedata['from']];
1368             $to         = $users[$messagedata['to']];
1369             $subject    = $messagedata['subject'];
1371             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
1372                 $messageid = $this->send_fake_message($from, $to, $subject);
1373             } else {
1374                 // If there is no state, or the state is not 'unread', assume the message is read.
1375                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
1376             }
1378             $updatemessage = new stdClass();
1379             $updatemessage->id = $messageid;
1380             if (isset($messagedata['timecreated'])) {
1381                 $updatemessage->timecreated = $messagedata['timecreated'];
1382             } else if (isset($messagedata['timemodifier'])) {
1383                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
1384             } else {
1385                 $updatemessage->timecreated = $defaulttimecreated;
1386             }
1388             $DB->update_record('messages', $updatemessage);
1389         }
1391         foreach ($expectations as $username => $data) {
1392             // Get the recent conversations for the specified user.
1393             $user = $users[$username];
1394             $conversations = array_values(\core_message\api::get_conversations($user->id));
1395             foreach ($data as $expectation) {
1396                 $otheruser = $users[$expectation['with']];
1397                 $conversation = $conversations[$expectation['messageposition']];
1398                 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
1399                 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
1400                 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
1401             }
1402         }
1403     }
1405     /**
1406      * Tests retrieving contacts.
1407      */
1408     public function test_get_contacts() {
1409         // Create some users.
1410         $user1 = self::getDataGenerator()->create_user();
1412         // Set as the user.
1413         $this->setUser($user1);
1415         $user2 = new stdClass();
1416         $user2->firstname = 'User';
1417         $user2->lastname = 'A';
1418         $user2 = self::getDataGenerator()->create_user($user2);
1420         $user3 = new stdClass();
1421         $user3->firstname = 'User';
1422         $user3->lastname = 'B';
1423         $user3 = self::getDataGenerator()->create_user($user3);
1425         $user4 = new stdClass();
1426         $user4->firstname = 'User';
1427         $user4->lastname = 'C';
1428         $user4 = self::getDataGenerator()->create_user($user4);
1430         $user5 = new stdClass();
1431         $user5->firstname = 'User';
1432         $user5->lastname = 'D';
1433         $user5 = self::getDataGenerator()->create_user($user5);
1435         // Add some users as contacts.
1436         \core_message\api::add_contact($user1->id, $user2->id);
1437         \core_message\api::add_contact($user1->id, $user3->id);
1438         \core_message\api::add_contact($user1->id, $user4->id);
1440         // Retrieve the contacts.
1441         $contacts = \core_message\api::get_contacts($user1->id);
1443         // Confirm the data is correct.
1444         $this->assertEquals(3, count($contacts));
1445         usort($contacts, ['static', 'sort_contacts']);
1447         $contact1 = $contacts[0];
1448         $contact2 = $contacts[1];
1449         $contact3 = $contacts[2];
1451         $this->assertEquals($user2->id, $contact1->userid);
1452         $this->assertEmpty($contact1->useridfrom);
1453         $this->assertFalse($contact1->ismessaging);
1454         $this->assertNull($contact1->lastmessage);
1455         $this->assertNull($contact1->messageid);
1456         $this->assertNull($contact1->isonline);
1457         $this->assertFalse($contact1->isread);
1458         $this->assertFalse($contact1->isblocked);
1459         $this->assertNull($contact1->unreadcount);
1461         $this->assertEquals($user3->id, $contact2->userid);
1462         $this->assertEmpty($contact2->useridfrom);
1463         $this->assertFalse($contact2->ismessaging);
1464         $this->assertNull($contact2->lastmessage);
1465         $this->assertNull($contact2->messageid);
1466         $this->assertNull($contact2->isonline);
1467         $this->assertFalse($contact2->isread);
1468         $this->assertFalse($contact2->isblocked);
1469         $this->assertNull($contact2->unreadcount);
1471         $this->assertEquals($user4->id, $contact3->userid);
1472         $this->assertEmpty($contact3->useridfrom);
1473         $this->assertFalse($contact3->ismessaging);
1474         $this->assertNull($contact3->lastmessage);
1475         $this->assertNull($contact3->messageid);
1476         $this->assertNull($contact3->isonline);
1477         $this->assertFalse($contact3->isread);
1478         $this->assertFalse($contact3->isblocked);
1479         $this->assertNull($contact3->unreadcount);
1480     }
1482     /**
1483      * Tests retrieving messages.
1484      */
1485     public function test_get_messages() {
1486         // Create some users.
1487         $user1 = self::getDataGenerator()->create_user();
1488         $user2 = self::getDataGenerator()->create_user();
1490         // The person doing the search.
1491         $this->setUser($user1);
1493         // Send some messages back and forth.
1494         $time = 1;
1495         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1496         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1497         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1498         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1500         // Retrieve the messages.
1501         $messages = \core_message\api::get_messages($user1->id, $user2->id);
1502         $this->assertDebuggingCalledCount(3);
1504         // Confirm the message data is correct.
1505         $this->assertEquals(4, count($messages));
1507         $message1 = $messages[0];
1508         $message2 = $messages[1];
1509         $message3 = $messages[2];
1510         $message4 = $messages[3];
1512         $this->assertEquals($user1->id, $message1->useridfrom);
1513         $this->assertEquals($user2->id, $message1->useridto);
1514         $this->assertTrue($message1->displayblocktime);
1515         $this->assertContains('Yo!', $message1->text);
1517         $this->assertEquals($user2->id, $message2->useridfrom);
1518         $this->assertEquals($user1->id, $message2->useridto);
1519         $this->assertFalse($message2->displayblocktime);
1520         $this->assertContains('Sup mang?', $message2->text);
1522         $this->assertEquals($user1->id, $message3->useridfrom);
1523         $this->assertEquals($user2->id, $message3->useridto);
1524         $this->assertFalse($message3->displayblocktime);
1525         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1527         $this->assertEquals($user2->id, $message4->useridfrom);
1528         $this->assertEquals($user1->id, $message4->useridto);
1529         $this->assertFalse($message4->displayblocktime);
1530         $this->assertContains('Word.', $message4->text);
1531     }
1533     /**
1534      * Tests retrieving conversation messages.
1535      */
1536     public function test_get_conversation_messages() {
1537         // Create some users.
1538         $user1 = self::getDataGenerator()->create_user();
1539         $user2 = self::getDataGenerator()->create_user();
1541         // Create conversation.
1542         $conversation = \core_message\api::create_conversation(
1543             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1544             [$user1->id, $user2->id]
1545         );
1547         // The person doing the search.
1548         $this->setUser($user1);
1550         // Send some messages back and forth.
1551         $time = 1;
1552         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1553         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1554         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1555         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1557         // Retrieve the messages.
1558         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1560         // Confirm the conversation id is correct.
1561         $this->assertEquals($conversation->id, $convmessages['id']);
1563         // Confirm the message data is correct.
1564         $messages = $convmessages['messages'];
1565         $this->assertEquals(4, count($messages));
1566         $message1 = $messages[0];
1567         $message2 = $messages[1];
1568         $message3 = $messages[2];
1569         $message4 = $messages[3];
1571         $this->assertEquals($user1->id, $message1->useridfrom);
1572         $this->assertContains('Yo!', $message1->text);
1574         $this->assertEquals($user2->id, $message2->useridfrom);
1575         $this->assertContains('Sup mang?', $message2->text);
1577         $this->assertEquals($user1->id, $message3->useridfrom);
1578         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1580         $this->assertEquals($user1->id, $message4->useridfrom);
1581         $this->assertContains('Word.', $message4->text);
1583         // Confirm the members data is correct.
1584         $members = $convmessages['members'];
1585         $this->assertEquals(2, count($members));
1586     }
1588     /**
1589      * Tests retrieving group conversation messages.
1590      */
1591     public function test_get_group_conversation_messages() {
1592         // Create some users.
1593         $user1 = self::getDataGenerator()->create_user();
1594         $user2 = self::getDataGenerator()->create_user();
1595         $user3 = self::getDataGenerator()->create_user();
1596         $user4 = self::getDataGenerator()->create_user();
1598         // Create group conversation.
1599         $conversation = \core_message\api::create_conversation(
1600             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1601             [$user1->id, $user2->id, $user3->id, $user4->id]
1602         );
1604         // The person doing the search.
1605         $this->setUser($user1);
1607         // Send some messages back and forth.
1608         $time = 1;
1609         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1610         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1611         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1612         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1613         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
1615         // Retrieve the messages.
1616         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1618         // Confirm the conversation id is correct.
1619         $this->assertEquals($conversation->id, $convmessages['id']);
1621         // Confirm the message data is correct.
1622         $messages = $convmessages['messages'];
1623         $this->assertEquals(5, count($messages));
1625         $message1 = $messages[0];
1626         $message2 = $messages[1];
1627         $message3 = $messages[2];
1628         $message4 = $messages[3];
1629         $message5 = $messages[4];
1631         $this->assertEquals($user1->id, $message1->useridfrom);
1632         $this->assertContains('Yo!', $message1->text);
1634         $this->assertEquals($user2->id, $message2->useridfrom);
1635         $this->assertContains('Sup mang?', $message2->text);
1637         $this->assertEquals($user3->id, $message3->useridfrom);
1638         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1640         $this->assertEquals($user1->id, $message4->useridfrom);
1641         $this->assertContains('Word.', $message4->text);
1643         $this->assertEquals($user2->id, $message5->useridfrom);
1644         $this->assertContains('Yeah!', $message5->text);
1646         // Confirm the members data is correct.
1647         $members = $convmessages['members'];
1648         $this->assertEquals(3, count($members));
1649     }
1651     /**
1652      * Test verifying the sorting param for get_conversation_messages is respected().
1653      */
1654     public function test_get_conversation_messages_sorting() {
1655         // Create some users.
1656         $user1 = self::getDataGenerator()->create_user();
1657         $user2 = self::getDataGenerator()->create_user();
1658         $user3 = self::getDataGenerator()->create_user();
1660         // Create conversations - 1 group and 1 individual.
1661         $conversation = \core_message\api::create_conversation(
1662             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1663             [$user1->id, $user2->id]
1664         );
1665         $conversation2 = \core_message\api::create_conversation(
1666             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1667             [$user1->id, $user2->id, $user3->id]
1668         );
1670         // Send some messages back and forth.
1671         $time = 1;
1672         $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
1673         $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
1674         $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
1675         $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
1677         $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
1678         $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
1679         $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
1680         $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
1682         // The person doing the search.
1683         $this->setUser($user1);
1685         // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
1686         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
1687         $messages = $convmessages['messages'];
1688         $this->assertEquals($m1id, $messages[0]->id);
1689         $this->assertEquals($m2id, $messages[1]->id);
1690         $this->assertEquals($m3id, $messages[2]->id);
1691         $this->assertEquals($m4id, $messages[3]->id);
1693         // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
1694         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
1695         $messages = $convmessages['messages'];
1696         $this->assertEquals($m1id, $messages[3]->id);
1697         $this->assertEquals($m2id, $messages[2]->id);
1698         $this->assertEquals($m3id, $messages[1]->id);
1699         $this->assertEquals($m4id, $messages[0]->id);
1701         // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
1702         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
1703         $messages = $convmessages['messages'];
1704         $this->assertEquals($gm1id, $messages[0]->id);
1705         $this->assertEquals($gm2id, $messages[1]->id);
1706         $this->assertEquals($gm3id, $messages[2]->id);
1707         $this->assertEquals($gm4id, $messages[3]->id);
1709         // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
1710         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
1711         $messages = $convmessages['messages'];
1712         $this->assertEquals($gm1id, $messages[3]->id);
1713         $this->assertEquals($gm2id, $messages[2]->id);
1714         $this->assertEquals($gm3id, $messages[1]->id);
1715         $this->assertEquals($gm4id, $messages[0]->id);
1716     }
1718     /**
1719      * Test retrieving conversation messages by providing a minimum timecreated value.
1720      */
1721     public function test_get_conversation_messages_time_from_only() {
1722         // Create some users.
1723         $user1 = self::getDataGenerator()->create_user();
1724         $user2 = self::getDataGenerator()->create_user();
1725         $user3 = self::getDataGenerator()->create_user();
1726         $user4 = self::getDataGenerator()->create_user();
1728         // Create group conversation.
1729         $conversation = \core_message\api::create_conversation(
1730             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1731             [$user1->id, $user2->id, $user3->id, $user4->id]
1732         );
1734         // The person doing the search.
1735         $this->setUser($user1);
1737         // Send some messages back and forth.
1738         $time = 1;
1739         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1740         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1741         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1742         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1744         // Retrieve the messages from $time, which should be all of them.
1745         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
1747         // Confirm the conversation id is correct.
1748         $this->assertEquals($conversation->id, $convmessages['id']);
1750         // Confirm the message data is correct.
1751         $messages = $convmessages['messages'];
1752         $this->assertEquals(4, count($messages));
1754         $message1 = $messages[0];
1755         $message2 = $messages[1];
1756         $message3 = $messages[2];
1757         $message4 = $messages[3];
1759         $this->assertContains('Message 1', $message1->text);
1760         $this->assertContains('Message 2', $message2->text);
1761         $this->assertContains('Message 3', $message3->text);
1762         $this->assertContains('Message 4', $message4->text);
1764         // Confirm the members data is correct.
1765         $members = $convmessages['members'];
1766         $this->assertEquals(3, count($members));
1768         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1769         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1770             'timecreated ASC', $time + 3);
1772         // Confirm the conversation id is correct.
1773         $this->assertEquals($conversation->id, $convmessages['id']);
1775         // Confirm the message data is correct.
1776         $messages = $convmessages['messages'];
1777         $this->assertEquals(2, count($messages));
1779         $message1 = $messages[0];
1780         $message2 = $messages[1];
1782         $this->assertContains('Message 3', $message1->text);
1783         $this->assertContains('Message 4', $message2->text);
1785         // Confirm the members data is correct.
1786         $members = $convmessages['members'];
1787         $this->assertEquals(2, count($members));
1788     }
1790     /**
1791      * Test retrieving conversation messages by providing a maximum timecreated value.
1792      */
1793     public function test_get_conversation_messages_time_to_only() {
1794         // Create some users.
1795         $user1 = self::getDataGenerator()->create_user();
1796         $user2 = self::getDataGenerator()->create_user();
1797         $user3 = self::getDataGenerator()->create_user();
1798         $user4 = self::getDataGenerator()->create_user();
1800         // Create group conversation.
1801         $conversation = \core_message\api::create_conversation(
1802             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1803             [$user1->id, $user2->id, $user3->id, $user4->id]
1804         );
1806         // The person doing the search.
1807         $this->setUser($user1);
1809         // Send some messages back and forth.
1810         $time = 1;
1811         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1812         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1813         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1814         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1816         // Retrieve the messages up until $time + 4, which should be all of them.
1817         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1818             0, $time + 4);
1820         // Confirm the conversation id is correct.
1821         $this->assertEquals($conversation->id, $convmessages['id']);
1823         // Confirm the message data is correct.
1824         $messages = $convmessages['messages'];
1825         $this->assertEquals(4, count($messages));
1827         $message1 = $messages[0];
1828         $message2 = $messages[1];
1829         $message3 = $messages[2];
1830         $message4 = $messages[3];
1832         $this->assertContains('Message 1', $message1->text);
1833         $this->assertContains('Message 2', $message2->text);
1834         $this->assertContains('Message 3', $message3->text);
1835         $this->assertContains('Message 4', $message4->text);
1837         // Confirm the members data is correct.
1838         $members = $convmessages['members'];
1839         $this->assertEquals(3, count($members));
1841         // Retrieve the messages up until $time + 2, which should be the first two.
1842         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
1843             0, $time + 2);
1845         // Confirm the conversation id is correct.
1846         $this->assertEquals($conversation->id, $convmessages['id']);
1848         // Confirm the message data is correct.
1849         $messages = $convmessages['messages'];
1850         $this->assertEquals(2, count($messages));
1852         $message1 = $messages[0];
1853         $message2 = $messages[1];
1855         $this->assertContains('Message 1', $message1->text);
1856         $this->assertContains('Message 2', $message2->text);
1858         // Confirm the members data is correct.
1859         $members = $convmessages['members'];
1860         $this->assertEquals(2, count($members));
1861     }
1863     /**
1864      * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
1865      */
1866     public function test_get_conversation_messages_time_from_and_to() {
1867         // Create some users.
1868         $user1 = self::getDataGenerator()->create_user();
1869         $user2 = self::getDataGenerator()->create_user();
1870         $user3 = self::getDataGenerator()->create_user();
1871         $user4 = self::getDataGenerator()->create_user();
1873         // Create group conversation.
1874         $conversation = \core_message\api::create_conversation(
1875             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1876             [$user1->id, $user2->id, $user3->id, $user4->id]
1877         );
1879         // The person doing the search.
1880         $this->setUser($user1);
1882         // Send some messages back and forth.
1883         $time = 1;
1884         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1885         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1886         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1887         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1889         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1890         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
1891             'timecreated ASC', $time + 2, $time + 3);
1893         // Confirm the conversation id is correct.
1894         $this->assertEquals($conversation->id, $convmessages['id']);
1896         // Confirm the message data is correct.
1897         $messages = $convmessages['messages'];
1898         $this->assertEquals(2, count($messages));
1900         $message1 = $messages[0];
1901         $message2 = $messages[1];
1903         $this->assertContains('Message 2', $message1->text);
1904         $this->assertContains('Message 3', $message2->text);
1906         // Confirm the members data is correct.
1907         $members = $convmessages['members'];
1908         $this->assertEquals(2, count($members));
1909     }
1912     /**
1913      * Test retrieving conversation messages by providing a limitfrom value.
1914      */
1915     public function test_get_conversation_messages_limitfrom_only() {
1916         // Create some users.
1917         $user1 = self::getDataGenerator()->create_user();
1918         $user2 = self::getDataGenerator()->create_user();
1919         $user3 = self::getDataGenerator()->create_user();
1920         $user4 = self::getDataGenerator()->create_user();
1922         // Create group conversation.
1923         $conversation = \core_message\api::create_conversation(
1924             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1925             [$user1->id, $user2->id, $user3->id, $user4->id]
1926         );
1928         // The person doing the search.
1929         $this->setUser($user1);
1931         // Send some messages back and forth.
1932         $time = 1;
1933         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1934         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1935         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1936         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1938         // Retrieve the messages from $time, which should be all of them.
1939         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
1941         // Confirm the conversation id is correct.
1942         $messages = $convmessages['messages'];
1943         $this->assertEquals($conversation->id, $convmessages['id']);
1945         // Confirm the message data is correct.
1946         $this->assertEquals(2, count($messages));
1948         $message1 = $messages[0];
1949         $message2 = $messages[1];
1951         $this->assertContains('Message 3', $message1->text);
1952         $this->assertContains('Message 4', $message2->text);
1954         // Confirm the members data is correct.
1955         $members = $convmessages['members'];
1956         $this->assertEquals(2, count($members));
1957     }
1959     /**
1960      * Test retrieving conversation messages by providing a limitnum value.
1961      */
1962     public function test_get_conversation_messages_limitnum() {
1963         // Create some users.
1964         $user1 = self::getDataGenerator()->create_user();
1965         $user2 = self::getDataGenerator()->create_user();
1966         $user3 = self::getDataGenerator()->create_user();
1967         $user4 = self::getDataGenerator()->create_user();
1969         // Create group conversation.
1970         $conversation = \core_message\api::create_conversation(
1971             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1972             [$user1->id, $user2->id, $user3->id, $user4->id]
1973         );
1975         // The person doing the search.
1976         $this->setUser($user1);
1978         // Send some messages back and forth.
1979         $time = 1;
1980         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
1981         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
1982         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
1983         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
1985         // Retrieve the messages from $time, which should be all of them.
1986         $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
1988         // Confirm the conversation id is correct.
1989         $messages = $convmessages['messages'];
1990         $this->assertEquals($conversation->id, $convmessages['id']);
1992         // Confirm the message data is correct.
1993         $messages = $convmessages['messages'];
1994         $this->assertEquals(1, count($messages));
1996         $message1 = $messages[0];
1998         $this->assertContains('Message 3', $message1->text);
2000         // Confirm the members data is correct.
2001         $members = $convmessages['members'];
2002         $this->assertEquals(1, count($members));
2003     }
2005     /**
2006      * Tests retrieving most recent message.
2007      */
2008     public function test_get_most_recent_message() {
2009         // Create some users.
2010         $user1 = self::getDataGenerator()->create_user();
2011         $user2 = self::getDataGenerator()->create_user();
2013         // The person doing the search.
2014         $this->setUser($user1);
2016         // Send some messages back and forth.
2017         $time = 1;
2018         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2019         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2020         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2021         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2023         // Retrieve the most recent messages.
2024         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
2025         $this->assertDebuggingCalledCount(3);
2027         // Check the results are correct.
2028         $this->assertEquals($user2->id, $message->useridfrom);
2029         $this->assertEquals($user1->id, $message->useridto);
2030         $this->assertContains('Word.', $message->text);
2031     }
2033     /**
2034      * Tests retrieving most recent conversation message.
2035      */
2036     public function test_get_most_recent_conversation_message() {
2037         // Create some users.
2038         $user1 = self::getDataGenerator()->create_user();
2039         $user2 = self::getDataGenerator()->create_user();
2040         $user3 = self::getDataGenerator()->create_user();
2042         // Create group conversation.
2043         $conversation = \core_message\api::create_conversation(
2044             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2045             [$user1->id, $user2->id, $user3->id]
2046         );
2048         // The person getting the most recent conversation message.
2049         $this->setUser($user1);
2051         // Send some messages back and forth.
2052         $time = 1;
2053         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2054         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2055         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2056         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2058         // Retrieve the most recent messages.
2059         $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
2061         // Check the results are correct.
2062         $this->assertEquals($user2->id, $message->useridfrom);
2063         $this->assertContains('Word.', $message->text);
2064     }
2066     /**
2067      * Tests retrieving a user's profile.
2068      */
2069     public function test_get_profile() {
2070         // Create some users.
2071         $user1 = self::getDataGenerator()->create_user();
2073         $user2 = new stdClass();
2074         $user2->country = 'AU';
2075         $user2->city = 'Perth';
2076         $user2 = self::getDataGenerator()->create_user($user2);
2078         // The person doing the search.
2079         $this->setUser($user1);
2081         // Get the profile.
2082         $profile = \core_message\api::get_profile($user1->id, $user2->id);
2084         $this->assertEquals($user2->id, $profile->userid);
2085         $this->assertEmpty($profile->email);
2086         $this->assertEmpty($profile->country);
2087         $this->assertEmpty($profile->city);
2088         $this->assertEquals(fullname($user2), $profile->fullname);
2089         $this->assertNull($profile->isonline);
2090         $this->assertFalse($profile->isblocked);
2091         $this->assertFalse($profile->iscontact);
2092     }
2094     /**
2095      * Tests retrieving a user's profile.
2096      */
2097     public function test_get_profile_as_admin() {
2098         // The person doing the search.
2099         $this->setAdminUser();
2101         // Create some users.
2102         $user1 = self::getDataGenerator()->create_user();
2104         $user2 = new stdClass();
2105         $user2->country = 'AU';
2106         $user2->city = 'Perth';
2107         $user2 = self::getDataGenerator()->create_user($user2);
2109         // Get the profile.
2110         $profile = \core_message\api::get_profile($user1->id, $user2->id);
2112         $this->assertEquals($user2->id, $profile->userid);
2113         $this->assertEquals($user2->email, $profile->email);
2114         $this->assertEquals($user2->country, $profile->country);
2115         $this->assertEquals($user2->city, $profile->city);
2116         $this->assertEquals(fullname($user2), $profile->fullname);
2117         $this->assertFalse($profile->isonline);
2118         $this->assertFalse($profile->isblocked);
2119         $this->assertFalse($profile->iscontact);
2120     }
2122     /**
2123      * Tests checking if a user can mark all messages as read.
2124      */
2125     public function test_can_mark_all_messages_as_read() {
2126         // Set as the admin.
2127         $this->setAdminUser();
2129         // Create some users.
2130         $user1 = self::getDataGenerator()->create_user();
2131         $user2 = self::getDataGenerator()->create_user();
2132         $user3 = self::getDataGenerator()->create_user();
2134         // Send some messages back and forth.
2135         $time = 1;
2136         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2137         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2138         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2139         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2141         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2143         // The admin can do anything.
2144         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2146         // Set as the user 1.
2147         $this->setUser($user1);
2149         // The user can mark the messages as he is in the conversation.
2150         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2152         // User 1 can not mark the messages read for user 2.
2153         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
2155         // This user is not a part of the conversation.
2156         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
2157     }
2159     /**
2160      * Tests checking if a user can delete a conversation.
2161      */
2162     public function test_can_delete_conversation() {
2163         // Set as the admin.
2164         $this->setAdminUser();
2166         // Create some users.
2167         $user1 = self::getDataGenerator()->create_user();
2168         $user2 = self::getDataGenerator()->create_user();
2170         // Send some messages back and forth.
2171         $time = 1;
2172         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2173         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2174         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2175         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2177         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2179         // The admin can do anything.
2180         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2182         // Set as the user 1.
2183         $this->setUser($user1);
2185         // They can delete their own messages.
2186         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
2188         // They can't delete someone elses.
2189         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
2190     }
2192     /**
2193      * Tests deleting a conversation.
2194      */
2195     public function test_delete_conversation() {
2196         global $DB;
2198         // Create some users.
2199         $user1 = self::getDataGenerator()->create_user();
2200         $user2 = self::getDataGenerator()->create_user();
2202         // The person doing the search.
2203         $this->setUser($user1);
2205         // Send some messages back and forth.
2206         $time = 1;
2207         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2208         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2209         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2210         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2212         // Delete the conversation as user 1.
2213         \core_message\api::delete_conversation($user1->id, $user2->id);
2214         $this->assertDebuggingCalled();
2216         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2217         $this->assertCount(4, $muas);
2218         // Sort by id.
2219         ksort($muas);
2221         $mua1 = array_shift($muas);
2222         $mua2 = array_shift($muas);
2223         $mua3 = array_shift($muas);
2224         $mua4 = array_shift($muas);
2226         $this->assertEquals($user1->id, $mua1->userid);
2227         $this->assertEquals($m1id, $mua1->messageid);
2228         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2230         $this->assertEquals($user1->id, $mua2->userid);
2231         $this->assertEquals($m2id, $mua2->messageid);
2232         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2234         $this->assertEquals($user1->id, $mua3->userid);
2235         $this->assertEquals($m3id, $mua3->messageid);
2236         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2238         $this->assertEquals($user1->id, $mua4->userid);
2239         $this->assertEquals($m4id, $mua4->messageid);
2240         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2241     }
2243     /**
2244      * Tests deleting a conversation by conversation id.
2245      */
2246     public function test_delete_conversation_by_id() {
2247         global $DB;
2249         // Create some users.
2250         $user1 = self::getDataGenerator()->create_user();
2251         $user2 = self::getDataGenerator()->create_user();
2253         // The person doing the search.
2254         $this->setUser($user1);
2256         // Send some messages back and forth.
2257         $time = 1;
2258         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2259         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2260         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2261         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2263         // Delete the conversation as user 1.
2264         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2265         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
2267         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2268         $this->assertCount(4, $muas);
2269         // Sort by id.
2270         ksort($muas);
2272         $mua1 = array_shift($muas);
2273         $mua2 = array_shift($muas);
2274         $mua3 = array_shift($muas);
2275         $mua4 = array_shift($muas);
2277         $this->assertEquals($user1->id, $mua1->userid);
2278         $this->assertEquals($m1id, $mua1->messageid);
2279         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2281         $this->assertEquals($user1->id, $mua2->userid);
2282         $this->assertEquals($m2id, $mua2->messageid);
2283         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2285         $this->assertEquals($user1->id, $mua3->userid);
2286         $this->assertEquals($m3id, $mua3->messageid);
2287         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2289         $this->assertEquals($user1->id, $mua4->userid);
2290         $this->assertEquals($m4id, $mua4->messageid);
2291         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2292     }
2294     /**
2295      * Tests counting unread conversations.
2296      */
2297     public function test_count_unread_conversations() {
2298         $this->resetAfterTest(true);
2300         // Create some users.
2301         $user1 = self::getDataGenerator()->create_user();
2302         $user2 = self::getDataGenerator()->create_user();
2303         $user3 = self::getDataGenerator()->create_user();
2304         $user4 = self::getDataGenerator()->create_user();
2306         // The person wanting the conversation count.
2307         $this->setUser($user1);
2309         // Send some messages back and forth, have some different conversations with different users.
2310         $this->send_fake_message($user1, $user2, 'Yo!');
2311         $this->send_fake_message($user2, $user1, 'Sup mang?');
2312         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2313         $this->send_fake_message($user2, $user1, 'Word.');
2315         $this->send_fake_message($user1, $user3, 'Booyah');
2316         $this->send_fake_message($user3, $user1, 'Whaaat?');
2317         $this->send_fake_message($user1, $user3, 'Nothing.');
2318         $this->send_fake_message($user3, $user1, 'Cool.');
2320         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2321         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2322         $this->send_fake_message($user1, $user4, 'Dope.');
2324         // Check the amount for the current user.
2325         $this->assertEquals(3, core_message\api::count_unread_conversations());
2327         // Check the amount for the second user.
2328         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2329     }
2331     /**
2332      * Tests deleting a conversation.
2333      */
2334     public function test_get_all_message_preferences() {
2335         $user = self::getDataGenerator()->create_user();
2336         $this->setUser($user);
2338         // Set a couple of preferences to test.
2339         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2340         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2342         $processors = get_message_processors();
2343         $providers = message_get_providers_for_user($user->id);
2344         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2346         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2347         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2348     }
2350     /**
2351      * Tests the user can post a message.
2352      */
2353     public function test_can_post_message() {
2354         // Create some users.
2355         $user1 = self::getDataGenerator()->create_user();
2356         $user2 = self::getDataGenerator()->create_user();
2358         // Set as the first user.
2359         $this->setUser($user1);
2361         // With the default privacy setting, users can't message them.
2362         $this->assertFalse(\core_message\api::can_post_message($user2));
2364         // Enrol users to the same course.
2365         $course = $this->getDataGenerator()->create_course();
2366         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2367         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2368         // After enrolling users to the course, they should be able to message them with the default privacy setting.
2369         $this->assertTrue(\core_message\api::can_post_message($user2));
2370     }
2372     /**
2373      * Tests the user can't post a message without proper capability.
2374      */
2375     public function test_can_post_message_without_sendmessage_cap() {
2376         global $DB;
2378         // Create some users.
2379         $user1 = self::getDataGenerator()->create_user();
2380         $user2 = self::getDataGenerator()->create_user();
2382         // Set as the user 1.
2383         $this->setUser($user1);
2385         // Remove the capability to send a message.
2386         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
2387         unassign_capability('moodle/site:sendmessage', $roleids['user'],
2388             context_system::instance());
2390         // Check that we can not post a message without the capability.
2391         $this->assertFalse(\core_message\api::can_post_message($user2));
2392     }
2394     /**
2395      * Tests the user can post a message when they are contact.
2396      */
2397     public function test_can_post_message_when_contact() {
2398         // Create some users.
2399         $user1 = self::getDataGenerator()->create_user();
2400         $user2 = self::getDataGenerator()->create_user();
2402         // Set as the first user.
2403         $this->setUser($user1);
2405         // Check that we can not send user2 a message.
2406         $this->assertFalse(\core_message\api::can_post_message($user2));
2408         // Add users as contacts.
2409         \core_message\api::add_contact($user1->id, $user2->id);
2411         // Check that the return result is now true.
2412         $this->assertTrue(\core_message\api::can_post_message($user2));
2413     }
2415     /**
2416      * Tests the user can't post a message if they are not a contact and the user
2417      * has requested messages only from contacts.
2418      */
2419     public function test_can_post_message_when_not_contact() {
2420         // Create some users.
2421         $user1 = self::getDataGenerator()->create_user();
2422         $user2 = self::getDataGenerator()->create_user();
2424         // Set as the first user.
2425         $this->setUser($user1);
2427         // Set the second user's preference to not receive messages from non-contacts.
2428         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2430         // Check that we can not send user 2 a message.
2431         $this->assertFalse(\core_message\api::can_post_message($user2));
2432     }
2434     /**
2435      * Tests the user can't post a message if they are blocked.
2436      */
2437     public function test_can_post_message_when_blocked() {
2438         // Create some users.
2439         $user1 = self::getDataGenerator()->create_user();
2440         $user2 = self::getDataGenerator()->create_user();
2442         // Set the user.
2443         $this->setUser($user1);
2445         // Block the second user.
2446         \core_message\api::block_user($user1->id, $user2->id);
2448         // Check that the second user can no longer send the first user a message.
2449         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
2450     }
2452     /**
2453      * Tests the user can post a message when site-wide messaging setting is enabled,
2454      * even if they are not a contact and are not members of the same course.
2455      */
2456     public function test_can_post_message_site_messaging_setting() {
2457         // Create some users.
2458         $user1 = self::getDataGenerator()->create_user();
2459         $user2 = self::getDataGenerator()->create_user();
2461         // Set as the first user.
2462         $this->setUser($user1);
2464         // By default, user only can be messaged by contacts and members of any of his/her courses.
2465         $this->assertFalse(\core_message\api::can_post_message($user2));
2467         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2468         set_config('messagingallusers', true);
2470         // Set the second user's preference to receive messages from everybody.
2471         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
2473         // Check that we can send user2 a message.
2474         $this->assertTrue(\core_message\api::can_post_message($user2));
2476         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
2477         // and members sharing a course with her.
2478         set_config('messagingallusers', false);
2480         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
2481         $this->assertFalse(\core_message\api::can_post_message($user2));
2483         // Enrol users to the same course.
2484         $course = $this->getDataGenerator()->create_course();
2485         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2486         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2487         // Check that we can send user2 a message because they are sharing a course.
2488         $this->assertTrue(\core_message\api::can_post_message($user2));
2490         // Set the second user's preference to receive messages only from contacts.
2491         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2492         // Check that now the user2 can't be contacted because user1 is not their contact.
2493         $this->assertFalse(\core_message\api::can_post_message($user2));
2495         // Make contacts user1 and user2.
2496         \core_message\api::add_contact($user2->id, $user1->id);
2497         // Check that we can send user2 a message because they are contacts.
2498         $this->assertTrue(\core_message\api::can_post_message($user2));
2499     }
2501     /**
2502      * Tests the user with the messageanyuser capability can post a message.
2503      */
2504     public function test_can_post_message_with_messageanyuser_cap() {
2505         global $DB;
2507         // Create some users.
2508         $teacher1 = self::getDataGenerator()->create_user();
2509         $student1 = self::getDataGenerator()->create_user();
2510         $student2 = self::getDataGenerator()->create_user();
2512         // Create users not enrolled in any course.
2513         $user1 = self::getDataGenerator()->create_user();
2515         // Create a course.
2516         $course1 = $this->getDataGenerator()->create_course();
2518         // Enrol the users in the course.
2519         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
2520         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
2521         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
2523         // Set some student preferences to not receive messages from non-contacts.
2524         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
2526         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
2527         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
2528         // Check that the teacher can't contact user1 because it's not his teacher.
2529         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
2531         // Remove the messageanyuser capability from the course1 for teachers.
2532         $coursecontext = context_course::instance($course1->id);
2533         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
2534         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
2535         $coursecontext->mark_dirty();
2537         // Check that we can't send user1 a message because they are not contacts.
2538         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
2539         // However, teacher can message student2 because they are sharing a course.
2540         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
2541     }
2543     /**
2544      * Tests get_user_privacy_messaging_preference method.
2545      */
2546     public function test_get_user_privacy_messaging_preference() {
2547         // Create some users.
2548         $user1 = self::getDataGenerator()->create_user();
2549         $user2 = self::getDataGenerator()->create_user();
2550         $user3 = self::getDataGenerator()->create_user();
2552         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
2553         set_config('messagingallusers', true);
2555         // Set some user preferences.
2556         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
2557         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2559         // Check the returned value for each user.
2560         $this->assertEquals(
2561             \core_message\api::MESSAGE_PRIVACY_SITE,
2562             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2563         );
2564         $this->assertEquals(
2565             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2566             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2567         );
2568         $this->assertEquals(
2569             \core_message\api::MESSAGE_PRIVACY_SITE,
2570             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2571         );
2573         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
2574         set_config('messagingallusers', false);
2576         // Check the returned value for each user.
2577         $this->assertEquals(
2578             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2579             \core_message\api::get_user_privacy_messaging_preference($user1->id)
2580         );
2581         $this->assertEquals(
2582             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
2583             \core_message\api::get_user_privacy_messaging_preference($user2->id)
2584         );
2585         $this->assertEquals(
2586             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
2587             \core_message\api::get_user_privacy_messaging_preference($user3->id)
2588         );
2589     }
2591     /**
2592      * Tests that when blocking messages from non-contacts is enabled that
2593      * non-contacts trying to send a message return false.
2594      */
2595     public function test_is_user_non_contact_blocked() {
2596         // Create some users.
2597         $user1 = self::getDataGenerator()->create_user();
2598         $user2 = self::getDataGenerator()->create_user();
2600         // Set as the first user.
2601         $this->setUser($user1);
2603         // By default, user only can be messaged by contacts and members of any of his/her courses.
2604         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2605         $this->assertDebuggingCalled();
2607         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
2608         // messages from everybody.
2609         set_config('messagingallusers', true);
2610         // Check that the return result is now false because any site user can contact him/her.
2611         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2612         $this->assertDebuggingCalled();
2614         // Set the second user's preference to not receive messages from non-contacts.
2615         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
2616         // Check that the return result is still true (because is even more restricted).
2617         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
2618         $this->assertDebuggingCalled();
2620         // Add the first user as a contact for the second user.
2621         \core_message\api::add_contact($user2->id, $user1->id);
2623         // Check that the return result is now false.
2624         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2625         $this->assertDebuggingCalled();
2627         // Set the second user's preference to receive messages from course members.
2628         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
2629         // Check that the return result is still false (because $user1 is still his/her contact).
2630         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
2631         $this->assertDebuggingCalled();
2632     }
2634     /**
2635      * Tests that we return true when a user is blocked, or false
2636      * if they are not blocked.
2637      */
2638     public function test_is_user_blocked() {
2639         // Create some users.
2640         $user1 = self::getDataGenerator()->create_user();
2641         $user2 = self::getDataGenerator()->create_user();
2643         // Set the user.
2644         $this->setUser($user1);
2646         // User shouldn't be blocked.
2647         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2648         $this->assertDebuggingCalled();
2650         // Block the user.
2651         \core_message\api::block_user($user1->id, $user2->id);
2653         // User should be blocked.
2654         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
2655         $this->assertDebuggingCalled();
2657         // Unblock the user.
2658         \core_message\api::unblock_user($user1->id, $user2->id);
2659         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
2660         $this->assertDebuggingCalled();
2661     }
2663     /**
2664      * Tests that the admin is not blocked even if someone has chosen to block them.
2665      */
2666     public function test_is_user_blocked_as_admin() {
2667         // Create a user.
2668         $user1 = self::getDataGenerator()->create_user();
2670         // Set the user.
2671         $this->setUser($user1);
2673         // Block the admin user.
2674         \core_message\api::block_user($user1->id, 2);
2676         // Now change to the admin user.
2677         $this->setAdminUser();
2679         // As the admin you should still be able to send messages to the user.
2680         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
2681         $this->assertDebuggingCalled();
2682     }
2684     /*
2685      * Tes get_message_processor api.
2686      */
2687     public function test_get_message_processor() {
2688         $processors = get_message_processors(true);
2689         if (empty($processors)) {
2690             $this->markTestSkipped("No message processors found");
2691         }
2693         $name = key($processors);
2694         $processor = current($processors);
2695         $testprocessor = \core_message\api::get_message_processor($name);
2696         $this->assertEquals($processor->name, $testprocessor->name);
2697         $this->assertEquals($processor->enabled, $testprocessor->enabled);
2698         $this->assertEquals($processor->available, $testprocessor->available);
2699         $this->assertEquals($processor->configured, $testprocessor->configured);
2701         // Disable processor and test.
2702         \core_message\api::update_processor_status($testprocessor, 0);
2703         $testprocessor = \core_message\api::get_message_processor($name, true);
2704         $this->assertEmpty($testprocessor);
2705         $testprocessor = \core_message\api::get_message_processor($name);
2706         $this->assertEquals($processor->name, $testprocessor->name);
2707         $this->assertEquals(0, $testprocessor->enabled);
2709         // Enable again and test.
2710         \core_message\api::update_processor_status($testprocessor, 1);
2711         $testprocessor = \core_message\api::get_message_processor($name, true);
2712         $this->assertEquals($processor->name, $testprocessor->name);
2713         $this->assertEquals(1, $testprocessor->enabled);
2714         $testprocessor = \core_message\api::get_message_processor($name);
2715         $this->assertEquals($processor->name, $testprocessor->name);
2716         $this->assertEquals(1, $testprocessor->enabled);
2717     }
2719     /**
2720      * Test method update_processor_status.
2721      */
2722     public function test_update_processor_status() {
2723         $processors = get_message_processors();
2724         if (empty($processors)) {
2725             $this->markTestSkipped("No message processors found");
2726         }
2727         $name = key($processors);
2728         $testprocessor = current($processors);
2730         // Enable.
2731         \core_message\api::update_processor_status($testprocessor, 1);
2732         $testprocessor = \core_message\api::get_message_processor($name);
2733         $this->assertEquals(1, $testprocessor->enabled);
2735         // Disable.
2736         \core_message\api::update_processor_status($testprocessor, 0);
2737         $testprocessor = \core_message\api::get_message_processor($name);
2738         $this->assertEquals(0, $testprocessor->enabled);
2740         // Enable again.
2741         \core_message\api::update_processor_status($testprocessor, 1);
2742         $testprocessor = \core_message\api::get_message_processor($name);
2743         $this->assertEquals(1, $testprocessor->enabled);
2744     }
2746     /**
2747      * Test method is_user_enabled.
2748      */
2749     public function is_user_enabled() {
2750         $processors = get_message_processors();
2751         if (empty($processors)) {
2752             $this->markTestSkipped("No message processors found");
2753         }
2754         $name = key($processors);
2755         $testprocessor = current($processors);
2757         // Enable.
2758         \core_message\api::update_processor_status($testprocessor, 1);
2759         $status = \core_message\api::is_processor_enabled($name);
2760         $this->assertEquals(1, $status);
2762         // Disable.
2763         \core_message\api::update_processor_status($testprocessor, 0);
2764         $status = \core_message\api::is_processor_enabled($name);
2765         $this->assertEquals(0, $status);
2767         // Enable again.
2768         \core_message\api::update_processor_status($testprocessor, 1);
2769         $status = \core_message\api::is_processor_enabled($name);
2770         $this->assertEquals(1, $status);
2771     }
2773     /**
2774      * Test retrieving messages by providing a minimum timecreated value.
2775      */
2776     public function test_get_messages_time_from_only() {
2777         // Create some users.
2778         $user1 = self::getDataGenerator()->create_user();
2779         $user2 = self::getDataGenerator()->create_user();
2781         // The person doing the search.
2782         $this->setUser($user1);
2784         // Send some messages back and forth.
2785         $time = 1;
2786         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2787         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2788         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2789         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2791         // Retrieve the messages from $time, which should be all of them.
2792         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
2793         $this->assertDebuggingCalledCount(3);
2795         // Confirm the message data is correct.
2796         $this->assertEquals(4, count($messages));
2798         $message1 = $messages[0];
2799         $message2 = $messages[1];
2800         $message3 = $messages[2];
2801         $message4 = $messages[3];
2803         $this->assertContains('Message 1', $message1->text);
2804         $this->assertContains('Message 2', $message2->text);
2805         $this->assertContains('Message 3', $message3->text);
2806         $this->assertContains('Message 4', $message4->text);
2808         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2809         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
2810         $this->assertDebuggingCalledCount(3);
2812         // Confirm the message data is correct.
2813         $this->assertEquals(2, count($messages));
2815         $message1 = $messages[0];
2816         $message2 = $messages[1];
2818         $this->assertContains('Message 3', $message1->text);
2819         $this->assertContains('Message 4', $message2->text);
2820     }
2822     /**
2823      * Test retrieving messages by providing a maximum timecreated value.
2824      */
2825     public function test_get_messages_time_to_only() {
2826         // Create some users.
2827         $user1 = self::getDataGenerator()->create_user();
2828         $user2 = self::getDataGenerator()->create_user();
2830         // The person doing the search.
2831         $this->setUser($user1);
2833         // Send some messages back and forth.
2834         $time = 1;
2835         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2836         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2837         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2838         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2840         // Retrieve the messages up until $time + 4, which should be all of them.
2841         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
2842         $this->assertDebuggingCalledCount(3);
2844         // Confirm the message data is correct.
2845         $this->assertEquals(4, count($messages));
2847         $message1 = $messages[0];
2848         $message2 = $messages[1];
2849         $message3 = $messages[2];
2850         $message4 = $messages[3];
2852         $this->assertContains('Message 1', $message1->text);
2853         $this->assertContains('Message 2', $message2->text);
2854         $this->assertContains('Message 3', $message3->text);
2855         $this->assertContains('Message 4', $message4->text);
2857         // Retrieve the messages up until $time + 2, which should be the first two.
2858         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
2859         $this->assertDebuggingCalledCount(3);
2861         // Confirm the message data is correct.
2862         $this->assertEquals(2, count($messages));
2864         $message1 = $messages[0];
2865         $message2 = $messages[1];
2867         $this->assertContains('Message 1', $message1->text);
2868         $this->assertContains('Message 2', $message2->text);
2869     }
2871     /**
2872      * Test retrieving messages by providing a minimum and maximum timecreated value.
2873      */
2874     public function test_get_messages_time_from_and_to() {
2875         // Create some users.
2876         $user1 = self::getDataGenerator()->create_user();
2877         $user2 = self::getDataGenerator()->create_user();
2879         // The person doing the search.
2880         $this->setUser($user1);
2882         // Send some messages back and forth.
2883         $time = 1;
2884         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2885         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2886         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2887         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2889         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2890         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
2891         $this->assertDebuggingCalledCount(3);
2893         // Confirm the message data is correct.
2894         $this->assertEquals(2, count($messages));
2896         $message1 = $messages[0];
2897         $message2 = $messages[1];
2899         $this->assertContains('Message 2', $message1->text);
2900         $this->assertContains('Message 3', $message2->text);
2901     }
2903     /**
2904      * Test returning blocked users.
2905      */
2906     public function test_get_blocked_users() {
2907         global $USER;
2909         // Set this user as the admin.
2910         $this->setAdminUser();
2912         // Create a user to add to the admin's contact list.
2913         $user1 = $this->getDataGenerator()->create_user();
2914         $user2 = $this->getDataGenerator()->create_user();
2916         // Add users to the admin's contact list.
2917         \core_message\api::block_user($USER->id, $user2->id);
2919         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2921         // Block other user.
2922         \core_message\api::block_user($USER->id, $user1->id);
2923         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
2925         // Test deleting users.
2926         delete_user($user1);
2927         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2928     }
2930     /**
2931      * Test returning contacts with unread message count.
2932      */
2933     public function test_get_contacts_with_unread_message_count() {
2934         global $DB;
2936         $user1 = self::getDataGenerator()->create_user();
2937         $user2 = self::getDataGenerator()->create_user();
2938         $user3 = self::getDataGenerator()->create_user();
2939         $user4 = self::getDataGenerator()->create_user();
2941         // Add the users to each of their contacts.
2942         \core_message\api::add_contact($user1->id, $user2->id);
2943         \core_message\api::add_contact($user2->id, $user3->id);
2945         $this->send_fake_message($user1, $user2);
2946         $this->send_fake_message($user1, $user2);
2947         $this->send_fake_message($user1, $user2);
2948         $message4id = $this->send_fake_message($user1, $user2);
2950         $this->send_fake_message($user3, $user2);
2951         $message6id = $this->send_fake_message($user3, $user2);
2952         $this->send_fake_message($user3, $user2);
2953         $this->send_fake_message($user3, $user2);
2954         $this->send_fake_message($user3, $user2);
2956         // Send a message that should never be included as the user is not a contact.
2957         $this->send_fake_message($user4, $user2);
2959         // Get the contacts and the unread message count.
2960         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2962         // Confirm the size is correct.
2963         $this->assertCount(2, $messages);
2964         ksort($messages);
2966         $messageinfo1 = array_shift($messages);
2967         $messageinfo2 = array_shift($messages);
2969         $this->assertEquals($user1->id, $messageinfo1->id);
2970         $this->assertEquals(4, $messageinfo1->messagecount);
2971         $this->assertEquals($user3->id, $messageinfo2->id);
2972         $this->assertEquals(5, $messageinfo2->messagecount);
2974         // Mark some of the messages as read.
2975         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2976         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2977         \core_message\api::mark_message_as_read($user2->id, $m4);
2978         \core_message\api::mark_message_as_read($user2->id, $m6);
2980         // Get the contacts and the unread message count.
2981         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2983         // Confirm the size is correct.
2984         $this->assertCount(2, $messages);
2985         ksort($messages);
2987         // Confirm read messages are not included.
2988         $messageinfo1 = array_shift($messages);
2989         $messageinfo2 = array_shift($messages);
2990         $this->assertEquals($user1->id, $messageinfo1->id);
2991         $this->assertEquals(3, $messageinfo1->messagecount);
2992         $this->assertEquals($user3->id, $messageinfo2->id);
2993         $this->assertEquals(4, $messageinfo2->messagecount);
2995         // Now, let's populate the database with messages from user2 to user 1.
2996         $this->send_fake_message($user2, $user1);
2997         $this->send_fake_message($user2, $user1);
2998         $messageid = $this->send_fake_message($user2, $user1);
3000         // Send a message that should never be included as the user is not a contact.
3001         $this->send_fake_message($user4, $user1);
3003         // Get the contacts and the unread message count.
3004         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
3006         // Confirm the size is correct.
3007         $this->assertCount(1, $messages);
3008         $messageinfo1 = array_shift($messages);
3009         $this->assertEquals($user2->id, $messageinfo1->id);
3010         $this->assertEquals(3, $messageinfo1->messagecount);
3012         // Mark the last message as read.
3013         $m = $DB->get_record('messages', ['id' => $messageid]);
3014         \core_message\api::mark_message_as_read($user1->id, $m);
3016         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
3018         // Confirm the size is correct.
3019         $this->assertCount(1, $messages);
3021         // Confirm read messages are not included.
3022         $messageinfo1 = array_shift($messages);
3023         $this->assertEquals($user2->id, $messageinfo1->id);
3024         $this->assertEquals(2, $messageinfo1->messagecount);
3025     }
3027     /**
3028      * Test returning contacts with unread message count when there are no messages.
3029      */
3030     public function test_get_contacts_with_unread_message_count_no_messages() {
3031         $user1 = self::getDataGenerator()->create_user();
3032         $user2 = self::getDataGenerator()->create_user();
3034         // Add the users to each of their contacts.
3035         \core_message\api::add_contact($user2->id, $user1->id);
3037         // Check we get the correct message count.
3038         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
3040         // Confirm the size is correct.
3041         $this->assertCount(1, $messages);
3043         $messageinfo = array_shift($messages);
3045         $this->assertEquals($user1->id, $messageinfo->id);
3046         $this->assertEquals(0, $messageinfo->messagecount);
3047     }
3049     /**
3050      * Test returning non-contacts with unread message count.
3051      */
3052     public function test_get_non_contacts_with_unread_message_count() {
3053         global $DB;
3055         $user1 = self::getDataGenerator()->create_user();
3056         $user2 = self::getDataGenerator()->create_user();
3057         $user3 = self::getDataGenerator()->create_user();
3058         $user4 = self::getDataGenerator()->create_user();
3060         // Add a user to the contact list of the users we are testing this function with.
3061         \core_message\api::add_contact($user1->id, $user4->id);
3062         \core_message\api::add_contact($user2->id, $user4->id);
3064         $this->send_fake_message($user1, $user2);
3065         $this->send_fake_message($user1, $user2);
3066         $this->send_fake_message($user1, $user2);
3067         $message4id = $this->send_fake_message($user1, $user2);
3069         $this->send_fake_message($user3, $user2);
3070         $message6id = $this->send_fake_message($user3, $user2);
3071         $this->send_fake_message($user3, $user2);
3072         $this->send_fake_message($user3, $user2);
3073         $this->send_fake_message($user3, $user2);
3075         // Send a message that should never be included as the user is a contact.
3076         $this->send_fake_message($user4, $user2);
3078         // Get the non-contacts and the unread message count.
3079         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
3081         // Check we get the correct message count.
3082         ksort($messages);
3083         $this->assertCount(2, $messages);
3084         $messageinfo1 = array_shift($messages);
3085         $messageinfo2 = array_shift($messages);
3086         $this->assertEquals($user1->id, $messageinfo1->id);
3087         $this->assertEquals(4, $messageinfo1->messagecount);
3088         $this->assertEquals($user3->id, $messageinfo2->id);
3089         $this->assertEquals(5, $messageinfo2->messagecount);
3091         // Mark some of the messages as read.
3092         $m4 = $DB->get_record('messages', ['id' => $message4id]);
3093         $m6 = $DB->get_record('messages', ['id' => $message6id]);
3094         \core_message\api::mark_message_as_read($user2->id, $m4);
3095         \core_message\api::mark_message_as_read($user2->id, $m6);
3097         // Get the non-contacts and the unread message count.
3098         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
3100         // Check the marked message is not returned in the message count.
3101         ksort($messages);
3102         $this->assertCount(2, $messages);
3103         $messageinfo1 = array_shift($messages);
3104         $messageinfo2 = array_shift($messages);
3105         $this->assertEquals($user1->id, $messageinfo1->id);
3106         $this->assertEquals(3, $messageinfo1->messagecount);
3107         $this->assertEquals($user3->id, $messageinfo2->id);
3108         $this->assertEquals(4, $messageinfo2->messagecount);
3110         // Now, let's populate the database with messages from user2 to user 1.
3111         $this->send_fake_message($user2, $user1);
3112         $this->send_fake_message($user2, $user1);
3113         $messageid = $this->send_fake_message($user2, $user1);
3115         // Send a message that should never be included as the user is a contact.
3116         $this->send_fake_message($user4, $user1);
3118         // Get the non-contacts and the unread message count.
3119         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
3121         // Confirm the size is correct.
3122         $this->assertCount(1, $messages);
3123         $messageinfo1 = array_shift($messages);
3124         $this->assertEquals($user2->id, $messageinfo1->id);
3125         $this->assertEquals(3, $messageinfo1->messagecount);
3127         // Mark the last message as read.
3128         $m = $DB->get_record('messages', ['id' => $messageid]);
3129         \core_message\api::mark_message_as_read($user1->id, $m);
3131         // Get the non-contacts and the unread message count.
3132         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
3134         // Check the marked message is not returned in the message count.
3135         $this->assertCount(1, $messages);
3136         $messageinfo1 = array_shift($messages);
3137         $this->assertEquals($user2->id, $messageinfo1->id);
3138         $this->assertEquals(2, $messageinfo1->messagecount);
3139     }
3141     /**
3142      * Test marking a message as read.
3143      */
3144     public function test_mark_message_as_read() {
3145         global $DB;
3147         $user1 = self::getDataGenerator()->create_user();
3148         $user2 = self::getDataGenerator()->create_user();
3150         $this->send_fake_message($user1, $user2);
3151         $m2id = $this->send_fake_message($user1, $user2);
3152         $this->send_fake_message($user2, $user1);
3153         $m4id = $this->send_fake_message($user2, $user1);
3155         $m2 = $DB->get_record('messages', ['id' => $m2id]);
3156         $m4 = $DB->get_record('messages', ['id' => $m4id]);
3157         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
3158         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
3160         // Confirm there are two user actions.
3161         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
3162         $this->assertEquals(2, count($muas));
3164         // Confirm they are correct.
3165         $mua1 = array_shift($muas);
3166         $mua2 = array_shift($muas);
3168         // Confirm first action.
3169         $this->assertEquals($user2->id, $mua1->userid);
3170         $this->assertEquals($m2id, $mua1->messageid);
3171         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
3172         $this->assertEquals(11, $mua1->timecreated);
3174         // Confirm second action.
3175         $this->assertEquals($user1->id, $mua2->userid);
3176         $this->assertEquals($m4id, $mua2->messageid);
3177         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
3178         $this->assertEquals(12, $mua2->timecreated);
3179     }
3181     /**
3182      * Test marking a notification as read.
3183      */
3184     public function test_mark_notification_as_read() {
3185         global $DB;
3187         $user1 = self::getDataGenerator()->create_user();
3188         $user2 = self::getDataGenerator()->create_user();
3190         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
3191         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
3192         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
3193         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
3195         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3196         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3198         \core_message\api::mark_notification_as_read($n2, 11);
3199         \core_message\api::mark_notification_as_read($n4, 12);
3201         // Retrieve the notifications.
3202         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3203         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3205         // Confirm they have been marked as read.
3206         $this->assertEquals(11, $n2->timeread);
3207         $this->assertEquals(12, $n4->timeread);
3208     }
3210     /**
3211      * Test a conversation is not returned if there is none.
3212      */
3213     public function test_get_conversation_between_users_no_conversation() {
3214         $user1 = self::getDataGenerator()->create_user();
3215         $user2 = self::getDataGenerator()->create_user();
3217         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
3218     }
3220     /**
3221      * Test we can return a conversation that exists between users.
3222      */
3223     public function test_get_conversation_between_users_with_existing_conversation() {
3224         $user1 = self::getDataGenerator()->create_user();
3225         $user2 = self::getDataGenerator()->create_user();
3227         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
3228         $this->assertDebuggingCalled();
3230         $this->assertEquals($conversationid,
3231             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
3232     }
3234     /**
3235      * Test count_conversation_members for non existing conversation.
3236      */
3237     public function test_count_conversation_members_no_existing_conversation() {
3238         $this->assertEquals(0,
3239             \core_message\api::count_conversation_members(0));
3240     }
3242     /**
3243      * Test count_conversation_members for existing conversation.
3244      */
3245     public function test_count_conversation_members_existing_conversation() {
3246         $user1 = self::getDataGenerator()->create_user();
3247         $user2 = self::getDataGenerator()->create_user();
3249         $conversation = \core_message\api::create_conversation(
3250             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3251             [
3252                 $user1->id,
3253                 $user2->id
3254             ]
3255         );
3256         $conversationid = $conversation->id;
3258         $this->assertEquals(2,
3259             \core_message\api::count_conversation_members($conversationid));
3260     }
3262     /**
3263      * Test add_members_to_conversation for an individual conversation.
3264      */
3265     public function test_add_members_to_individual_conversation() {
3266         $user1 = self::getDataGenerator()->create_user();
3267         $user2 = self::getDataGenerator()->create_user();
3268         $user3 = self::getDataGenerator()->create_user();
3270         $conversation = \core_message\api::create_conversation(
3271             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3272             [
3273                 $user1->id,
3274                 $user2->id
3275             ]
3276         );
3277         $conversationid = $conversation->id;
3279         $this->expectException('moodle_exception');
3280         \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
3281     }
3283     /**
3284      * Test add_members_to_conversation for existing conversation.
3285      */
3286     public function test_add_members_to_existing_conversation() {
3287         $user1 = self::getDataGenerator()->create_user();
3288         $user2 = self::getDataGenerator()->create_user();
3289         $user3 = self::getDataGenerator()->create_user();
3291         $conversation = \core_message\api::create_conversation(
3292             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3293             [
3294                 $user1->id,
3295                 $user2->id
3296             ]
3297         );
3298         $conversationid = $conversation->id;
3300         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
3301         $this->assertEquals(3,
3302             \core_message\api::count_conversation_members($conversationid));
3303     }
3305     /**
3306      * Test add_members_to_conversation for non existing conversation.
3307      */
3308     public function test_add_members_to_no_existing_conversation() {
3309         $user1 = self::getDataGenerator()->create_user();
3311         // Throw dml_missing_record_exception for non existing conversation.
3312         $this->expectException('dml_missing_record_exception');
3313         \core_message\api::add_members_to_conversation([$user1->id], 0);
3314     }
3316     /**
3317      * Test add_member_to_conversation for non existing user.
3318      */
3319     public function test_add_members_to_no_existing_user() {
3320         $user1 = self::getDataGenerator()->create_user();
3321         $user2 = self::getDataGenerator()->create_user();
3323         $conversation = \core_message\api::create_conversation(