MDL-63280 core: minor changes after review
[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 /**
33  * Test message API.
34  *
35  * @package core_message
36  * @category test
37  * @copyright 2016 Mark Nelson <markn@moodle.com>
38  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39  */
40 class core_message_api_testcase extends core_message_messagelib_testcase {
42     public function test_mark_all_read_for_user_touser() {
43         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
44         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
46         $this->send_fake_message($sender, $recipient, 'Notification', 1);
47         $this->send_fake_message($sender, $recipient, 'Notification', 1);
48         $this->send_fake_message($sender, $recipient, 'Notification', 1);
49         $this->send_fake_message($sender, $recipient);
50         $this->send_fake_message($sender, $recipient);
51         $this->send_fake_message($sender, $recipient);
53         \core_message\api::mark_all_read_for_user($recipient->id);
54         $this->assertDebuggingCalled();
55         $this->assertEquals(message_count_unread_messages($recipient), 0);
56     }
58     public function test_mark_all_read_for_user_touser_with_fromuser() {
59         $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
60         $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
61         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
63         $this->send_fake_message($sender1, $recipient, 'Notification', 1);
64         $this->send_fake_message($sender1, $recipient, 'Notification', 1);
65         $this->send_fake_message($sender1, $recipient, 'Notification', 1);
66         $this->send_fake_message($sender1, $recipient);
67         $this->send_fake_message($sender1, $recipient);
68         $this->send_fake_message($sender1, $recipient);
69         $this->send_fake_message($sender2, $recipient, 'Notification', 1);
70         $this->send_fake_message($sender2, $recipient, 'Notification', 1);
71         $this->send_fake_message($sender2, $recipient, 'Notification', 1);
72         $this->send_fake_message($sender2, $recipient);
73         $this->send_fake_message($sender2, $recipient);
74         $this->send_fake_message($sender2, $recipient);
76         \core_message\api::mark_all_read_for_user($recipient->id, $sender1->id);
77         $this->assertDebuggingCalled();
78         $this->assertEquals(message_count_unread_messages($recipient), 3);
79     }
81     public function test_mark_all_read_for_user_touser_with_type() {
82         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
83         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
85         $this->send_fake_message($sender, $recipient, 'Notification', 1);
86         $this->send_fake_message($sender, $recipient, 'Notification', 1);
87         $this->send_fake_message($sender, $recipient, 'Notification', 1);
88         $this->send_fake_message($sender, $recipient);
89         $this->send_fake_message($sender, $recipient);
90         $this->send_fake_message($sender, $recipient);
92         \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_NOTIFICATION);
93         $this->assertDebuggingCalled();
94         $this->assertEquals(message_count_unread_messages($recipient), 3);
96         \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_MESSAGE);
97         $this->assertDebuggingCalled();
98         $this->assertEquals(message_count_unread_messages($recipient), 0);
99     }
101     /**
102      * Test count_blocked_users.
103      */
104     public function test_count_blocked_users() {
105         global $USER;
107         // Set this user as the admin.
108         $this->setAdminUser();
110         // Create user to add to the admin's block list.
111         $user1 = $this->getDataGenerator()->create_user();
112         $user2 = $this->getDataGenerator()->create_user();
114         $this->assertEquals(0, \core_message\api::count_blocked_users());
116         // Add 1 blocked user to admin's blocked user list.
117         \core_message\api::block_user($USER->id, $user1->id);
119         $this->assertEquals(0, \core_message\api::count_blocked_users($user1));
120         $this->assertEquals(1, \core_message\api::count_blocked_users());
121     }
123     /**
124      * Tests searching users in a course.
125      */
126     public function test_search_users_in_course() {
127         // Create some users.
128         $user1 = new stdClass();
129         $user1->firstname = 'User';
130         $user1->lastname = 'One';
131         $user1 = self::getDataGenerator()->create_user($user1);
133         // The person doing the search.
134         $this->setUser($user1);
136         // Second user is going to have their last access set to now, so they are online.
137         $user2 = new stdClass();
138         $user2->firstname = 'User';
139         $user2->lastname = 'Two';
140         $user2->lastaccess = time();
141         $user2 = self::getDataGenerator()->create_user($user2);
143         // Block the second user.
144         \core_message\api::block_user($user1->id, $user2->id);
146         $user3 = new stdClass();
147         $user3->firstname = 'User';
148         $user3->lastname = 'Three';
149         $user3 = self::getDataGenerator()->create_user($user3);
151         // Create a course.
152         $course1 = new stdClass();
153         $course1->fullname = 'Course';
154         $course1->shortname = 'One';
155         $course1 = $this->getDataGenerator()->create_course($course1);
157         // Enrol the searcher and one user in the course.
158         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
159         $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
161         // Perform a search.
162         $results = \core_message\api::search_users_in_course($user1->id, $course1->id, 'User');
164         $this->assertEquals(1, count($results));
166         $user = $results[0];
167         $this->assertEquals($user2->id, $user->userid);
168         $this->assertEquals(fullname($user2), $user->fullname);
169         $this->assertFalse($user->ismessaging);
170         $this->assertNull($user->lastmessage);
171         $this->assertNull($user->messageid);
172         $this->assertNull($user->isonline);
173         $this->assertFalse($user->isread);
174         $this->assertTrue($user->isblocked);
175         $this->assertNull($user->unreadcount);
176     }
178     /**
179      * Tests searching users.
180      */
181     public function test_search_users() {
182         global $DB;
184         // Create some users.
185         $user1 = new stdClass();
186         $user1->firstname = 'User';
187         $user1->lastname = 'One';
188         $user1 = self::getDataGenerator()->create_user($user1);
190         // Set as the user performing the search.
191         $this->setUser($user1);
193         $user2 = new stdClass();
194         $user2->firstname = 'User search';
195         $user2->lastname = 'Two';
196         $user2 = self::getDataGenerator()->create_user($user2);
198         $user3 = new stdClass();
199         $user3->firstname = 'User search';
200         $user3->lastname = 'Three';
201         $user3 = self::getDataGenerator()->create_user($user3);
203         $user4 = new stdClass();
204         $user4->firstname = 'User';
205         $user4->lastname = 'Four';
206         $user4 = self::getDataGenerator()->create_user($user4);
208         $user5 = new stdClass();
209         $user5->firstname = 'User search';
210         $user5->lastname = 'Five';
211         $user5 = self::getDataGenerator()->create_user($user5);
213         $user6 = new stdClass();
214         $user6->firstname = 'User';
215         $user6->lastname = 'Six';
216         $user6 = self::getDataGenerator()->create_user($user6);
218         // Create some courses.
219         $course1 = new stdClass();
220         $course1->fullname = 'Course search';
221         $course1->shortname = 'One';
222         $course1 = $this->getDataGenerator()->create_course($course1);
224         $course2 = new stdClass();
225         $course2->fullname = 'Course';
226         $course2->shortname = 'Two';
227         $course2 = $this->getDataGenerator()->create_course($course2);
229         $course3 = new stdClass();
230         $course3->fullname = 'Course';
231         $course3->shortname = 'Three search';
232         $course3 = $this->getDataGenerator()->create_course($course3);
234         $course4 = new stdClass();
235         $course4->fullname = 'Course Four';
236         $course4->shortname = 'CF100';
237         $course4 = $this->getDataGenerator()->create_course($course4);
239         $course5 = new stdClass();
240         $course5->fullname = 'Course';
241         $course5->shortname = 'Five search';
242         $course5 = $this->getDataGenerator()->create_course($course5);
244         $role = $DB->get_record('role', ['shortname' => 'student']);
245         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $role->id);
246         $this->getDataGenerator()->enrol_user($user1->id, $course2->id, $role->id);
247         $this->getDataGenerator()->enrol_user($user1->id, $course3->id, $role->id);
248         $this->getDataGenerator()->enrol_user($user1->id, $course5->id, $role->id);
250         // Add some users as contacts.
251         \core_message\api::add_contact($user1->id, $user2->id);
252         \core_message\api::add_contact($user1->id, $user3->id);
253         \core_message\api::add_contact($user1->id, $user4->id);
255         // Remove the viewparticipants capability from one of the courses.
256         $course5context = context_course::instance($course5->id);
257         assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $role->id, $course5context->id);
259         // Perform a search.
260         list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
262         // Check that we retrieved the correct contacts.
263         $this->assertEquals(2, count($contacts));
264         $this->assertEquals($user3->id, $contacts[0]->userid);
265         $this->assertEquals($user2->id, $contacts[1]->userid);
267         // Check that we retrieved the correct courses.
268         $this->assertEquals(2, count($courses));
269         $this->assertEquals($course3->id, $courses[0]->id);
270         $this->assertEquals($course1->id, $courses[1]->id);
272         // Check that we retrieved the correct non-contacts.
273         $this->assertEquals(1, count($noncontacts));
274         $this->assertEquals($user5->id, $noncontacts[0]->userid);
275     }
277     /**
278      * Tests searching messages.
279      */
280     public function test_search_messages() {
281         // Create some users.
282         $user1 = self::getDataGenerator()->create_user();
283         $user2 = self::getDataGenerator()->create_user();
284         $user3 = self::getDataGenerator()->create_user();
286         // The person doing the search.
287         $this->setUser($user1);
289         // Send some messages back and forth.
290         $time = 1;
291         $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
292         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
293         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
294         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
295         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
297         // Block user 3.
298         \core_message\api::block_user($user1->id, $user3->id);
300         // Perform a search.
301         $messages = \core_message\api::search_messages($user1->id, 'o');
303         // Confirm the data is correct.
304         $this->assertEquals(3, count($messages));
306         $message1 = $messages[0];
307         $message2 = $messages[1];
308         $message3 = $messages[2];
310         $this->assertEquals($user2->id, $message1->userid);
311         $this->assertEquals($user2->id, $message1->useridfrom);
312         $this->assertEquals(fullname($user2), $message1->fullname);
313         $this->assertTrue($message1->ismessaging);
314         $this->assertEquals('Word.', $message1->lastmessage);
315         $this->assertNotEmpty($message1->messageid);
316         $this->assertNull($message1->isonline);
317         $this->assertFalse($message1->isread);
318         $this->assertFalse($message1->isblocked);
319         $this->assertNull($message1->unreadcount);
321         $this->assertEquals($user2->id, $message2->userid);
322         $this->assertEquals($user1->id, $message2->useridfrom);
323         $this->assertEquals(fullname($user2), $message2->fullname);
324         $this->assertTrue($message2->ismessaging);
325         $this->assertEquals('Yo!', $message2->lastmessage);
326         $this->assertNotEmpty($message2->messageid);
327         $this->assertNull($message2->isonline);
328         $this->assertTrue($message2->isread);
329         $this->assertFalse($message2->isblocked);
330         $this->assertNull($message2->unreadcount);
332         $this->assertEquals($user3->id, $message3->userid);
333         $this->assertEquals($user3->id, $message3->useridfrom);
334         $this->assertEquals(fullname($user3), $message3->fullname);
335         $this->assertTrue($message3->ismessaging);
336         $this->assertEquals('Don\'t block me.', $message3->lastmessage);
337         $this->assertNotEmpty($message3->messageid);
338         $this->assertNull($message3->isonline);
339         $this->assertFalse($message3->isread);
340         $this->assertTrue($message3->isblocked);
341         $this->assertNull($message3->unreadcount);
342     }
344     /**
345      * Test verifying that favourited conversations can be retrieved.
346      */
347     public function test_get_favourite_conversations() {
348         // Create some users.
349         $user1 = self::getDataGenerator()->create_user();
350         $user2 = self::getDataGenerator()->create_user();
351         $user3 = self::getDataGenerator()->create_user();
352         $user4 = self::getDataGenerator()->create_user();
354         // The person doing the search.
355         $this->setUser($user1);
357         // No conversations yet.
358         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
360         // Create some conversations for user1.
361         $time = 1;
362         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
363         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
364         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
365         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
367         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
368         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
369         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
370         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
372         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
373         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
374         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
376         // Favourite the first 2 conversations for user1.
377         $convoids = [];
378         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
379         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
380         $user1context = context_user::instance($user1->id);
381         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
382         foreach ($convoids as $convoid) {
383             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
384         }
386         // We should have 3 conversations.
387         $this->assertCount(3, \core_message\api::get_conversations($user1->id));
389         // And 2 favourited conversations.
390         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
391         $this->assertCount(2, $conversations);
392     }
394     /**
395      * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
396      */
397     public function test_get_favourite_conversations_limit_offset() {
398         // Create some users.
399         $user1 = self::getDataGenerator()->create_user();
400         $user2 = self::getDataGenerator()->create_user();
401         $user3 = self::getDataGenerator()->create_user();
402         $user4 = self::getDataGenerator()->create_user();
404         // The person doing the search.
405         $this->setUser($user1);
407         // No conversations yet.
408         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
410         // Create some conversations for user1.
411         $time = 1;
412         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
413         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
414         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
415         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
417         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
418         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
419         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
420         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
422         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
423         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
424         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
426         // Favourite the all conversations for user1.
427         $convoids = [];
428         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
429         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
430         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
431         $user1context = context_user::instance($user1->id);
432         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
433         foreach ($convoids as $convoid) {
434             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
435         }
437         // Get all records, using offset 0 and large limit.
438         $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
440         // Now, get 10 conversations starting at the second record. We should see 2 conversations.
441         $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
443         // Now, try to get favourited conversations using an invalid offset.
444         $this->assertCount(0, \core_message\api::get_conversations($user1->id, 4, 10, null, true));
445     }
447     /**
448      * Tests retrieving favourite conversations when a conversation contains a deleted user.
449      */
450     public function test_get_favourite_conversations_with_deleted_user() {
451         // Create some users.
452         $user1 = self::getDataGenerator()->create_user();
453         $user2 = self::getDataGenerator()->create_user();
454         $user3 = self::getDataGenerator()->create_user();
456         // Send some messages back and forth, have some different conversations with different users.
457         $time = 1;
458         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
459         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
460         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
461         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
463         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
464         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
465         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
466         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
468         // Favourite the all conversations for user1.
469         $convoids = [];
470         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
471         $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
472         $user1context = context_user::instance($user1->id);
473         $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
474         foreach ($convoids as $convoid) {
475             $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
476         }
478         // Delete the second user.
479         delete_user($user2);
481         // Retrieve the conversations.
482         $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
484         // We should only have one conversation because the other user was deleted.
485         $this->assertCount(1, $conversations);
487         // Confirm the conversation is from the non-deleted user.
488         $conversation = reset($conversations);
489         $this->assertEquals($user3->id, $conversation->userid);
490     }
492     /**
493      * Test confirming that conversations can be marked as favourites.
494      */
495     public function test_set_favourite_conversation() {
496         // Create some users.
497         $user1 = self::getDataGenerator()->create_user();
498         $user2 = self::getDataGenerator()->create_user();
499         $user3 = self::getDataGenerator()->create_user();
501         // Send some messages back and forth, have some different conversations with different users.
502         $time = 1;
503         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
504         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
505         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
506         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
508         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
509         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
510         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
511         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
513         // Favourite the first conversation as user 1.
514         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
515         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
517         // Verify we have a single favourite conversation a user 1.
518         $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
520         // Verify we have no favourites as user2, despite being a member in that conversation.
521         $this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
523         // Try to favourite the same conversation again.
524         $this->expectException(\moodle_exception::class);
525         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
526     }
528     /**
529      * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
530      */
531     public function test_set_favourite_conversation_nonexistent_conversation() {
532         // Create some users.
533         $user1 = self::getDataGenerator()->create_user();
534         // Try to favourite a non-existent conversation.
535         $this->expectException(\moodle_exception::class);
536         \core_message\api::set_favourite_conversation(0, $user1->id);
537     }
539     /**
540      * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
541      */
542     public function test_set_favourite_conversation_non_member() {
543         // Create some users.
544         $user1 = self::getDataGenerator()->create_user();
545         $user2 = self::getDataGenerator()->create_user();
546         $user3 = self::getDataGenerator()->create_user();
548         // Send some messages back and forth, have some different conversations with different users.
549         $time = 1;
550         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
551         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
552         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
553         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
555         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
556         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
557         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
558         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
560         // Try to favourite the first conversation as user 3, who is not a member.
561         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
562         $this->expectException(\moodle_exception::class);
563         \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
564     }
566     /**
567      * Test confirming that those conversations marked as favourites can be unfavourited.
568      */
569     public function test_unset_favourite_conversation() {
570         // Create some users.
571         $user1 = self::getDataGenerator()->create_user();
572         $user2 = self::getDataGenerator()->create_user();
573         $user3 = self::getDataGenerator()->create_user();
575         // Send some messages back and forth, have some different conversations with different users.
576         $time = 1;
577         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
578         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
579         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
580         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
582         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
583         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
584         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
585         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
587         // Favourite the first conversation as user 1 and the second as user 3.
588         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
589         $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
590         \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
591         \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
593         // Verify we have a single favourite conversation for both user 1 and user 3.
594         $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
595         $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
597         // Now unfavourite the conversation as user 1.
598         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
600         // Verify we have a single favourite conversation user 3 only, and none for user1.
601         $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
602         $this->assertCount(0, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
604         // Try to favourite the same conversation again as user 1.
605         $this->expectException(\moodle_exception::class);
606         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
607     }
609     /**
610      * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
611      */
612     public function test_unset_favourite_conversation_not_favourite() {
613         // Create some users.
614         $user1 = self::getDataGenerator()->create_user();
615         $user2 = self::getDataGenerator()->create_user();
617         // Send some messages back and forth, have some different conversations with different users.
618         $time = 1;
619         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
620         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
621         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
622         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
624         // Now try to unfavourite the conversation as user 1.
625         $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
626         $this->expectException(\moodle_exception::class);
627         \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
628     }
630     /**
631      * Test verifying that a non-existent conversation cannot be unset as a favourite.
632      */
633     public function test_unset_favourite_conversation_non_existent_conversation() {
634         // Create some users.
635         $user1 = self::getDataGenerator()->create_user();
637         // Now try to unfavourite the conversation as user 1.
638         $this->expectException(\moodle_exception::class);
639         \core_message\api::unset_favourite_conversation(0, $user1->id);
640     }
642     /**
643      * Tests retrieving conversations.
644      */
645     public function test_get_conversations() {
646         // Create some users.
647         $user1 = self::getDataGenerator()->create_user();
648         $user2 = self::getDataGenerator()->create_user();
649         $user3 = self::getDataGenerator()->create_user();
650         $user4 = self::getDataGenerator()->create_user();
652         // The person doing the search.
653         $this->setUser($user1);
655         // No conversations yet.
656         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
658         // Send some messages back and forth, have some different conversations with different users.
659         $time = 1;
660         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
661         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
662         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
663         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
665         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
666         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
667         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
668         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
670         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
671         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
672         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
674         // Retrieve the conversations.
675         $conversations = \core_message\api::get_conversations($user1->id);
677         // Confirm the data is correct.
678         $this->assertEquals(3, count($conversations));
680         $message1 = array_shift($conversations);
681         $message2 = array_shift($conversations);
682         $message3 = array_shift($conversations);
684         $this->assertEquals($user4->id, $message1->userid);
685         $this->assertEquals($user1->id, $message1->useridfrom);
686         $this->assertTrue($message1->ismessaging);
687         $this->assertEquals('Dope.', $message1->lastmessage);
688         $this->assertEquals($messageid3, $message1->messageid);
689         $this->assertNull($message1->isonline);
690         $this->assertFalse($message1->isread);
691         $this->assertFalse($message1->isblocked);
692         $this->assertEquals(1, $message1->unreadcount);
694         $this->assertEquals($user3->id, $message2->userid);
695         $this->assertEquals($user3->id, $message2->useridfrom);
696         $this->assertTrue($message2->ismessaging);
697         $this->assertEquals('Cool.', $message2->lastmessage);
698         $this->assertEquals($messageid2, $message2->messageid);
699         $this->assertNull($message2->isonline);
700         $this->assertFalse($message2->isread);
701         $this->assertFalse($message2->isblocked);
702         $this->assertEquals(2, $message2->unreadcount);
704         $this->assertEquals($user2->id, $message3->userid);
705         $this->assertEquals($user2->id, $message3->useridfrom);
706         $this->assertTrue($message3->ismessaging);
707         $this->assertEquals('Word.', $message3->lastmessage);
708         $this->assertEquals($messageid1, $message3->messageid);
709         $this->assertNull($message3->isonline);
710         $this->assertFalse($message3->isread);
711         $this->assertFalse($message3->isblocked);
712         $this->assertEquals(2, $message3->unreadcount);
713     }
715     /**
716      * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
717      */
718     public function test_get_conversations_limit_offset() {
719         // Create some users.
720         $user1 = self::getDataGenerator()->create_user();
721         $user2 = self::getDataGenerator()->create_user();
722         $user3 = self::getDataGenerator()->create_user();
723         $user4 = self::getDataGenerator()->create_user();
725         // The person doing the search.
726         $this->setUser($user1);
728         // Send some messages back and forth, have some different conversations with different users.
729         $time = 1;
730         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
731         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
732         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
733         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
735         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
736         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
737         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
738         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
740         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
741         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
742         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
744         // Retrieve the conversations.
745         $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
747         // We should only have one conversation because of the limit.
748         $this->assertCount(1, $conversations);
750         $conversation = array_shift($conversations);
752         $this->assertEquals($user3->id, $conversation->userid);
753         $this->assertEquals($user3->id, $conversation->useridfrom);
754         $this->assertTrue($conversation->ismessaging);
755         $this->assertEquals('Cool.', $conversation->lastmessage);
756         $this->assertEquals($messageid2, $conversation->messageid);
757         $this->assertNull($conversation->isonline);
758         $this->assertFalse($conversation->isread);
759         $this->assertFalse($conversation->isblocked);
760         $this->assertEquals(2, $conversation->unreadcount);
762         // Retrieve the next conversation.
763         $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
765         // We should only have one conversation because of the limit.
766         $this->assertCount(1, $conversations);
768         $conversation = array_shift($conversations);
770         $this->assertEquals($user2->id, $conversation->userid);
771         $this->assertEquals($user2->id, $conversation->useridfrom);
772         $this->assertTrue($conversation->ismessaging);
773         $this->assertEquals('Word.', $conversation->lastmessage);
774         $this->assertEquals($messageid1, $conversation->messageid);
775         $this->assertNull($conversation->isonline);
776         $this->assertFalse($conversation->isread);
777         $this->assertFalse($conversation->isblocked);
778         $this->assertEquals(2, $conversation->unreadcount);
780         // Ask for an offset that doesn't exist.
781         $conversations = \core_message\api::get_conversations($user1->id, 4, 1);
783         // We should not get any conversations back.
784         $this->assertCount(0, $conversations);
785     }
787     /**
788      * Tests retrieving conversations when a conversation contains a deleted user.
789      */
790     public function test_get_conversations_with_deleted_user() {
791         // Create some users.
792         $user1 = self::getDataGenerator()->create_user();
793         $user2 = self::getDataGenerator()->create_user();
794         $user3 = self::getDataGenerator()->create_user();
796         // Send some messages back and forth, have some different conversations with different users.
797         $time = 1;
798         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
799         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
800         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
801         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
803         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
804         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
805         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
806         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
808         // Delete the second user.
809         delete_user($user2);
811         // Retrieve the conversations.
812         $conversations = \core_message\api::get_conversations($user1->id);
814         // We should only have one conversation because the other user was deleted.
815         $this->assertCount(1, $conversations);
817         // Confirm the conversation is from the non-deleted user.
818         $conversation = reset($conversations);
819         $this->assertEquals($user3->id, $conversation->userid);
820     }
822    /**
823     * The data provider for get_conversations_mixed.
824     *
825     * This provides sets of data to for testing.
826     * @return array
827     */
828    public function get_conversations_mixed_provider() {
829        return array(
830             'Test that conversations with messages contacts is correctly ordered.' => array(
831                 'users' => array(
832                     'user1',
833                     'user2',
834                     'user3',
835                 ),
836                 'contacts' => array(
837                 ),
838                 'messages' => array(
839                     array(
840                         'from'          => 'user1',
841                         'to'            => 'user2',
842                         'state'         => 'unread',
843                         'subject'       => 'S1',
844                     ),
845                     array(
846                         'from'          => 'user2',
847                         'to'            => 'user1',
848                         'state'         => 'unread',
849                         'subject'       => 'S2',
850                     ),
851                     array(
852                         'from'          => 'user1',
853                         'to'            => 'user2',
854                         'state'         => 'unread',
855                         'timecreated'   => 0,
856                         'subject'       => 'S3',
857                     ),
858                     array(
859                         'from'          => 'user1',
860                         'to'            => 'user3',
861                         'state'         => 'read',
862                         'timemodifier'  => 1,
863                         'subject'       => 'S4',
864                     ),
865                     array(
866                         'from'          => 'user3',
867                         'to'            => 'user1',
868                         'state'         => 'read',
869                         'timemodifier'  => 1,
870                         'subject'       => 'S5',
871                     ),
872                     array(
873                         'from'          => 'user1',
874                         'to'            => 'user3',
875                         'state'         => 'read',
876                         'timecreated'   => 0,
877                         'subject'       => 'S6',
878                     ),
879                 ),
880                 'expectations' => array(
881                     'user1' => array(
882                         // User1 has conversed most recently with user3. The most recent message is M5.
883                         array(
884                             'messageposition'   => 0,
885                             'with'              => 'user3',
886                             'subject'           => 'S5',
887                             'unreadcount'       => 0,
888                         ),
889                         // User1 has also conversed with user2. The most recent message is S2.
890                         array(
891                             'messageposition'   => 1,
892                             'with'              => 'user2',
893                             'subject'           => 'S2',
894                             'unreadcount'       => 1,
895                         ),
896                     ),
897                     'user2' => array(
898                         // User2 has only conversed with user1. Their most recent shared message was S2.
899                         array(
900                             'messageposition'   => 0,
901                             'with'              => 'user1',
902                             'subject'           => 'S2',
903                             'unreadcount'       => 2,
904                         ),
905                     ),
906                     'user3' => array(
907                         // User3 has only conversed with user1. Their most recent shared message was S5.
908                         array(
909                             'messageposition'   => 0,
910                             'with'              => 'user1',
911                             'subject'           => 'S5',
912                             'unreadcount'       => 0,
913                         ),
914                     ),
915                 ),
916             ),
917             'Test that users with contacts and messages to self work as expected' => array(
918                 'users' => array(
919                     'user1',
920                     'user2',
921                     'user3',
922                 ),
923                 'contacts' => array(
924                     'user1' => array(
925                         'user2' => 0,
926                         'user3' => 0,
927                     ),
928                     'user2' => array(
929                         'user3' => 0,
930                     ),
931                 ),
932                 'messages' => array(
933                     array(
934                         'from'          => 'user1',
935                         'to'            => 'user1',
936                         'state'         => 'unread',
937                         'subject'       => 'S1',
938                     ),
939                     array(
940                         'from'          => 'user1',
941                         'to'            => 'user1',
942                         'state'         => 'unread',
943                         'subject'       => 'S2',
944                     ),
945                 ),
946                 'expectations' => array(
947                     'user1' => array(
948                         // User1 has conversed most recently with user1. The most recent message is S2.
949                         array(
950                             'messageposition'   => 0,
951                             'with'              => 'user1',
952                             'subject'           => 'S2',
953                             'unreadcount'       => 0, // Messages sent to and from the same user are counted as read.
954                         ),
955                     ),
956                 ),
957             ),
958             'Test conversations with a single user, where some messages are read and some are not.' => array(
959                 'users' => array(
960                     'user1',
961                     'user2',
962                 ),
963                 'contacts' => array(
964                 ),
965                 'messages' => array(
966                     array(
967                         'from'          => 'user1',
968                         'to'            => 'user2',
969                         'state'         => 'read',
970                         'subject'       => 'S1',
971                     ),
972                     array(
973                         'from'          => 'user2',
974                         'to'            => 'user1',
975                         'state'         => 'read',
976                         'subject'       => 'S2',
977                     ),
978                     array(
979                         'from'          => 'user1',
980                         'to'            => 'user2',
981                         'state'         => 'unread',
982                         'timemodifier'  => 1,
983                         'subject'       => 'S3',
984                     ),
985                     array(
986                         'from'          => 'user1',
987                         'to'            => 'user2',
988                         'state'         => 'unread',
989                         'timemodifier'  => 1,
990                         'subject'       => 'S4',
991                     ),
992                 ),
993                 'expectations' => array(
994                     // The most recent message between user1 and user2 was S4.
995                     'user1' => array(
996                         array(
997                             'messageposition'   => 0,
998                             'with'              => 'user2',
999                             'subject'           => 'S4',
1000                             'unreadcount'       => 0,
1001                         ),
1002                     ),
1003                     'user2' => array(
1004                         // The most recent message between user1 and user2 was S4.
1005                         array(
1006                             'messageposition'   => 0,
1007                             'with'              => 'user1',
1008                             'subject'           => 'S4',
1009                             'unreadcount'       => 2,
1010                         ),
1011                     ),
1012                 ),
1013             ),
1014             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1015             'are out of order' => array(
1016             // This can happen through a combination of factors including multi-master DB replication with messages
1017             // read somehow (e.g. API).
1018                 'users' => array(
1019                     'user1',
1020                     'user2',
1021                 ),
1022                 'contacts' => array(
1023                 ),
1024                 'messages' => array(
1025                     array(
1026                         'from'          => 'user1',
1027                         'to'            => 'user2',
1028                         'state'         => 'read',
1029                         'subject'       => 'S1',
1030                         'timemodifier'  => 1,
1031                     ),
1032                     array(
1033                         'from'          => 'user2',
1034                         'to'            => 'user1',
1035                         'state'         => 'read',
1036                         'subject'       => 'S2',
1037                         'timemodifier'  => 2,
1038                     ),
1039                     array(
1040                         'from'          => 'user1',
1041                         'to'            => 'user2',
1042                         'state'         => 'unread',
1043                         'subject'       => 'S3',
1044                     ),
1045                     array(
1046                         'from'          => 'user1',
1047                         'to'            => 'user2',
1048                         'state'         => 'unread',
1049                         'subject'       => 'S4',
1050                     ),
1051                 ),
1052                 'expectations' => array(
1053                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1054                     'user1' => array(
1055                         array(
1056                             'messageposition'   => 0,
1057                             'with'              => 'user2',
1058                             'subject'           => 'S2',
1059                             'unreadcount'       => 0,
1060                         ),
1061                     ),
1062                     'user2' => array(
1063                         array(
1064                             'messageposition'   => 0,
1065                             'with'              => 'user1',
1066                             'subject'           => 'S2',
1067                             'unreadcount'       => 2
1068                         ),
1069                     ),
1070                 ),
1071             ),
1072             'Test unread message count is correct for both users' => array(
1073                 'users' => array(
1074                     'user1',
1075                     'user2',
1076                 ),
1077                 'contacts' => array(
1078                 ),
1079                 'messages' => array(
1080                     array(
1081                         'from'          => 'user1',
1082                         'to'            => 'user2',
1083                         'state'         => 'read',
1084                         'subject'       => 'S1',
1085                         'timemodifier'  => 1,
1086                     ),
1087                     array(
1088                         'from'          => 'user2',
1089                         'to'            => 'user1',
1090                         'state'         => 'read',
1091                         'subject'       => 'S2',
1092                         'timemodifier'  => 2,
1093                     ),
1094                     array(
1095                         'from'          => 'user1',
1096                         'to'            => 'user2',
1097                         'state'         => 'read',
1098                         'subject'       => 'S3',
1099                         'timemodifier'  => 3,
1100                     ),
1101                     array(
1102                         'from'          => 'user1',
1103                         'to'            => 'user2',
1104                         'state'         => 'read',
1105                         'subject'       => 'S4',
1106                         'timemodifier'  => 4,
1107                     ),
1108                     array(
1109                         'from'          => 'user1',
1110                         'to'            => 'user2',
1111                         'state'         => 'unread',
1112                         'subject'       => 'S5',
1113                         'timemodifier'  => 5,
1114                     ),
1115                     array(
1116                         'from'          => 'user2',
1117                         'to'            => 'user1',
1118                         'state'         => 'unread',
1119                         'subject'       => 'S6',
1120                         'timemodifier'  => 6,
1121                     ),
1122                     array(
1123                         'from'          => 'user1',
1124                         'to'            => 'user2',
1125                         'state'         => 'unread',
1126                         'subject'       => 'S7',
1127                         'timemodifier'  => 7,
1128                     ),
1129                     array(
1130                         'from'          => 'user1',
1131                         'to'            => 'user2',
1132                         'state'         => 'unread',
1133                         'subject'       => 'S8',
1134                         'timemodifier'  => 8,
1135                     ),
1136                 ),
1137                 'expectations' => array(
1138                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1139                     'user1' => array(
1140                         array(
1141                             'messageposition'   => 0,
1142                             'with'              => 'user2',
1143                             'subject'           => 'S8',
1144                             'unreadcount'       => 1,
1145                         ),
1146                     ),
1147                     'user2' => array(
1148                         array(
1149                             'messageposition'   => 0,
1150                             'with'              => 'user1',
1151                             'subject'           => 'S8',
1152                             'unreadcount'       => 3,
1153                         ),
1154                     ),
1155                 ),
1156             ),
1157         );
1158     }
1160     /**
1161      * Test get_conversations with a mixture of messages.
1162      *
1163      * @dataProvider get_conversations_mixed_provider
1164      * @param array $usersdata The list of users to create for this test.
1165      * @param array $messagesdata The list of messages to create.
1166      * @param array $expectations The list of expected outcomes.
1167      */
1168     public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1169         global $DB;
1171         // Create all of the users.
1172         $users = array();
1173         foreach ($usersdata as $username) {
1174             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1175         }
1177         foreach ($contacts as $username => $contact) {
1178             foreach ($contact as $contactname => $blocked) {
1179                 $record = new stdClass();
1180                 $record->userid     = $users[$username]->id;
1181                 $record->contactid  = $users[$contactname]->id;
1182                 $record->blocked    = $blocked;
1183                 $record->id = $DB->insert_record('message_contacts', $record);
1184             }
1185         }
1187         $defaulttimecreated = time();
1188         foreach ($messagesdata as $messagedata) {
1189             $from       = $users[$messagedata['from']];
1190             $to         = $users[$messagedata['to']];
1191             $subject    = $messagedata['subject'];
1193             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
1194                 $messageid = $this->send_fake_message($from, $to, $subject);
1195             } else {
1196                 // If there is no state, or the state is not 'unread', assume the message is read.
1197                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
1198             }
1200             $updatemessage = new stdClass();
1201             $updatemessage->id = $messageid;
1202             if (isset($messagedata['timecreated'])) {
1203                 $updatemessage->timecreated = $messagedata['timecreated'];
1204             } else if (isset($messagedata['timemodifier'])) {
1205                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
1206             } else {
1207                 $updatemessage->timecreated = $defaulttimecreated;
1208             }
1210             $DB->update_record('messages', $updatemessage);
1211         }
1213         foreach ($expectations as $username => $data) {
1214             // Get the recent conversations for the specified user.
1215             $user = $users[$username];
1216             $conversations = array_values(\core_message\api::get_conversations($user->id));
1217             foreach ($data as $expectation) {
1218                 $otheruser = $users[$expectation['with']];
1219                 $conversation = $conversations[$expectation['messageposition']];
1220                 $this->assertEquals($otheruser->id, $conversation->userid);
1221                 $this->assertEquals($expectation['subject'], $conversation->lastmessage);
1222                 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
1223             }
1224         }
1225     }
1227     /**
1228      * Tests retrieving contacts.
1229      */
1230     public function test_get_contacts() {
1231         // Create some users.
1232         $user1 = self::getDataGenerator()->create_user();
1234         // Set as the user.
1235         $this->setUser($user1);
1237         $user2 = new stdClass();
1238         $user2->firstname = 'User';
1239         $user2->lastname = 'A';
1240         $user2 = self::getDataGenerator()->create_user($user2);
1242         $user3 = new stdClass();
1243         $user3->firstname = 'User';
1244         $user3->lastname = 'B';
1245         $user3 = self::getDataGenerator()->create_user($user3);
1247         $user4 = new stdClass();
1248         $user4->firstname = 'User';
1249         $user4->lastname = 'C';
1250         $user4 = self::getDataGenerator()->create_user($user4);
1252         $user5 = new stdClass();
1253         $user5->firstname = 'User';
1254         $user5->lastname = 'D';
1255         $user5 = self::getDataGenerator()->create_user($user5);
1257         // Add some users as contacts.
1258         \core_message\api::add_contact($user1->id, $user2->id);
1259         \core_message\api::add_contact($user1->id, $user3->id);
1260         \core_message\api::add_contact($user1->id, $user4->id);
1262         // Retrieve the contacts.
1263         $contacts = \core_message\api::get_contacts($user1->id);
1265         // Confirm the data is correct.
1266         $this->assertEquals(3, count($contacts));
1267         usort($contacts, ['static', 'sort_contacts']);
1269         $contact1 = $contacts[0];
1270         $contact2 = $contacts[1];
1271         $contact3 = $contacts[2];
1273         $this->assertEquals($user2->id, $contact1->userid);
1274         $this->assertEmpty($contact1->useridfrom);
1275         $this->assertFalse($contact1->ismessaging);
1276         $this->assertNull($contact1->lastmessage);
1277         $this->assertNull($contact1->messageid);
1278         $this->assertNull($contact1->isonline);
1279         $this->assertFalse($contact1->isread);
1280         $this->assertFalse($contact1->isblocked);
1281         $this->assertNull($contact1->unreadcount);
1283         $this->assertEquals($user3->id, $contact2->userid);
1284         $this->assertEmpty($contact2->useridfrom);
1285         $this->assertFalse($contact2->ismessaging);
1286         $this->assertNull($contact2->lastmessage);
1287         $this->assertNull($contact2->messageid);
1288         $this->assertNull($contact2->isonline);
1289         $this->assertFalse($contact2->isread);
1290         $this->assertFalse($contact2->isblocked);
1291         $this->assertNull($contact2->unreadcount);
1293         $this->assertEquals($user4->id, $contact3->userid);
1294         $this->assertEmpty($contact3->useridfrom);
1295         $this->assertFalse($contact3->ismessaging);
1296         $this->assertNull($contact3->lastmessage);
1297         $this->assertNull($contact3->messageid);
1298         $this->assertNull($contact3->isonline);
1299         $this->assertFalse($contact3->isread);
1300         $this->assertFalse($contact3->isblocked);
1301         $this->assertNull($contact3->unreadcount);
1302     }
1304     /**
1305      * Tests retrieving messages.
1306      */
1307     public function test_get_messages() {
1308         // Create some users.
1309         $user1 = self::getDataGenerator()->create_user();
1310         $user2 = self::getDataGenerator()->create_user();
1312         // The person doing the search.
1313         $this->setUser($user1);
1315         // Send some messages back and forth.
1316         $time = 1;
1317         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1318         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1319         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1320         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1322         // Retrieve the messages.
1323         $messages = \core_message\api::get_messages($user1->id, $user2->id);
1325         // Confirm the message data is correct.
1326         $this->assertEquals(4, count($messages));
1328         $message1 = $messages[0];
1329         $message2 = $messages[1];
1330         $message3 = $messages[2];
1331         $message4 = $messages[3];
1333         $this->assertEquals($user1->id, $message1->useridfrom);
1334         $this->assertEquals($user2->id, $message1->useridto);
1335         $this->assertTrue($message1->displayblocktime);
1336         $this->assertContains('Yo!', $message1->text);
1338         $this->assertEquals($user2->id, $message2->useridfrom);
1339         $this->assertEquals($user1->id, $message2->useridto);
1340         $this->assertFalse($message2->displayblocktime);
1341         $this->assertContains('Sup mang?', $message2->text);
1343         $this->assertEquals($user1->id, $message3->useridfrom);
1344         $this->assertEquals($user2->id, $message3->useridto);
1345         $this->assertFalse($message3->displayblocktime);
1346         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1348         $this->assertEquals($user2->id, $message4->useridfrom);
1349         $this->assertEquals($user1->id, $message4->useridto);
1350         $this->assertFalse($message4->displayblocktime);
1351         $this->assertContains('Word.', $message4->text);
1352     }
1354     /**
1355      * Tests retrieving most recent message.
1356      */
1357     public function test_get_most_recent_message() {
1358         // Create some users.
1359         $user1 = self::getDataGenerator()->create_user();
1360         $user2 = self::getDataGenerator()->create_user();
1362         // The person doing the search.
1363         $this->setUser($user1);
1365         // Send some messages back and forth.
1366         $time = 1;
1367         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1368         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1369         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1370         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1372         // Retrieve the most recent messages.
1373         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1375         // Check the results are correct.
1376         $this->assertEquals($user2->id, $message->useridfrom);
1377         $this->assertEquals($user1->id, $message->useridto);
1378         $this->assertContains('Word.', $message->text);
1379     }
1381     /**
1382      * Tests retrieving a user's profile.
1383      */
1384     public function test_get_profile() {
1385         // Create some users.
1386         $user1 = self::getDataGenerator()->create_user();
1388         $user2 = new stdClass();
1389         $user2->country = 'AU';
1390         $user2->city = 'Perth';
1391         $user2 = self::getDataGenerator()->create_user($user2);
1393         // The person doing the search.
1394         $this->setUser($user1);
1396         // Get the profile.
1397         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1399         $this->assertEquals($user2->id, $profile->userid);
1400         $this->assertEmpty($profile->email);
1401         $this->assertEmpty($profile->country);
1402         $this->assertEmpty($profile->city);
1403         $this->assertEquals(fullname($user2), $profile->fullname);
1404         $this->assertNull($profile->isonline);
1405         $this->assertFalse($profile->isblocked);
1406         $this->assertFalse($profile->iscontact);
1407     }
1409     /**
1410      * Tests retrieving a user's profile.
1411      */
1412     public function test_get_profile_as_admin() {
1413         // The person doing the search.
1414         $this->setAdminUser();
1416         // Create some users.
1417         $user1 = self::getDataGenerator()->create_user();
1419         $user2 = new stdClass();
1420         $user2->country = 'AU';
1421         $user2->city = 'Perth';
1422         $user2 = self::getDataGenerator()->create_user($user2);
1424         // Get the profile.
1425         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1427         $this->assertEquals($user2->id, $profile->userid);
1428         $this->assertEquals($user2->email, $profile->email);
1429         $this->assertEquals($user2->country, $profile->country);
1430         $this->assertEquals($user2->city, $profile->city);
1431         $this->assertEquals(fullname($user2), $profile->fullname);
1432         $this->assertFalse($profile->isonline);
1433         $this->assertFalse($profile->isblocked);
1434         $this->assertFalse($profile->iscontact);
1435     }
1437     /**
1438      * Tests checking if a user can mark all messages as read.
1439      */
1440     public function test_can_mark_all_messages_as_read() {
1441         // Set as the admin.
1442         $this->setAdminUser();
1444         // Create some users.
1445         $user1 = self::getDataGenerator()->create_user();
1446         $user2 = self::getDataGenerator()->create_user();
1447         $user3 = self::getDataGenerator()->create_user();
1449         // Send some messages back and forth.
1450         $time = 1;
1451         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1452         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1453         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1454         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1456         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1458         // The admin can do anything.
1459         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1461         // Set as the user 1.
1462         $this->setUser($user1);
1464         // The user can mark the messages as he is in the conversation.
1465         $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
1467         // User 1 can not mark the messages read for user 2.
1468         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
1470         // This user is not a part of the conversation.
1471         $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
1472     }
1474     /**
1475      * Tests checking if a user can delete a conversation.
1476      */
1477     public function test_can_delete_conversation() {
1478         // Set as the admin.
1479         $this->setAdminUser();
1481         // Create some users.
1482         $user1 = self::getDataGenerator()->create_user();
1483         $user2 = self::getDataGenerator()->create_user();
1485         // Send some messages back and forth.
1486         $time = 1;
1487         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1488         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1489         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1490         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1492         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1494         // The admin can do anything.
1495         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1497         // Set as the user 1.
1498         $this->setUser($user1);
1500         // They can delete their own messages.
1501         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1503         // They can't delete someone elses.
1504         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
1505     }
1507     /**
1508      * Tests deleting a conversation.
1509      */
1510     public function test_delete_conversation() {
1511         global $DB;
1513         // Create some users.
1514         $user1 = self::getDataGenerator()->create_user();
1515         $user2 = self::getDataGenerator()->create_user();
1517         // The person doing the search.
1518         $this->setUser($user1);
1520         // Send some messages back and forth.
1521         $time = 1;
1522         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1523         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1524         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1525         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1527         // Delete the conversation as user 1.
1528         \core_message\api::delete_conversation($user1->id, $user2->id);
1529         $this->assertDebuggingCalled();
1531         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1532         $this->assertCount(4, $muas);
1533         // Sort by id.
1534         ksort($muas);
1536         $mua1 = array_shift($muas);
1537         $mua2 = array_shift($muas);
1538         $mua3 = array_shift($muas);
1539         $mua4 = array_shift($muas);
1541         $this->assertEquals($user1->id, $mua1->userid);
1542         $this->assertEquals($m1id, $mua1->messageid);
1543         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1545         $this->assertEquals($user1->id, $mua2->userid);
1546         $this->assertEquals($m2id, $mua2->messageid);
1547         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1549         $this->assertEquals($user1->id, $mua3->userid);
1550         $this->assertEquals($m3id, $mua3->messageid);
1551         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1553         $this->assertEquals($user1->id, $mua4->userid);
1554         $this->assertEquals($m4id, $mua4->messageid);
1555         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1556     }
1558     /**
1559      * Tests deleting a conversation by conversation id.
1560      */
1561     public function test_delete_conversation_by_id() {
1562         global $DB;
1564         // Create some users.
1565         $user1 = self::getDataGenerator()->create_user();
1566         $user2 = self::getDataGenerator()->create_user();
1568         // The person doing the search.
1569         $this->setUser($user1);
1571         // Send some messages back and forth.
1572         $time = 1;
1573         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1574         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1575         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1576         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1578         // Delete the conversation as user 1.
1579         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1580         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
1582         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1583         $this->assertCount(4, $muas);
1584         // Sort by id.
1585         ksort($muas);
1587         $mua1 = array_shift($muas);
1588         $mua2 = array_shift($muas);
1589         $mua3 = array_shift($muas);
1590         $mua4 = array_shift($muas);
1592         $this->assertEquals($user1->id, $mua1->userid);
1593         $this->assertEquals($m1id, $mua1->messageid);
1594         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1596         $this->assertEquals($user1->id, $mua2->userid);
1597         $this->assertEquals($m2id, $mua2->messageid);
1598         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1600         $this->assertEquals($user1->id, $mua3->userid);
1601         $this->assertEquals($m3id, $mua3->messageid);
1602         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1604         $this->assertEquals($user1->id, $mua4->userid);
1605         $this->assertEquals($m4id, $mua4->messageid);
1606         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1607     }
1609     /**
1610      * Tests counting unread conversations.
1611      */
1612     public function test_count_unread_conversations() {
1613         $this->resetAfterTest(true);
1615         // Create some users.
1616         $user1 = self::getDataGenerator()->create_user();
1617         $user2 = self::getDataGenerator()->create_user();
1618         $user3 = self::getDataGenerator()->create_user();
1619         $user4 = self::getDataGenerator()->create_user();
1621         // The person wanting the conversation count.
1622         $this->setUser($user1);
1624         // Send some messages back and forth, have some different conversations with different users.
1625         $this->send_fake_message($user1, $user2, 'Yo!');
1626         $this->send_fake_message($user2, $user1, 'Sup mang?');
1627         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
1628         $this->send_fake_message($user2, $user1, 'Word.');
1630         $this->send_fake_message($user1, $user3, 'Booyah');
1631         $this->send_fake_message($user3, $user1, 'Whaaat?');
1632         $this->send_fake_message($user1, $user3, 'Nothing.');
1633         $this->send_fake_message($user3, $user1, 'Cool.');
1635         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
1636         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
1637         $this->send_fake_message($user1, $user4, 'Dope.');
1639         // Check the amount for the current user.
1640         $this->assertEquals(3, core_message\api::count_unread_conversations());
1642         // Check the amount for the second user.
1643         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
1644     }
1646     /**
1647      * Tests deleting a conversation.
1648      */
1649     public function test_get_all_message_preferences() {
1650         $user = self::getDataGenerator()->create_user();
1651         $this->setUser($user);
1653         // Set a couple of preferences to test.
1654         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
1655         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
1657         $processors = get_message_processors();
1658         $providers = message_get_providers_for_user($user->id);
1659         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
1661         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
1662         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
1663     }
1665     /**
1666      * Tests the user can post a message.
1667      */
1668     public function test_can_post_message() {
1669         // Create some users.
1670         $user1 = self::getDataGenerator()->create_user();
1671         $user2 = self::getDataGenerator()->create_user();
1673         // Set as the first user.
1674         $this->setUser($user1);
1676         // With the default privacy setting, users can't message them.
1677         $this->assertFalse(\core_message\api::can_post_message($user2));
1679         // Enrol users to the same course.
1680         $course = $this->getDataGenerator()->create_course();
1681         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1682         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1683         // After enrolling users to the course, they should be able to message them with the default privacy setting.
1684         $this->assertTrue(\core_message\api::can_post_message($user2));
1685     }
1687     /**
1688      * Tests the user can't post a message without proper capability.
1689      */
1690     public function test_can_post_message_without_sendmessage_cap() {
1691         global $DB;
1693         // Create some users.
1694         $user1 = self::getDataGenerator()->create_user();
1695         $user2 = self::getDataGenerator()->create_user();
1697         // Set as the user 1.
1698         $this->setUser($user1);
1700         // Remove the capability to send a message.
1701         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
1702         unassign_capability('moodle/site:sendmessage', $roleids['user'],
1703             context_system::instance());
1705         // Check that we can not post a message without the capability.
1706         $this->assertFalse(\core_message\api::can_post_message($user2));
1707     }
1709     /**
1710      * Tests the user can post a message when they are contact.
1711      */
1712     public function test_can_post_message_when_contact() {
1713         // Create some users.
1714         $user1 = self::getDataGenerator()->create_user();
1715         $user2 = self::getDataGenerator()->create_user();
1717         // Set as the first user.
1718         $this->setUser($user1);
1720         // Check that we can not send user2 a message.
1721         $this->assertFalse(\core_message\api::can_post_message($user2));
1723         // Add users as contacts.
1724         \core_message\api::add_contact($user1->id, $user2->id);
1726         // Check that the return result is now true.
1727         $this->assertTrue(\core_message\api::can_post_message($user2));
1728     }
1730     /**
1731      * Tests the user can't post a message if they are not a contact and the user
1732      * has requested messages only from contacts.
1733      */
1734     public function test_can_post_message_when_not_contact() {
1735         // Create some users.
1736         $user1 = self::getDataGenerator()->create_user();
1737         $user2 = self::getDataGenerator()->create_user();
1739         // Set as the first user.
1740         $this->setUser($user1);
1742         // Set the second user's preference to not receive messages from non-contacts.
1743         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1745         // Check that we can not send user 2 a message.
1746         $this->assertFalse(\core_message\api::can_post_message($user2));
1747     }
1749     /**
1750      * Tests the user can't post a message if they are blocked.
1751      */
1752     public function test_can_post_message_when_blocked() {
1753         // Create some users.
1754         $user1 = self::getDataGenerator()->create_user();
1755         $user2 = self::getDataGenerator()->create_user();
1757         // Set the user.
1758         $this->setUser($user1);
1760         // Block the second user.
1761         \core_message\api::block_user($user1->id, $user2->id);
1763         // Check that the second user can no longer send the first user a message.
1764         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
1765     }
1767     /**
1768      * Tests the user can post a message when site-wide messaging setting is enabled,
1769      * even if they are not a contact and are not members of the same course.
1770      */
1771     public function test_can_post_message_site_messaging_setting() {
1772         // Create some users.
1773         $user1 = self::getDataGenerator()->create_user();
1774         $user2 = self::getDataGenerator()->create_user();
1776         // Set as the first user.
1777         $this->setUser($user1);
1779         // By default, user only can be messaged by contacts and members of any of his/her courses.
1780         $this->assertFalse(\core_message\api::can_post_message($user2));
1782         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
1783         set_config('messagingallusers', true);
1785         // Set the second user's preference to receive messages from everybody.
1786         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
1788         // Check that we can send user2 a message.
1789         $this->assertTrue(\core_message\api::can_post_message($user2));
1791         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
1792         // and members sharing a course with her.
1793         set_config('messagingallusers', false);
1795         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
1796         $this->assertFalse(\core_message\api::can_post_message($user2));
1798         // Enrol users to the same course.
1799         $course = $this->getDataGenerator()->create_course();
1800         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1801         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1802         // Check that we can send user2 a message because they are sharing a course.
1803         $this->assertTrue(\core_message\api::can_post_message($user2));
1805         // Set the second user's preference to receive messages only from contacts.
1806         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1807         // Check that now the user2 can't be contacted because user1 is not their contact.
1808         $this->assertFalse(\core_message\api::can_post_message($user2));
1810         // Make contacts user1 and user2.
1811         \core_message\api::add_contact($user2->id, $user1->id);
1812         // Check that we can send user2 a message because they are contacts.
1813         $this->assertTrue(\core_message\api::can_post_message($user2));
1814     }
1816     /**
1817      * Tests the user with the messageanyuser capability can post a message.
1818      */
1819     public function test_can_post_message_with_messageanyuser_cap() {
1820         global $DB;
1822         // Create some users.
1823         $teacher1 = self::getDataGenerator()->create_user();
1824         $student1 = self::getDataGenerator()->create_user();
1825         $student2 = self::getDataGenerator()->create_user();
1827         // Create users not enrolled in any course.
1828         $user1 = self::getDataGenerator()->create_user();
1830         // Create a course.
1831         $course1 = $this->getDataGenerator()->create_course();
1833         // Enrol the users in the course.
1834         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
1835         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
1836         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
1838         // Set some student preferences to not receive messages from non-contacts.
1839         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
1841         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
1842         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
1843         // Check that the teacher can't contact user1 because it's not his teacher.
1844         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
1846         // Remove the messageanyuser capability from the course1 for teachers.
1847         $coursecontext = context_course::instance($course1->id);
1848         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
1849         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
1850         $coursecontext->mark_dirty();
1852         // Check that we can't send user1 a message because they are not contacts.
1853         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
1854         // However, teacher can message student2 because they are sharing a course.
1855         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
1856     }
1858     /**
1859      * Tests get_user_privacy_messaging_preference method.
1860      */
1861     public function test_get_user_privacy_messaging_preference() {
1862         // Create some users.
1863         $user1 = self::getDataGenerator()->create_user();
1864         $user2 = self::getDataGenerator()->create_user();
1865         $user3 = self::getDataGenerator()->create_user();
1867         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
1868         set_config('messagingallusers', true);
1870         // Set some user preferences.
1871         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
1872         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1874         // Check the returned value for each user.
1875         $this->assertEquals(
1876             \core_message\api::MESSAGE_PRIVACY_SITE,
1877             \core_message\api::get_user_privacy_messaging_preference($user1->id)
1878         );
1879         $this->assertEquals(
1880             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
1881             \core_message\api::get_user_privacy_messaging_preference($user2->id)
1882         );
1883         $this->assertEquals(
1884             \core_message\api::MESSAGE_PRIVACY_SITE,
1885             \core_message\api::get_user_privacy_messaging_preference($user3->id)
1886         );
1888         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
1889         set_config('messagingallusers', false);
1891         // Check the returned value for each user.
1892         $this->assertEquals(
1893             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
1894             \core_message\api::get_user_privacy_messaging_preference($user1->id)
1895         );
1896         $this->assertEquals(
1897             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
1898             \core_message\api::get_user_privacy_messaging_preference($user2->id)
1899         );
1900         $this->assertEquals(
1901             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
1902             \core_message\api::get_user_privacy_messaging_preference($user3->id)
1903         );
1904     }
1906     /**
1907      * Tests that when blocking messages from non-contacts is enabled that
1908      * non-contacts trying to send a message return false.
1909      */
1910     public function test_is_user_non_contact_blocked() {
1911         // Create some users.
1912         $user1 = self::getDataGenerator()->create_user();
1913         $user2 = self::getDataGenerator()->create_user();
1915         // Set as the first user.
1916         $this->setUser($user1);
1918         // By default, user only can be messaged by contacts and members of any of his/her courses.
1919         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
1920         $this->assertDebuggingCalled();
1922         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
1923         // messages from everybody.
1924         set_config('messagingallusers', true);
1925         // Check that the return result is now false because any site user can contact him/her.
1926         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1927         $this->assertDebuggingCalled();
1929         // Set the second user's preference to not receive messages from non-contacts.
1930         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1931         // Check that the return result is still true (because is even more restricted).
1932         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
1933         $this->assertDebuggingCalled();
1935         // Add the first user as a contact for the second user.
1936         \core_message\api::add_contact($user2->id, $user1->id);
1938         // Check that the return result is now false.
1939         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1940         $this->assertDebuggingCalled();
1942         // Set the second user's preference to receive messages from course members.
1943         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
1944         // Check that the return result is still false (because $user1 is still his/her contact).
1945         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1946         $this->assertDebuggingCalled();
1947     }
1949     /**
1950      * Tests that we return true when a user is blocked, or false
1951      * if they are not blocked.
1952      */
1953     public function test_is_user_blocked() {
1954         // Create some users.
1955         $user1 = self::getDataGenerator()->create_user();
1956         $user2 = self::getDataGenerator()->create_user();
1958         // Set the user.
1959         $this->setUser($user1);
1961         // User shouldn't be blocked.
1962         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1963         $this->assertDebuggingCalled();
1965         // Block the user.
1966         \core_message\api::block_user($user1->id, $user2->id);
1968         // User should be blocked.
1969         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
1970         $this->assertDebuggingCalled();
1972         // Unblock the user.
1973         \core_message\api::unblock_user($user1->id, $user2->id);
1974         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1975         $this->assertDebuggingCalled();
1976     }
1978     /**
1979      * Tests that the admin is not blocked even if someone has chosen to block them.
1980      */
1981     public function test_is_user_blocked_as_admin() {
1982         // Create a user.
1983         $user1 = self::getDataGenerator()->create_user();
1985         // Set the user.
1986         $this->setUser($user1);
1988         // Block the admin user.
1989         \core_message\api::block_user($user1->id, 2);
1991         // Now change to the admin user.
1992         $this->setAdminUser();
1994         // As the admin you should still be able to send messages to the user.
1995         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
1996         $this->assertDebuggingCalled();
1997     }
1999     /*
2000      * Tes get_message_processor api.
2001      */
2002     public function test_get_message_processor() {
2003         $processors = get_message_processors(true);
2004         if (empty($processors)) {
2005             $this->markTestSkipped("No message processors found");
2006         }
2008         $name = key($processors);
2009         $processor = current($processors);
2010         $testprocessor = \core_message\api::get_message_processor($name);
2011         $this->assertEquals($processor->name, $testprocessor->name);
2012         $this->assertEquals($processor->enabled, $testprocessor->enabled);
2013         $this->assertEquals($processor->available, $testprocessor->available);
2014         $this->assertEquals($processor->configured, $testprocessor->configured);
2016         // Disable processor and test.
2017         \core_message\api::update_processor_status($testprocessor, 0);
2018         $testprocessor = \core_message\api::get_message_processor($name, true);
2019         $this->assertEmpty($testprocessor);
2020         $testprocessor = \core_message\api::get_message_processor($name);
2021         $this->assertEquals($processor->name, $testprocessor->name);
2022         $this->assertEquals(0, $testprocessor->enabled);
2024         // Enable again and test.
2025         \core_message\api::update_processor_status($testprocessor, 1);
2026         $testprocessor = \core_message\api::get_message_processor($name, true);
2027         $this->assertEquals($processor->name, $testprocessor->name);
2028         $this->assertEquals(1, $testprocessor->enabled);
2029         $testprocessor = \core_message\api::get_message_processor($name);
2030         $this->assertEquals($processor->name, $testprocessor->name);
2031         $this->assertEquals(1, $testprocessor->enabled);
2032     }
2034     /**
2035      * Test method update_processor_status.
2036      */
2037     public function test_update_processor_status() {
2038         $processors = get_message_processors();
2039         if (empty($processors)) {
2040             $this->markTestSkipped("No message processors found");
2041         }
2042         $name = key($processors);
2043         $testprocessor = current($processors);
2045         // Enable.
2046         \core_message\api::update_processor_status($testprocessor, 1);
2047         $testprocessor = \core_message\api::get_message_processor($name);
2048         $this->assertEquals(1, $testprocessor->enabled);
2050         // Disable.
2051         \core_message\api::update_processor_status($testprocessor, 0);
2052         $testprocessor = \core_message\api::get_message_processor($name);
2053         $this->assertEquals(0, $testprocessor->enabled);
2055         // Enable again.
2056         \core_message\api::update_processor_status($testprocessor, 1);
2057         $testprocessor = \core_message\api::get_message_processor($name);
2058         $this->assertEquals(1, $testprocessor->enabled);
2059     }
2061     /**
2062      * Test method is_user_enabled.
2063      */
2064     public function is_user_enabled() {
2065         $processors = get_message_processors();
2066         if (empty($processors)) {
2067             $this->markTestSkipped("No message processors found");
2068         }
2069         $name = key($processors);
2070         $testprocessor = current($processors);
2072         // Enable.
2073         \core_message\api::update_processor_status($testprocessor, 1);
2074         $status = \core_message\api::is_processor_enabled($name);
2075         $this->assertEquals(1, $status);
2077         // Disable.
2078         \core_message\api::update_processor_status($testprocessor, 0);
2079         $status = \core_message\api::is_processor_enabled($name);
2080         $this->assertEquals(0, $status);
2082         // Enable again.
2083         \core_message\api::update_processor_status($testprocessor, 1);
2084         $status = \core_message\api::is_processor_enabled($name);
2085         $this->assertEquals(1, $status);
2086     }
2088     /**
2089      * Test retrieving messages by providing a minimum timecreated value.
2090      */
2091     public function test_get_messages_time_from_only() {
2092         // Create some users.
2093         $user1 = self::getDataGenerator()->create_user();
2094         $user2 = self::getDataGenerator()->create_user();
2096         // The person doing the search.
2097         $this->setUser($user1);
2099         // Send some messages back and forth.
2100         $time = 1;
2101         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2102         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2103         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2104         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2106         // Retrieve the messages from $time, which should be all of them.
2107         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
2109         // Confirm the message data is correct.
2110         $this->assertEquals(4, count($messages));
2112         $message1 = $messages[0];
2113         $message2 = $messages[1];
2114         $message3 = $messages[2];
2115         $message4 = $messages[3];
2117         $this->assertContains('Message 1', $message1->text);
2118         $this->assertContains('Message 2', $message2->text);
2119         $this->assertContains('Message 3', $message3->text);
2120         $this->assertContains('Message 4', $message4->text);
2122         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2123         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
2125         // Confirm the message data is correct.
2126         $this->assertEquals(2, count($messages));
2128         $message1 = $messages[0];
2129         $message2 = $messages[1];
2131         $this->assertContains('Message 3', $message1->text);
2132         $this->assertContains('Message 4', $message2->text);
2133     }
2135     /**
2136      * Test retrieving messages by providing a maximum timecreated value.
2137      */
2138     public function test_get_messages_time_to_only() {
2139         // Create some users.
2140         $user1 = self::getDataGenerator()->create_user();
2141         $user2 = self::getDataGenerator()->create_user();
2143         // The person doing the search.
2144         $this->setUser($user1);
2146         // Send some messages back and forth.
2147         $time = 1;
2148         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2149         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2150         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2151         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2153         // Retrieve the messages up until $time + 4, which should be all of them.
2154         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
2156         // Confirm the message data is correct.
2157         $this->assertEquals(4, count($messages));
2159         $message1 = $messages[0];
2160         $message2 = $messages[1];
2161         $message3 = $messages[2];
2162         $message4 = $messages[3];
2164         $this->assertContains('Message 1', $message1->text);
2165         $this->assertContains('Message 2', $message2->text);
2166         $this->assertContains('Message 3', $message3->text);
2167         $this->assertContains('Message 4', $message4->text);
2169         // Retrieve the messages up until $time + 2, which should be the first two.
2170         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
2172         // Confirm the message data is correct.
2173         $this->assertEquals(2, count($messages));
2175         $message1 = $messages[0];
2176         $message2 = $messages[1];
2178         $this->assertContains('Message 1', $message1->text);
2179         $this->assertContains('Message 2', $message2->text);
2180     }
2182     /**
2183      * Test retrieving messages by providing a minimum and maximum timecreated value.
2184      */
2185     public function test_get_messages_time_from_and_to() {
2186         // Create some users.
2187         $user1 = self::getDataGenerator()->create_user();
2188         $user2 = self::getDataGenerator()->create_user();
2190         // The person doing the search.
2191         $this->setUser($user1);
2193         // Send some messages back and forth.
2194         $time = 1;
2195         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
2196         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
2197         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
2198         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
2200         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2201         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
2203         // Confirm the message data is correct.
2204         $this->assertEquals(2, count($messages));
2206         $message1 = $messages[0];
2207         $message2 = $messages[1];
2209         $this->assertContains('Message 2', $message1->text);
2210         $this->assertContains('Message 3', $message2->text);
2211     }
2213     /**
2214      * Test returning blocked users.
2215      */
2216     public function test_get_blocked_users() {
2217         global $USER;
2219         // Set this user as the admin.
2220         $this->setAdminUser();
2222         // Create a user to add to the admin's contact list.
2223         $user1 = $this->getDataGenerator()->create_user();
2224         $user2 = $this->getDataGenerator()->create_user();
2226         // Add users to the admin's contact list.
2227         \core_message\api::block_user($USER->id, $user2->id);
2229         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2231         // Block other user.
2232         \core_message\api::block_user($USER->id, $user1->id);
2233         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
2235         // Test deleting users.
2236         delete_user($user1);
2237         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
2238     }
2240     /**
2241      * Test returning contacts with unread message count.
2242      */
2243     public function test_get_contacts_with_unread_message_count() {
2244         global $DB;
2246         $user1 = self::getDataGenerator()->create_user();
2247         $user2 = self::getDataGenerator()->create_user();
2248         $user3 = self::getDataGenerator()->create_user();
2249         $user4 = self::getDataGenerator()->create_user();
2251         // Add the users to each of their contacts.
2252         \core_message\api::add_contact($user1->id, $user2->id);
2253         \core_message\api::add_contact($user2->id, $user3->id);
2255         $this->send_fake_message($user1, $user2);
2256         $this->send_fake_message($user1, $user2);
2257         $this->send_fake_message($user1, $user2);
2258         $message4id = $this->send_fake_message($user1, $user2);
2260         $this->send_fake_message($user3, $user2);
2261         $message6id = $this->send_fake_message($user3, $user2);
2262         $this->send_fake_message($user3, $user2);
2263         $this->send_fake_message($user3, $user2);
2264         $this->send_fake_message($user3, $user2);
2266         // Send a message that should never be included as the user is not a contact.
2267         $this->send_fake_message($user4, $user2);
2269         // Get the contacts and the unread message count.
2270         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2272         // Confirm the size is correct.
2273         $this->assertCount(2, $messages);
2274         ksort($messages);
2276         $messageinfo1 = array_shift($messages);
2277         $messageinfo2 = array_shift($messages);
2279         $this->assertEquals($user1->id, $messageinfo1->id);
2280         $this->assertEquals(4, $messageinfo1->messagecount);
2281         $this->assertEquals($user3->id, $messageinfo2->id);
2282         $this->assertEquals(5, $messageinfo2->messagecount);
2284         // Mark some of the messages as read.
2285         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2286         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2287         \core_message\api::mark_message_as_read($user2->id, $m4);
2288         \core_message\api::mark_message_as_read($user2->id, $m6);
2290         // Get the contacts and the unread message count.
2291         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2293         // Confirm the size is correct.
2294         $this->assertCount(2, $messages);
2295         ksort($messages);
2297         // Confirm read messages are not included.
2298         $messageinfo1 = array_shift($messages);
2299         $messageinfo2 = array_shift($messages);
2300         $this->assertEquals($user1->id, $messageinfo1->id);
2301         $this->assertEquals(3, $messageinfo1->messagecount);
2302         $this->assertEquals($user3->id, $messageinfo2->id);
2303         $this->assertEquals(4, $messageinfo2->messagecount);
2305         // Now, let's populate the database with messages from user2 to user 1.
2306         $this->send_fake_message($user2, $user1);
2307         $this->send_fake_message($user2, $user1);
2308         $messageid = $this->send_fake_message($user2, $user1);
2310         // Send a message that should never be included as the user is not a contact.
2311         $this->send_fake_message($user4, $user1);
2313         // Get the contacts and the unread message count.
2314         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2316         // Confirm the size is correct.
2317         $this->assertCount(1, $messages);
2318         $messageinfo1 = array_shift($messages);
2319         $this->assertEquals($user2->id, $messageinfo1->id);
2320         $this->assertEquals(3, $messageinfo1->messagecount);
2322         // Mark the last message as read.
2323         $m = $DB->get_record('messages', ['id' => $messageid]);
2324         \core_message\api::mark_message_as_read($user1->id, $m);
2326         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
2328         // Confirm the size is correct.
2329         $this->assertCount(1, $messages);
2331         // Confirm read messages are not included.
2332         $messageinfo1 = array_shift($messages);
2333         $this->assertEquals($user2->id, $messageinfo1->id);
2334         $this->assertEquals(2, $messageinfo1->messagecount);
2335     }
2337     /**
2338      * Test returning contacts with unread message count when there are no messages.
2339      */
2340     public function test_get_contacts_with_unread_message_count_no_messages() {
2341         $user1 = self::getDataGenerator()->create_user();
2342         $user2 = self::getDataGenerator()->create_user();
2344         // Add the users to each of their contacts.
2345         \core_message\api::add_contact($user2->id, $user1->id);
2347         // Check we get the correct message count.
2348         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2350         // Confirm the size is correct.
2351         $this->assertCount(1, $messages);
2353         $messageinfo = array_shift($messages);
2355         $this->assertEquals($user1->id, $messageinfo->id);
2356         $this->assertEquals(0, $messageinfo->messagecount);
2357     }
2359     /**
2360      * Test returning non-contacts with unread message count.
2361      */
2362     public function test_get_non_contacts_with_unread_message_count() {
2363         global $DB;
2365         $user1 = self::getDataGenerator()->create_user();
2366         $user2 = self::getDataGenerator()->create_user();
2367         $user3 = self::getDataGenerator()->create_user();
2368         $user4 = self::getDataGenerator()->create_user();
2370         // Add a user to the contact list of the users we are testing this function with.
2371         \core_message\api::add_contact($user1->id, $user4->id);
2372         \core_message\api::add_contact($user2->id, $user4->id);
2374         $this->send_fake_message($user1, $user2);
2375         $this->send_fake_message($user1, $user2);
2376         $this->send_fake_message($user1, $user2);
2377         $message4id = $this->send_fake_message($user1, $user2);
2379         $this->send_fake_message($user3, $user2);
2380         $message6id = $this->send_fake_message($user3, $user2);
2381         $this->send_fake_message($user3, $user2);
2382         $this->send_fake_message($user3, $user2);
2383         $this->send_fake_message($user3, $user2);
2385         // Send a message that should never be included as the user is a contact.
2386         $this->send_fake_message($user4, $user2);
2388         // Get the non-contacts and the unread message count.
2389         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2391         // Check we get the correct message count.
2392         ksort($messages);
2393         $this->assertCount(2, $messages);
2394         $messageinfo1 = array_shift($messages);
2395         $messageinfo2 = array_shift($messages);
2396         $this->assertEquals($user1->id, $messageinfo1->id);
2397         $this->assertEquals(4, $messageinfo1->messagecount);
2398         $this->assertEquals($user3->id, $messageinfo2->id);
2399         $this->assertEquals(5, $messageinfo2->messagecount);
2401         // Mark some of the messages as read.
2402         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2403         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2404         \core_message\api::mark_message_as_read($user2->id, $m4);
2405         \core_message\api::mark_message_as_read($user2->id, $m6);
2407         // Get the non-contacts and the unread message count.
2408         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2410         // Check the marked message is not returned in the message count.
2411         ksort($messages);
2412         $this->assertCount(2, $messages);
2413         $messageinfo1 = array_shift($messages);
2414         $messageinfo2 = array_shift($messages);
2415         $this->assertEquals($user1->id, $messageinfo1->id);
2416         $this->assertEquals(3, $messageinfo1->messagecount);
2417         $this->assertEquals($user3->id, $messageinfo2->id);
2418         $this->assertEquals(4, $messageinfo2->messagecount);
2420         // Now, let's populate the database with messages from user2 to user 1.
2421         $this->send_fake_message($user2, $user1);
2422         $this->send_fake_message($user2, $user1);
2423         $messageid = $this->send_fake_message($user2, $user1);
2425         // Send a message that should never be included as the user is a contact.
2426         $this->send_fake_message($user4, $user1);
2428         // Get the non-contacts and the unread message count.
2429         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2431         // Confirm the size is correct.
2432         $this->assertCount(1, $messages);
2433         $messageinfo1 = array_shift($messages);
2434         $this->assertEquals($user2->id, $messageinfo1->id);
2435         $this->assertEquals(3, $messageinfo1->messagecount);
2437         // Mark the last message as read.
2438         $m = $DB->get_record('messages', ['id' => $messageid]);
2439         \core_message\api::mark_message_as_read($user1->id, $m);
2441         // Get the non-contacts and the unread message count.
2442         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2444         // Check the marked message is not returned in the message count.
2445         $this->assertCount(1, $messages);
2446         $messageinfo1 = array_shift($messages);
2447         $this->assertEquals($user2->id, $messageinfo1->id);
2448         $this->assertEquals(2, $messageinfo1->messagecount);
2449     }
2451     /**
2452      * Test marking a message as read.
2453      */
2454     public function test_mark_message_as_read() {
2455         global $DB;
2457         $user1 = self::getDataGenerator()->create_user();
2458         $user2 = self::getDataGenerator()->create_user();
2460         $this->send_fake_message($user1, $user2);
2461         $m2id = $this->send_fake_message($user1, $user2);
2462         $this->send_fake_message($user2, $user1);
2463         $m4id = $this->send_fake_message($user2, $user1);
2465         $m2 = $DB->get_record('messages', ['id' => $m2id]);
2466         $m4 = $DB->get_record('messages', ['id' => $m4id]);
2467         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
2468         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
2470         // Confirm there are two user actions.
2471         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
2472         $this->assertEquals(2, count($muas));
2474         // Confirm they are correct.
2475         $mua1 = array_shift($muas);
2476         $mua2 = array_shift($muas);
2478         // Confirm first action.
2479         $this->assertEquals($user2->id, $mua1->userid);
2480         $this->assertEquals($m2id, $mua1->messageid);
2481         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
2482         $this->assertEquals(11, $mua1->timecreated);
2484         // Confirm second action.
2485         $this->assertEquals($user1->id, $mua2->userid);
2486         $this->assertEquals($m4id, $mua2->messageid);
2487         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
2488         $this->assertEquals(12, $mua2->timecreated);
2489     }
2491     /**
2492      * Test marking a notification as read.
2493      */
2494     public function test_mark_notification_as_read() {
2495         global $DB;
2497         $user1 = self::getDataGenerator()->create_user();
2498         $user2 = self::getDataGenerator()->create_user();
2500         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
2501         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
2502         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
2503         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
2505         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2506         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2508         \core_message\api::mark_notification_as_read($n2, 11);
2509         \core_message\api::mark_notification_as_read($n4, 12);
2511         // Retrieve the notifications.
2512         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2513         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2515         // Confirm they have been marked as read.
2516         $this->assertEquals(11, $n2->timeread);
2517         $this->assertEquals(12, $n4->timeread);
2518     }
2520     /**
2521      * Test a conversation is not returned if there is none.
2522      */
2523     public function test_get_conversation_between_users_no_conversation() {
2524         $user1 = self::getDataGenerator()->create_user();
2525         $user2 = self::getDataGenerator()->create_user();
2527         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2528     }
2530     /**
2531      * Test we can return a conversation that exists between users.
2532      */
2533     public function test_get_conversation_between_users_with_existing_conversation() {
2534         $user1 = self::getDataGenerator()->create_user();
2535         $user2 = self::getDataGenerator()->create_user();
2537         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2538         $this->assertDebuggingCalled();
2540         $this->assertEquals($conversationid,
2541             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2542     }
2544     /**
2545      * Test count_conversation_members for non existing conversation.
2546      */
2547     public function test_count_conversation_members_no_existing_conversation() {
2548         $this->assertEquals(0,
2549             \core_message\api::count_conversation_members(0));
2550     }
2552     /**
2553      * Test count_conversation_members for existing conversation.
2554      */
2555     public function test_count_conversation_members_existing_conversation() {
2556         $user1 = self::getDataGenerator()->create_user();
2557         $user2 = self::getDataGenerator()->create_user();
2559         $conversation = \core_message\api::create_conversation(
2560             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2561             [
2562                 $user1->id,
2563                 $user2->id
2564             ]
2565         );
2566         $conversationid = $conversation->id;
2568         $this->assertEquals(2,
2569             \core_message\api::count_conversation_members($conversationid));
2570     }
2572     /**
2573      * Test add_members_to_conversation for an individual conversation.
2574      */
2575     public function test_add_members_to_individual_conversation() {
2576         $user1 = self::getDataGenerator()->create_user();
2577         $user2 = self::getDataGenerator()->create_user();
2578         $user3 = self::getDataGenerator()->create_user();
2580         $conversation = \core_message\api::create_conversation(
2581             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2582             [
2583                 $user1->id,
2584                 $user2->id
2585             ]
2586         );
2587         $conversationid = $conversation->id;
2589         $this->expectException('moodle_exception');
2590         \core_message\api::add_members_to_conversation([$user3->id], $conversationid);
2591     }
2593     /**
2594      * Test add_members_to_conversation for existing conversation.
2595      */
2596     public function test_add_members_to_existing_conversation() {
2597         $user1 = self::getDataGenerator()->create_user();
2598         $user2 = self::getDataGenerator()->create_user();
2599         $user3 = self::getDataGenerator()->create_user();
2601         $conversation = \core_message\api::create_conversation(
2602             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2603             [
2604                 $user1->id,
2605                 $user2->id
2606             ]
2607         );
2608         $conversationid = $conversation->id;
2610         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
2611         $this->assertEquals(3,
2612             \core_message\api::count_conversation_members($conversationid));
2613     }
2615     /**
2616      * Test add_members_to_conversation for non existing conversation.
2617      */
2618     public function test_add_members_to_no_existing_conversation() {
2619         $user1 = self::getDataGenerator()->create_user();
2621         // Throw dml_missing_record_exception for non existing conversation.
2622         $this->expectException('dml_missing_record_exception');
2623         \core_message\api::add_members_to_conversation([$user1->id], 0);
2624     }
2626     /**
2627      * Test add_member_to_conversation for non existing user.
2628      */
2629     public function test_add_members_to_no_existing_user() {
2630         $user1 = self::getDataGenerator()->create_user();
2631         $user2 = self::getDataGenerator()->create_user();
2633         $conversation = \core_message\api::create_conversation(
2634             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2635             [
2636                 $user1->id,
2637                 $user2->id
2638             ]
2639         );
2640         $conversationid = $conversation->id;
2642         // Don't throw an error for non existing user, but don't add it as a member.
2643         $this->assertNull(\core_message\api::add_members_to_conversation([0], $conversationid));
2644         $this->assertEquals(2,
2645             \core_message\api::count_conversation_members($conversationid));
2646     }
2648     /**
2649      * Test add_members_to_conversation for current conversation member.
2650      */
2651     public function test_add_members_to_current_conversation_member() {
2652         $user1 = self::getDataGenerator()->create_user();
2653         $user2 = self::getDataGenerator()->create_user();
2655         $conversation = \core_message\api::create_conversation(
2656             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2657             [
2658                 $user1->id,
2659                 $user2->id
2660             ]
2661         );
2662         $conversationid = $conversation->id;
2664         // Don't add as a member a user that is already conversation member.
2665         $this->assertNull(\core_message\api::add_members_to_conversation([$user1->id], $conversationid));
2666         $this->assertEquals(2,
2667             \core_message\api::count_conversation_members($conversationid));
2668     }
2670     /**
2671      * Test add_members_to_conversation for multiple users.
2672      */
2673     public function test_add_members_for_multiple_users() {
2674         $user1 = self::getDataGenerator()->create_user();
2675         $user2 = self::getDataGenerator()->create_user();
2676         $user3 = self::getDataGenerator()->create_user();
2677         $user4 = self::getDataGenerator()->create_user();
2679         $conversation = \core_message\api::create_conversation(
2680             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2681             [
2682                 $user1->id,
2683                 $user2->id
2684             ]
2685         );
2686         $conversationid = $conversation->id;
2688         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
2689         $this->assertEquals(4,
2690             \core_message\api::count_conversation_members($conversationid));
2691     }
2693     /**
2694      * Test add_members_to_conversation for multiple users, included non existing and current conversation members
2695      */
2696     public function test_add_members_for_multiple_not_valid_users() {
2697         $user1 = self::getDataGenerator()->create_user();
2698         $user2 = self::getDataGenerator()->create_user();
2699         $user3 = self::getDataGenerator()->create_user();
2701         $conversation = \core_message\api::create_conversation(
2702             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2703             [
2704                 $user1->id,
2705                 $user2->id
2706             ]
2707         );
2708         $conversationid = $conversation->id;
2710         // Don't throw errors, but don't add as members users don't exist or are already conversation members.
2711         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
2712         $this->assertEquals(3,
2713             \core_message\api::count_conversation_members($conversationid));
2714     }
2716     /**
2717      * Test remove_members_from_conversation for individual conversation.
2718      */
2719     public function test_remove_members_from_individual_conversation() {
2720         $user1 = self::getDataGenerator()->create_user();
2721         $user2 = self::getDataGenerator()->create_user();
2723         $conversation = \core_message\api::create_conversation(
2724             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2725             [
2726                 $user1->id,
2727                 $user2->id
2728             ]
2729         );
2730         $conversationid = $conversation->id;
2732         $this->expectException('moodle_exception');
2733         \core_message\api::remove_members_from_conversation([$user1->id], $conversationid);
2734     }
2736     /**
2737      * Test remove_members_from_conversation for existing conversation.
2738      */
2739     public function test_remove_members_from_existing_conversation() {
2740         $user1 = self::getDataGenerator()->create_user();
2741         $user2 = self::getDataGenerator()->create_user();
2743         $conversation = \core_message\api::create_conversation(
2744             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2745             [
2746                 $user1->id,
2747                 $user2->id
2748             ]
2749         );
2750         $conversationid = $conversation->id;
2752         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id], $conversationid));
2753         $this->assertEquals(1,
2754             \core_message\api::count_conversation_members($conversationid));
2755     }
2757     /**
2758      * Test remove_members_from_conversation for non existing conversation.
2759      */
2760     public function test_remove_members_from_no_existing_conversation() {
2761         $user1 = self::getDataGenerator()->create_user();
2763         // Throw dml_missing_record_exception for non existing conversation.
2764         $this->expectException('dml_missing_record_exception');
2765         \core_message\api::remove_members_from_conversation([$user1->id], 0);
2766     }
2768     /**
2769      * Test remove_members_from_conversation for non existing user.
2770      */
2771     public function test_remove_members_for_no_existing_user() {
2772         $user1 = self::getDataGenerator()->create_user();
2773         $user2 = self::getDataGenerator()->create_user();
2775         $conversation = \core_message\api::create_conversation(
2776             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2777             [
2778                 $user1->id,
2779                 $user2->id
2780             ]
2781         );
2782         $conversationid = $conversation->id;
2784         $this->assertNull(\core_message\api::remove_members_from_conversation([0], $conversationid));
2785         $this->assertEquals(2,
2786             \core_message\api::count_conversation_members($conversationid));
2787     }
2789     /**
2790      * Test remove_members_from_conversation for multiple users.
2791      */
2792     public function test_remove_members_for_multiple_users() {
2793         $user1 = self::getDataGenerator()->create_user();
2794         $user2 = self::getDataGenerator()->create_user();
2795         $user3 = self::getDataGenerator()->create_user();
2796         $user4 = self::getDataGenerator()->create_user();
2798         $conversation = \core_message\api::create_conversation(
2799             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2800             [
2801                 $user1->id,
2802                 $user2->id
2803             ]
2804         );
2805         $conversationid = $conversation->id;
2807         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
2808         $this->assertNull(\core_message\api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
2809         $this->assertEquals(2,
2810             \core_message\api::count_conversation_members($conversationid));
2811     }
2813     /**
2814      * Test remove_members_from_conversation for multiple non valid users.
2815      */
2816     public function test_remove_members_for_multiple_no_valid_users() {
2817         $user1 = self::getDataGenerator()->create_user();
2818         $user2 = self::getDataGenerator()->create_user();
2819         $user3 = self::getDataGenerator()->create_user();
2820         $user4 = self::getDataGenerator()->create_user();
2822         $conversation = \core_message\api::create_conversation(
2823             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2824             [
2825                 $user1->id,
2826                 $user2->id
2827             ]
2828         );
2829         $conversationid = $conversation->id;
2831         $this->assertNull(\core_message\api::add_members_to_conversation([$user3->id], $conversationid));
2832         $this->assertNull(
2833             \core_message\api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid)
2834         );
2835         $this->assertEquals(1,
2836             \core_message\api::count_conversation_members($conversationid));
2837     }
2839     /**
2840      * Test count_conversation_members for empty conversation.
2841      */
2842     public function test_count_conversation_members_empty_conversation() {
2843         $user1 = self::getDataGenerator()->create_user();
2844         $user2 = self::getDataGenerator()->create_user();
2846         $conversation = \core_message\api::create_conversation(
2847             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2848             [
2849                 $user1->id,
2850                 $user2->id
2851             ]
2852         );
2853         $conversationid = $conversation->id;
2855         $this->assertNull(\core_message\api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid));
2857         $this->assertEquals(0,
2858             \core_message\api::count_conversation_members($conversationid));
2859     }
2861     /**
2862      * Test can create a contact request.
2863      */
2864     public function test_can_create_contact_request() {
2865         global $CFG;
2867         $user1 = self::getDataGenerator()->create_user();
2868         $user2 = self::getDataGenerator()->create_user();
2870         // Disable messaging.
2871         $CFG->messaging = 0;
2872         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
2874         // Re-enable messaging.
2875         $CFG->messaging = 1;
2877         // Allow users to message anyone site-wide.
2878         $CFG->messagingallusers = 1;
2879         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
2881         // Disallow users from messaging anyone site-wide.
2882         $CFG->messagingallusers = 0;
2883         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
2885         // Put the users in the same course so a contact request should be possible.
2886         $course = self::getDataGenerator()->create_course();
2887         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2888         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2889         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
2890     }
2892     /**
2893      * Test creating a contact request.
2894      */
2895     public function test_create_contact_request() {
2896         global $DB;
2898         $user1 = self::getDataGenerator()->create_user();
2899         $user2 = self::getDataGenerator()->create_user();
2901         \core_message\api::create_contact_request($user1->id, $user2->id);
2903         $request = $DB->get_records('message_contact_requests');
2905         $this->assertCount(1, $request);
2907         $request = reset($request);
2909         $this->assertEquals($user1->id, $request->userid);
2910         $this->assertEquals($user2->id, $request->requesteduserid);
2911     }
2913     /**
2914      * Test confirming a contact request.
2915      */
2916     public function test_confirm_contact_request() {
2917         global $DB;
2919         $user1 = self::getDataGenerator()->create_user();
2920         $user2 = self::getDataGenerator()->create_user();
2922         \core_message\api::create_contact_request($user1->id, $user2->id);
2924         \core_message\api::confirm_contact_request($user1->id, $user2->id);
2926         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
2928         $contact = $DB->get_records('message_contacts');
2930         $this->assertCount(1, $contact);
2932         $contact = reset($contact);
2934         $this->assertEquals($user1->id, $contact->userid);
2935         $this->assertEquals($user2->id, $contact->contactid);
2936     }
2938     /**
2939      * Test declining a contact request.
2940      */
2941     public function test_decline_contact_request() {
2942         global $DB;
2944         $user1 = self::getDataGenerator()->create_user();
2945         $user2 = self::getDataGenerator()->create_user();
2947         \core_message\api::create_contact_request($user1->id, $user2->id);
2949         \core_message\api::decline_contact_request($user1->id, $user2->id);
2951         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
2952         $this->assertEquals(0, $DB->count_records('message_contacts'));
2953     }
2955     /**
2956      * Test retrieving contact requests.
2957      */
2958     public function test_get_contact_requests() {
2959         $user1 = self::getDataGenerator()->create_user();
2960         $user2 = self::getDataGenerator()->create_user();
2961         $user3 = self::getDataGenerator()->create_user();
2963         // Block one user, their request should not show up.
2964         \core_message\api::block_user($user1->id, $user3->id);
2966         \core_message\api::create_contact_request($user2->id, $user1->id);
2967         \core_message\api::create_contact_request($user3->id, $user1->id);
2969         $requests = \core_message\api::get_contact_requests($user1->id);
2971         $this->assertCount(1, $requests);
2973         $request = reset($requests);
2975         $this->assertEquals($user2->id, $request->id);
2976         $this->assertEquals($user2->picture, $request->picture);
2977         $this->assertEquals($user2->firstname, $request->firstname);
2978         $this->assertEquals($user2->lastname, $request->lastname);
2979         $this->assertEquals($user2->firstnamephonetic, $request->firstnamephonetic);
2980         $this->assertEquals($user2->lastnamephonetic, $request->lastnamephonetic);
2981         $this->assertEquals($user2->middlename, $request->middlename);
2982         $this->assertEquals($user2->alternatename, $request->alternatename);
2983         $this->assertEquals($user2->email, $request->email);
2984     }
2986     /**
2987      * Test adding contacts.
2988      */
2989     public function test_add_contact() {
2990         global $DB;
2992         $user1 = self::getDataGenerator()->create_user();
2993         $user2 = self::getDataGenerator()->create_user();
2995         \core_message\api::add_contact($user1->id, $user2->id);
2997         $contact = $DB->get_records('message_contacts');
2999         $this->assertCount(1, $contact);
3001         $contact = reset($contact);
3003         $this->assertEquals($user1->id, $contact->userid);
3004         $this->assertEquals($user2->id, $contact->contactid);
3005     }
3007     /**
3008      * Test removing contacts.
3009      */
3010     public function test_remove_contact() {
3011         global $DB;
3013         $user1 = self::getDataGenerator()->create_user();
3014         $user2 = self::getDataGenerator()->create_user();
3016         \core_message\api::add_contact($user1->id, $user2->id);
3017         \core_message\api::remove_contact($user1->id, $user2->id);
3019         $this->assertEquals(0, $DB->count_records('message_contacts'));
3020     }
3022     /**
3023      * Test blocking users.
3024      */
3025     public function test_block_user() {
3026         global $DB;
3028         $user1 = self::getDataGenerator()->create_user();
3029         $user2 = self::getDataGenerator()->create_user();
3031         \core_message\api::block_user($user1->id, $user2->id);
3033         $blockedusers = $DB->get_records('message_users_blocked');
3035         $this->assertCount(1, $blockedusers);
3037         $blockeduser = reset($blockedusers);
3039         $this->assertEquals($user1->id, $blockeduser->userid);
3040         $this->assertEquals($user2->id, $blockeduser->blockeduserid);
3041     }
3043     /**
3044      * Test unblocking users.
3045      */
3046     public function test_unblock_user() {
3047         global $DB;
3049         $user1 = self::getDataGenerator()->create_user();
3050         $user2 = self::getDataGenerator()->create_user();
3052         \core_message\api::block_user($user1->id, $user2->id);
3053         \core_message\api::unblock_user($user1->id, $user2->id);
3055         $this->assertEquals(0, $DB->count_records('message_users_blocked'));
3056     }
3058     /**
3059      * Test is contact check.
3060      */
3061     public function test_is_contact() {
3062         $user1 = self::getDataGenerator()->create_user();
3063         $user2 = self::getDataGenerator()->create_user();
3064         $user3 = self::getDataGenerator()->create_user();
3066         \core_message\api::add_contact($user1->id, $user2->id);
3068         $this->assertTrue(\core_message\api::is_contact($user1->id, $user2->id));
3069         $this->assertTrue(\core_message\api::is_contact($user2->id, $user1->id));
3070         $this->assertFalse(\core_message\api::is_contact($user2->id, $user3->id));
3071     }
3073     /**
3074      * Test get contact.
3075      */
3076     public function test_get_contact() {
3077         $user1 = self::getDataGenerator()->create_user();
3078         $user2 = self::getDataGenerator()->create_user();
3080         \core_message\api::add_contact($user1->id, $user2->id);
3082         $contact = \core_message\api::get_contact($user1->id, $user2->id);
3084         $this->assertEquals($user1->id, $contact->userid);
3085         $this->assertEquals($user2->id, $contact->contactid);
3086     }
3088     /**
3089      * Test is blocked checked.
3090      */
3091     public function test_is_blocked() {
3092         $user1 = self::getDataGenerator()->create_user();
3093         $user2 = self::getDataGenerator()->create_user();
3095         $this->assertFalse(\core_message\api::is_blocked($user1->id, $user2->id));
3096         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
3098         \core_message\api::block_user($user1->id, $user2->id);
3100         $this->assertTrue(\core_message\api::is_blocked($user1->id, $user2->id));
3101         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
3102     }
3104     /**
3105      * Test the contact request exist check.
3106      */
3107     public function test_does_contact_request_exist() {
3108         $user1 = self::getDataGenerator()->create_user();
3109         $user2 = self::getDataGenerator()->create_user();
3111         $this->assertFalse(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
3112         $this->assertFalse(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
3114         \core_message\api::create_contact_request($user1->id, $user2->id);
3116         $this->assertTrue(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
3117         $this->assertTrue(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
3118     }
3120     /**
3121      * Test the user in conversation check.
3122      */
3123     public function test_is_user_in_conversation() {
3124         $user1 = self::getDataGenerator()->create_user();
3125         $user2 = self::getDataGenerator()->create_user();
3127         $conversation = \core_message\api::create_conversation(
3128             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3129             [
3130                 $user1->id,
3131                 $user2->id
3132             ]
3133         );
3134         $conversationid = $conversation->id;
3136         $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $conversationid));
3137     }
3139     /**
3140      * Test the user in conversation check when they are not.
3141      */
3142     public function test_is_user_in_conversation_when_not() {
3143         $user1 = self::getDataGenerator()->create_user();
3144         $user2 = self::getDataGenerator()->create_user();
3145         $user3 = self::getDataGenerator()->create_user();
3147         $conversation = \core_message\api::create_conversation(
3148             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3149             [
3150                 $user1->id,
3151                 $user2->id
3152             ]
3153         );
3154         $conversationid = $conversation->id;
3156         $this->assertFalse(\core_message\api::is_user_in_conversation($user3->id, $conversationid));
3157     }
3159     /**
3160      * Test can create a group conversation.
3161      */
3162     public function test_can_create_group_conversation() {
3163         global $CFG;
3165         $student = self::getDataGenerator()->create_user();
3166         $teacher = self::getDataGenerator()->create_user();
3167         $course = self::getDataGenerator()->create_course();
3169         $coursecontext = context_course::instance($course->id);
3171         $this->getDataGenerator()->enrol_user($student->id, $course->id);
3172         $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
3174         // Disable messaging.
3175         $CFG->messaging = 0;
3176         $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
3178         // Re-enable messaging.
3179         $CFG->messaging = 1;
3181         // Student shouldn't be able to.
3182         $this->assertFalse(\core_message\api::can_create_group_conversation($student->id, $coursecontext));
3184         // Teacher should.
3185         $this->assertTrue(\core_message\api::can_create_group_conversation($teacher->id, $coursecontext));
3186     }
3188     /**
3189      * Test creating an individual conversation.
3190      */
3191     public function test_create_conversation_individual() {
3192         $user1 = self::getDataGenerator()->create_user();
3193         $user2 = self::getDataGenerator()->create_user();
3195         $conversation = \core_message\api::create_conversation(
3196             \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3197             [
3198                 $user1->id,
3199                 $user2->id
3200             ],
3201             'A conversation name'
3202         );
3204         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type);
3205         $this->assertEquals('A conversation name', $conversation->name);
3206         $this->assertEquals(\core_message\helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash);
3208         $this->assertCount(2, $conversation->members);
3210         $member1 = array_shift($conversation->members);
3211         $member2 = array_shift($conversation->members);
3213         $this->assertEquals($user1->id, $member1->userid);
3214         $this->assertEquals($conversation->id, $member1->conversationid);
3216         $this->assertEquals($user2->id, $member2->userid);
3217         $this->assertEquals($conversation->id, $member2->conversationid);
3218     }
3220     /**
3221      * Test creating a group conversation.
3222      */
3223     public function test_create_conversation_group() {
3224         $user1 = self::getDataGenerator()->create_user();
3225         $user2 = self::getDataGenerator()->create_user();
3226         $user3 = self::getDataGenerator()->create_user();
3228         $conversation = \core_message\api::create_conversation(
3229             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3230             [
3231                 $user1->id,
3232                 $user2->id,
3233                 $user3->id
3234             ],
3235             'A conversation name'
3236         );
3238         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type);
3239         $this->assertEquals('A conversation name', $conversation->name);
3240         $this->assertNull($conversation->convhash);
3242         $this->assertCount(3, $conversation->members);
3244         $member1 = array_shift($conversation->members);
3245         $member2 = array_shift($conversation->members);
3246         $member3 = array_shift($conversation->members);
3248         $this->assertEquals($user1->id, $member1->userid);
3249         $this->assertEquals($conversation->id, $member1->conversationid);
3251         $this->assertEquals($user2->id, $member2->userid);
3252         $this->assertEquals($conversation->id, $member2->conversationid);
3254         $this->assertEquals($user3->id, $member3->userid);
3255         $this->assertEquals($conversation->id, $member3->conversationid);
3256     }
3258     /**
3259      * Test creating an individual conversation with too many members.
3260      */
3261     public function test_create_conversation_individual_too_many_members() {
3262         $this->expectException('moodle_exception');
3263         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]);
3264     }
3266     /**
3267      * Test create message conversation area.
3268      */
3269     public function test_create_conversation_area() {
3270         $this->resetAfterTest();
3271         $contextid = 111;
3272         $itemid = 222;
3273         $name = 'Name of conversation';
3274         $conversationarea = \core_message\api::create_conversation_area('core_group', 'groups', $itemid, $contextid, $name, 0);
3276         $this->assertEquals($itemid, $conversationarea->itemid);
3277         $this->assertEquals($contextid, $conversationarea->contextid);
3278         $this->assertEquals('core_group', $conversationarea->component);
3279         $this->assertEquals('groups', $conversationarea->itemtype);
3280         $this->assertEquals(0, $conversationarea->enabled);
3281     }
3283     /**
3284      * Test get_conversation_area.
3285      */
3286     public function test_get_conversation_area() {
3287         $contextid = 111;
3288         $itemid = 222;
3289         $name = 'Name of conversation';
3290         \core_message\api::create_conversation_area('core_group', 'groups', $itemid, $contextid, $name, 1);
3291         $conversationarea = \core_message\api::get_conversation_area('core_group', 'groups', $itemid, $contextid);
3293         $this->assertEquals($itemid, $conversationarea->itemid);
3294         $this->assertEquals($contextid, $conversationarea->contextid);
3295         $this->assertEquals('core_group', $conversationarea->component);
3296         $this->assertEquals('groups', $conversationarea->itemtype);
3297         $this->assertEquals(1, $conversationarea->enabled);
3298     }
3300     /**
3301      * Test enable_conversation_area.
3302      */
3303     public function test_enable_conversation_area() {
3304         global $DB;
3306         $contextid = 111;
3307         $itemid = 222;
3308         $name = 'Name of conversation';
3309         $conversationarea = \core_message\api::create_conversation_area('core_group', 'groups', $itemid, $contextid, $name, 0);
3310         \core_message\api::enable_conversation_area($conversationarea->id);
3311         $conversationareaenabled = $DB->get_field('message_conversation_area', 'enabled', ['id' => $conversationarea->id]);
3312         $this->assertEquals(1, $conversationareaenabled);
3313     }
3315     /**
3316      * Test disable_conversation_area.
3317      */
3318     public function test_disable_conversation_area() {
3319         global $DB;
3321         $contextid = 111;
3322         $itemid = 222;
3323         $name = 'Name of conversation';
3324         $conversationarea = \core_message\api::create_conversation_area('core_group', 'groups', $itemid, $contextid, $name, 1);
3325         $this->assertEquals(1, $conversationarea->enabled);
3326         \core_message\api::disable_conversation_area($conversationarea->id);
3327         $conversationareaenabled = $DB->get_field('message_conversation_area', 'enabled', ['id' => $conversationarea->id]);
3328         $this->assertEquals(0, $conversationareaenabled);
3329     }
3330     /**
3331      * Test update_conversation_name.
3332      */
3333     public function test_update_conversation_name() {
3334         global $DB;
3336         $contextid = 111;
3337         $itemid = 222;
3338         $name = 'Name of conversation';
3339         $conversationarea = \core_message\api::create_conversation_area('core_group', 'groups', $itemid, $contextid, $name, 1);
3341         $newname = 'New name of conversation';
3342         \core_message\api::update_conversation_name($conversationarea->conversationid, $newname);
3344         $this->assertEquals(
3345                 $newname,
3346                 $DB->get_field('message_conversations', 'name', ['id' => $conversationarea->conversationid])
3347         );
3348     }
3350     /**
3351      * Comparison function for sorting contacts.
3352      *
3353      * @param stdClass $a
3354      * @param stdClass $b
3355      * @return bool
3356      */
3357     protected static function sort_contacts($a, $b) {
3358         return $a->userid > $b->userid;
3359     }