MDL-63289 message: Deprecate is_user_non_contact_blocked method
[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      * Tests retrieving conversations.
346      */
347     public function test_get_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         // Send some messages back and forth, have some different conversations with different users.
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         // Retrieve the conversations.
377         $conversations = \core_message\api::get_conversations($user1->id);
379         // Confirm the data is correct.
380         $this->assertEquals(3, count($conversations));
382         $message1 = array_shift($conversations);
383         $message2 = array_shift($conversations);
384         $message3 = array_shift($conversations);
386         $this->assertEquals($user4->id, $message1->userid);
387         $this->assertEquals($user1->id, $message1->useridfrom);
388         $this->assertTrue($message1->ismessaging);
389         $this->assertEquals('Dope.', $message1->lastmessage);
390         $this->assertEquals($messageid3, $message1->messageid);
391         $this->assertNull($message1->isonline);
392         $this->assertFalse($message1->isread);
393         $this->assertFalse($message1->isblocked);
394         $this->assertEquals(1, $message1->unreadcount);
396         $this->assertEquals($user3->id, $message2->userid);
397         $this->assertEquals($user3->id, $message2->useridfrom);
398         $this->assertTrue($message2->ismessaging);
399         $this->assertEquals('Cool.', $message2->lastmessage);
400         $this->assertEquals($messageid2, $message2->messageid);
401         $this->assertNull($message2->isonline);
402         $this->assertFalse($message2->isread);
403         $this->assertFalse($message2->isblocked);
404         $this->assertEquals(2, $message2->unreadcount);
406         $this->assertEquals($user2->id, $message3->userid);
407         $this->assertEquals($user2->id, $message3->useridfrom);
408         $this->assertTrue($message3->ismessaging);
409         $this->assertEquals('Word.', $message3->lastmessage);
410         $this->assertEquals($messageid1, $message3->messageid);
411         $this->assertNull($message3->isonline);
412         $this->assertFalse($message3->isread);
413         $this->assertFalse($message3->isblocked);
414         $this->assertEquals(2, $message3->unreadcount);
415     }
417     /**
418      * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
419      */
420     public function test_get_conversations_limit_offset() {
421         // Create some users.
422         $user1 = self::getDataGenerator()->create_user();
423         $user2 = self::getDataGenerator()->create_user();
424         $user3 = self::getDataGenerator()->create_user();
425         $user4 = self::getDataGenerator()->create_user();
427         // The person doing the search.
428         $this->setUser($user1);
430         // Send some messages back and forth, have some different conversations with different users.
431         $time = 1;
432         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
433         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
434         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
435         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
437         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
438         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
439         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
440         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
442         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
443         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
444         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
446         // Retrieve the conversations.
447         $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
449         // We should only have one conversation because of the limit.
450         $this->assertCount(1, $conversations);
452         $conversation = array_shift($conversations);
454         $this->assertEquals($user3->id, $conversation->userid);
455         $this->assertEquals($user3->id, $conversation->useridfrom);
456         $this->assertTrue($conversation->ismessaging);
457         $this->assertEquals('Cool.', $conversation->lastmessage);
458         $this->assertEquals($messageid2, $conversation->messageid);
459         $this->assertNull($conversation->isonline);
460         $this->assertFalse($conversation->isread);
461         $this->assertFalse($conversation->isblocked);
462         $this->assertEquals(2, $conversation->unreadcount);
464         // Retrieve the next conversation.
465         $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
467         // We should only have one conversation because of the limit.
468         $this->assertCount(1, $conversations);
470         $conversation = array_shift($conversations);
472         $this->assertEquals($user2->id, $conversation->userid);
473         $this->assertEquals($user2->id, $conversation->useridfrom);
474         $this->assertTrue($conversation->ismessaging);
475         $this->assertEquals('Word.', $conversation->lastmessage);
476         $this->assertEquals($messageid1, $conversation->messageid);
477         $this->assertNull($conversation->isonline);
478         $this->assertFalse($conversation->isread);
479         $this->assertFalse($conversation->isblocked);
480         $this->assertEquals(2, $conversation->unreadcount);
482         // Ask for an offset that doesn't exist.
483         $conversations = \core_message\api::get_conversations($user1->id, 4, 1);
485         // We should not get any conversations back.
486         $this->assertCount(0, $conversations);
487     }
489     /**
490      * Tests retrieving conversations when a conversation contains a deleted user.
491      */
492     public function test_get_conversations_with_deleted_user() {
493         // Create some users.
494         $user1 = self::getDataGenerator()->create_user();
495         $user2 = self::getDataGenerator()->create_user();
496         $user3 = self::getDataGenerator()->create_user();
498         // Send some messages back and forth, have some different conversations with different users.
499         $time = 1;
500         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
501         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
502         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
503         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
505         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
506         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
507         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
508         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
510         // Delete the second user.
511         delete_user($user2);
513         // Retrieve the conversations.
514         $conversations = \core_message\api::get_conversations($user1->id);
516         // We should only have one conversation because the other user was deleted.
517         $this->assertCount(1, $conversations);
519         // Confirm the conversation is from the non-deleted user.
520         $conversation = reset($conversations);
521         $this->assertEquals($user3->id, $conversation->userid);
522     }
524    /**
525     * The data provider for get_conversations_mixed.
526     *
527     * This provides sets of data to for testing.
528     * @return array
529     */
530    public function get_conversations_mixed_provider() {
531        return array(
532             'Test that conversations with messages contacts is correctly ordered.' => array(
533                 'users' => array(
534                     'user1',
535                     'user2',
536                     'user3',
537                 ),
538                 'contacts' => array(
539                 ),
540                 'messages' => array(
541                     array(
542                         'from'          => 'user1',
543                         'to'            => 'user2',
544                         'state'         => 'unread',
545                         'subject'       => 'S1',
546                     ),
547                     array(
548                         'from'          => 'user2',
549                         'to'            => 'user1',
550                         'state'         => 'unread',
551                         'subject'       => 'S2',
552                     ),
553                     array(
554                         'from'          => 'user1',
555                         'to'            => 'user2',
556                         'state'         => 'unread',
557                         'timecreated'   => 0,
558                         'subject'       => 'S3',
559                     ),
560                     array(
561                         'from'          => 'user1',
562                         'to'            => 'user3',
563                         'state'         => 'read',
564                         'timemodifier'  => 1,
565                         'subject'       => 'S4',
566                     ),
567                     array(
568                         'from'          => 'user3',
569                         'to'            => 'user1',
570                         'state'         => 'read',
571                         'timemodifier'  => 1,
572                         'subject'       => 'S5',
573                     ),
574                     array(
575                         'from'          => 'user1',
576                         'to'            => 'user3',
577                         'state'         => 'read',
578                         'timecreated'   => 0,
579                         'subject'       => 'S6',
580                     ),
581                 ),
582                 'expectations' => array(
583                     'user1' => array(
584                         // User1 has conversed most recently with user3. The most recent message is M5.
585                         array(
586                             'messageposition'   => 0,
587                             'with'              => 'user3',
588                             'subject'           => 'S5',
589                             'unreadcount'       => 0,
590                         ),
591                         // User1 has also conversed with user2. The most recent message is S2.
592                         array(
593                             'messageposition'   => 1,
594                             'with'              => 'user2',
595                             'subject'           => 'S2',
596                             'unreadcount'       => 1,
597                         ),
598                     ),
599                     'user2' => array(
600                         // User2 has only conversed with user1. Their most recent shared message was S2.
601                         array(
602                             'messageposition'   => 0,
603                             'with'              => 'user1',
604                             'subject'           => 'S2',
605                             'unreadcount'       => 2,
606                         ),
607                     ),
608                     'user3' => array(
609                         // User3 has only conversed with user1. Their most recent shared message was S5.
610                         array(
611                             'messageposition'   => 0,
612                             'with'              => 'user1',
613                             'subject'           => 'S5',
614                             'unreadcount'       => 0,
615                         ),
616                     ),
617                 ),
618             ),
619             'Test that users with contacts and messages to self work as expected' => array(
620                 'users' => array(
621                     'user1',
622                     'user2',
623                     'user3',
624                 ),
625                 'contacts' => array(
626                     'user1' => array(
627                         'user2' => 0,
628                         'user3' => 0,
629                     ),
630                     'user2' => array(
631                         'user3' => 0,
632                     ),
633                 ),
634                 'messages' => array(
635                     array(
636                         'from'          => 'user1',
637                         'to'            => 'user1',
638                         'state'         => 'unread',
639                         'subject'       => 'S1',
640                     ),
641                     array(
642                         'from'          => 'user1',
643                         'to'            => 'user1',
644                         'state'         => 'unread',
645                         'subject'       => 'S2',
646                     ),
647                 ),
648                 'expectations' => array(
649                     'user1' => array(
650                         // User1 has conversed most recently with user1. The most recent message is S2.
651                         array(
652                             'messageposition'   => 0,
653                             'with'              => 'user1',
654                             'subject'           => 'S2',
655                             'unreadcount'       => 0, // Messages sent to and from the same user are counted as read.
656                         ),
657                     ),
658                 ),
659             ),
660             'Test conversations with a single user, where some messages are read and some are not.' => array(
661                 'users' => array(
662                     'user1',
663                     'user2',
664                 ),
665                 'contacts' => array(
666                 ),
667                 'messages' => array(
668                     array(
669                         'from'          => 'user1',
670                         'to'            => 'user2',
671                         'state'         => 'read',
672                         'subject'       => 'S1',
673                     ),
674                     array(
675                         'from'          => 'user2',
676                         'to'            => 'user1',
677                         'state'         => 'read',
678                         'subject'       => 'S2',
679                     ),
680                     array(
681                         'from'          => 'user1',
682                         'to'            => 'user2',
683                         'state'         => 'unread',
684                         'timemodifier'  => 1,
685                         'subject'       => 'S3',
686                     ),
687                     array(
688                         'from'          => 'user1',
689                         'to'            => 'user2',
690                         'state'         => 'unread',
691                         'timemodifier'  => 1,
692                         'subject'       => 'S4',
693                     ),
694                 ),
695                 'expectations' => array(
696                     // The most recent message between user1 and user2 was S4.
697                     'user1' => array(
698                         array(
699                             'messageposition'   => 0,
700                             'with'              => 'user2',
701                             'subject'           => 'S4',
702                             'unreadcount'       => 0,
703                         ),
704                     ),
705                     'user2' => array(
706                         // The most recent message between user1 and user2 was S4.
707                         array(
708                             'messageposition'   => 0,
709                             'with'              => 'user1',
710                             'subject'           => 'S4',
711                             'unreadcount'       => 2,
712                         ),
713                     ),
714                 ),
715             ),
716             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
717             'are out of order' => array(
718             // This can happen through a combination of factors including multi-master DB replication with messages
719             // read somehow (e.g. API).
720                 'users' => array(
721                     'user1',
722                     'user2',
723                 ),
724                 'contacts' => array(
725                 ),
726                 'messages' => array(
727                     array(
728                         'from'          => 'user1',
729                         'to'            => 'user2',
730                         'state'         => 'read',
731                         'subject'       => 'S1',
732                         'timemodifier'  => 1,
733                     ),
734                     array(
735                         'from'          => 'user2',
736                         'to'            => 'user1',
737                         'state'         => 'read',
738                         'subject'       => 'S2',
739                         'timemodifier'  => 2,
740                     ),
741                     array(
742                         'from'          => 'user1',
743                         'to'            => 'user2',
744                         'state'         => 'unread',
745                         'subject'       => 'S3',
746                     ),
747                     array(
748                         'from'          => 'user1',
749                         'to'            => 'user2',
750                         'state'         => 'unread',
751                         'subject'       => 'S4',
752                     ),
753                 ),
754                 'expectations' => array(
755                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
756                     'user1' => array(
757                         array(
758                             'messageposition'   => 0,
759                             'with'              => 'user2',
760                             'subject'           => 'S2',
761                             'unreadcount'       => 0,
762                         ),
763                     ),
764                     'user2' => array(
765                         array(
766                             'messageposition'   => 0,
767                             'with'              => 'user1',
768                             'subject'           => 'S2',
769                             'unreadcount'       => 2
770                         ),
771                     ),
772                 ),
773             ),
774             'Test unread message count is correct for both users' => array(
775                 'users' => array(
776                     'user1',
777                     'user2',
778                 ),
779                 'contacts' => array(
780                 ),
781                 'messages' => array(
782                     array(
783                         'from'          => 'user1',
784                         'to'            => 'user2',
785                         'state'         => 'read',
786                         'subject'       => 'S1',
787                         'timemodifier'  => 1,
788                     ),
789                     array(
790                         'from'          => 'user2',
791                         'to'            => 'user1',
792                         'state'         => 'read',
793                         'subject'       => 'S2',
794                         'timemodifier'  => 2,
795                     ),
796                     array(
797                         'from'          => 'user1',
798                         'to'            => 'user2',
799                         'state'         => 'read',
800                         'subject'       => 'S3',
801                         'timemodifier'  => 3,
802                     ),
803                     array(
804                         'from'          => 'user1',
805                         'to'            => 'user2',
806                         'state'         => 'read',
807                         'subject'       => 'S4',
808                         'timemodifier'  => 4,
809                     ),
810                     array(
811                         'from'          => 'user1',
812                         'to'            => 'user2',
813                         'state'         => 'unread',
814                         'subject'       => 'S5',
815                         'timemodifier'  => 5,
816                     ),
817                     array(
818                         'from'          => 'user2',
819                         'to'            => 'user1',
820                         'state'         => 'unread',
821                         'subject'       => 'S6',
822                         'timemodifier'  => 6,
823                     ),
824                     array(
825                         'from'          => 'user1',
826                         'to'            => 'user2',
827                         'state'         => 'unread',
828                         'subject'       => 'S7',
829                         'timemodifier'  => 7,
830                     ),
831                     array(
832                         'from'          => 'user1',
833                         'to'            => 'user2',
834                         'state'         => 'unread',
835                         'subject'       => 'S8',
836                         'timemodifier'  => 8,
837                     ),
838                 ),
839                 'expectations' => array(
840                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
841                     'user1' => array(
842                         array(
843                             'messageposition'   => 0,
844                             'with'              => 'user2',
845                             'subject'           => 'S8',
846                             'unreadcount'       => 1,
847                         ),
848                     ),
849                     'user2' => array(
850                         array(
851                             'messageposition'   => 0,
852                             'with'              => 'user1',
853                             'subject'           => 'S8',
854                             'unreadcount'       => 3,
855                         ),
856                     ),
857                 ),
858             ),
859         );
860     }
862     /**
863      * Test get_conversations with a mixture of messages.
864      *
865      * @dataProvider get_conversations_mixed_provider
866      * @param array $usersdata The list of users to create for this test.
867      * @param array $messagesdata The list of messages to create.
868      * @param array $expectations The list of expected outcomes.
869      */
870     public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
871         global $DB;
873         // Create all of the users.
874         $users = array();
875         foreach ($usersdata as $username) {
876             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
877         }
879         foreach ($contacts as $username => $contact) {
880             foreach ($contact as $contactname => $blocked) {
881                 $record = new stdClass();
882                 $record->userid     = $users[$username]->id;
883                 $record->contactid  = $users[$contactname]->id;
884                 $record->blocked    = $blocked;
885                 $record->id = $DB->insert_record('message_contacts', $record);
886             }
887         }
889         $defaulttimecreated = time();
890         foreach ($messagesdata as $messagedata) {
891             $from       = $users[$messagedata['from']];
892             $to         = $users[$messagedata['to']];
893             $subject    = $messagedata['subject'];
895             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
896                 $messageid = $this->send_fake_message($from, $to, $subject);
897             } else {
898                 // If there is no state, or the state is not 'unread', assume the message is read.
899                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
900             }
902             $updatemessage = new stdClass();
903             $updatemessage->id = $messageid;
904             if (isset($messagedata['timecreated'])) {
905                 $updatemessage->timecreated = $messagedata['timecreated'];
906             } else if (isset($messagedata['timemodifier'])) {
907                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
908             } else {
909                 $updatemessage->timecreated = $defaulttimecreated;
910             }
912             $DB->update_record('messages', $updatemessage);
913         }
915         foreach ($expectations as $username => $data) {
916             // Get the recent conversations for the specified user.
917             $user = $users[$username];
918             $conversations = array_values(\core_message\api::get_conversations($user->id));
919             foreach ($data as $expectation) {
920                 $otheruser = $users[$expectation['with']];
921                 $conversation = $conversations[$expectation['messageposition']];
922                 $this->assertEquals($otheruser->id, $conversation->userid);
923                 $this->assertEquals($expectation['subject'], $conversation->lastmessage);
924                 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
925             }
926         }
927     }
929     /**
930      * Tests retrieving contacts.
931      */
932     public function test_get_contacts() {
933         // Create some users.
934         $user1 = self::getDataGenerator()->create_user();
936         // Set as the user.
937         $this->setUser($user1);
939         $user2 = new stdClass();
940         $user2->firstname = 'User';
941         $user2->lastname = 'A';
942         $user2 = self::getDataGenerator()->create_user($user2);
944         $user3 = new stdClass();
945         $user3->firstname = 'User';
946         $user3->lastname = 'B';
947         $user3 = self::getDataGenerator()->create_user($user3);
949         $user4 = new stdClass();
950         $user4->firstname = 'User';
951         $user4->lastname = 'C';
952         $user4 = self::getDataGenerator()->create_user($user4);
954         $user5 = new stdClass();
955         $user5->firstname = 'User';
956         $user5->lastname = 'D';
957         $user5 = self::getDataGenerator()->create_user($user5);
959         // Add some users as contacts.
960         \core_message\api::add_contact($user1->id, $user2->id);
961         \core_message\api::add_contact($user1->id, $user3->id);
962         \core_message\api::add_contact($user1->id, $user4->id);
964         // Retrieve the contacts.
965         $contacts = \core_message\api::get_contacts($user1->id);
967         // Confirm the data is correct.
968         $this->assertEquals(3, count($contacts));
969         usort($contacts, ['static', 'sort_contacts']);
971         $contact1 = $contacts[0];
972         $contact2 = $contacts[1];
973         $contact3 = $contacts[2];
975         $this->assertEquals($user2->id, $contact1->userid);
976         $this->assertEmpty($contact1->useridfrom);
977         $this->assertFalse($contact1->ismessaging);
978         $this->assertNull($contact1->lastmessage);
979         $this->assertNull($contact1->messageid);
980         $this->assertNull($contact1->isonline);
981         $this->assertFalse($contact1->isread);
982         $this->assertFalse($contact1->isblocked);
983         $this->assertNull($contact1->unreadcount);
985         $this->assertEquals($user3->id, $contact2->userid);
986         $this->assertEmpty($contact2->useridfrom);
987         $this->assertFalse($contact2->ismessaging);
988         $this->assertNull($contact2->lastmessage);
989         $this->assertNull($contact2->messageid);
990         $this->assertNull($contact2->isonline);
991         $this->assertFalse($contact2->isread);
992         $this->assertFalse($contact2->isblocked);
993         $this->assertNull($contact2->unreadcount);
995         $this->assertEquals($user4->id, $contact3->userid);
996         $this->assertEmpty($contact3->useridfrom);
997         $this->assertFalse($contact3->ismessaging);
998         $this->assertNull($contact3->lastmessage);
999         $this->assertNull($contact3->messageid);
1000         $this->assertNull($contact3->isonline);
1001         $this->assertFalse($contact3->isread);
1002         $this->assertFalse($contact3->isblocked);
1003         $this->assertNull($contact3->unreadcount);
1004     }
1006     /**
1007      * Tests retrieving messages.
1008      */
1009     public function test_get_messages() {
1010         // Create some users.
1011         $user1 = self::getDataGenerator()->create_user();
1012         $user2 = self::getDataGenerator()->create_user();
1014         // The person doing the search.
1015         $this->setUser($user1);
1017         // Send some messages back and forth.
1018         $time = 1;
1019         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1020         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1021         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1022         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1024         // Retrieve the messages.
1025         $messages = \core_message\api::get_messages($user1->id, $user2->id);
1027         // Confirm the message data is correct.
1028         $this->assertEquals(4, count($messages));
1030         $message1 = $messages[0];
1031         $message2 = $messages[1];
1032         $message3 = $messages[2];
1033         $message4 = $messages[3];
1035         $this->assertEquals($user1->id, $message1->useridfrom);
1036         $this->assertEquals($user2->id, $message1->useridto);
1037         $this->assertTrue($message1->displayblocktime);
1038         $this->assertContains('Yo!', $message1->text);
1040         $this->assertEquals($user2->id, $message2->useridfrom);
1041         $this->assertEquals($user1->id, $message2->useridto);
1042         $this->assertFalse($message2->displayblocktime);
1043         $this->assertContains('Sup mang?', $message2->text);
1045         $this->assertEquals($user1->id, $message3->useridfrom);
1046         $this->assertEquals($user2->id, $message3->useridto);
1047         $this->assertFalse($message3->displayblocktime);
1048         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1050         $this->assertEquals($user2->id, $message4->useridfrom);
1051         $this->assertEquals($user1->id, $message4->useridto);
1052         $this->assertFalse($message4->displayblocktime);
1053         $this->assertContains('Word.', $message4->text);
1054     }
1056     /**
1057      * Tests retrieving most recent message.
1058      */
1059     public function test_get_most_recent_message() {
1060         // Create some users.
1061         $user1 = self::getDataGenerator()->create_user();
1062         $user2 = self::getDataGenerator()->create_user();
1064         // The person doing the search.
1065         $this->setUser($user1);
1067         // Send some messages back and forth.
1068         $time = 1;
1069         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1070         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1071         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1072         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1074         // Retrieve the most recent messages.
1075         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1077         // Check the results are correct.
1078         $this->assertEquals($user2->id, $message->useridfrom);
1079         $this->assertEquals($user1->id, $message->useridto);
1080         $this->assertContains('Word.', $message->text);
1081     }
1083     /**
1084      * Tests retrieving a user's profile.
1085      */
1086     public function test_get_profile() {
1087         // Create some users.
1088         $user1 = self::getDataGenerator()->create_user();
1090         $user2 = new stdClass();
1091         $user2->country = 'AU';
1092         $user2->city = 'Perth';
1093         $user2 = self::getDataGenerator()->create_user($user2);
1095         // The person doing the search.
1096         $this->setUser($user1);
1098         // Get the profile.
1099         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1101         $this->assertEquals($user2->id, $profile->userid);
1102         $this->assertEmpty($profile->email);
1103         $this->assertEmpty($profile->country);
1104         $this->assertEmpty($profile->city);
1105         $this->assertEquals(fullname($user2), $profile->fullname);
1106         $this->assertNull($profile->isonline);
1107         $this->assertFalse($profile->isblocked);
1108         $this->assertFalse($profile->iscontact);
1109     }
1111     /**
1112      * Tests retrieving a user's profile.
1113      */
1114     public function test_get_profile_as_admin() {
1115         // The person doing the search.
1116         $this->setAdminUser();
1118         // Create some users.
1119         $user1 = self::getDataGenerator()->create_user();
1121         $user2 = new stdClass();
1122         $user2->country = 'AU';
1123         $user2->city = 'Perth';
1124         $user2 = self::getDataGenerator()->create_user($user2);
1126         // Get the profile.
1127         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1129         $this->assertEquals($user2->id, $profile->userid);
1130         $this->assertEquals($user2->email, $profile->email);
1131         $this->assertEquals($user2->country, $profile->country);
1132         $this->assertEquals($user2->city, $profile->city);
1133         $this->assertEquals(fullname($user2), $profile->fullname);
1134         $this->assertFalse($profile->isonline);
1135         $this->assertFalse($profile->isblocked);
1136         $this->assertFalse($profile->iscontact);
1137     }
1139     /**
1140      * Tests checking if a user can delete a conversation.
1141      */
1142     public function test_can_delete_conversation() {
1143         // Set as the admin.
1144         $this->setAdminUser();
1146         // Create some users.
1147         $user1 = self::getDataGenerator()->create_user();
1148         $user2 = self::getDataGenerator()->create_user();
1150         // Send some messages back and forth.
1151         $time = 1;
1152         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1153         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1154         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1155         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1157         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1159         // The admin can do anything.
1160         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1162         // Set as the user 1.
1163         $this->setUser($user1);
1165         // They can delete their own messages.
1166         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1168         // They can't delete someone elses.
1169         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
1170     }
1172     /**
1173      * Tests deleting a conversation.
1174      */
1175     public function test_delete_conversation() {
1176         global $DB;
1178         // Create some users.
1179         $user1 = self::getDataGenerator()->create_user();
1180         $user2 = self::getDataGenerator()->create_user();
1182         // The person doing the search.
1183         $this->setUser($user1);
1185         // Send some messages back and forth.
1186         $time = 1;
1187         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1188         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1189         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1190         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1192         // Delete the conversation as user 1.
1193         \core_message\api::delete_conversation($user1->id, $user2->id);
1194         $this->assertDebuggingCalled();
1196         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1197         $this->assertCount(4, $muas);
1198         // Sort by id.
1199         ksort($muas);
1201         $mua1 = array_shift($muas);
1202         $mua2 = array_shift($muas);
1203         $mua3 = array_shift($muas);
1204         $mua4 = array_shift($muas);
1206         $this->assertEquals($user1->id, $mua1->userid);
1207         $this->assertEquals($m1id, $mua1->messageid);
1208         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1210         $this->assertEquals($user1->id, $mua2->userid);
1211         $this->assertEquals($m2id, $mua2->messageid);
1212         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1214         $this->assertEquals($user1->id, $mua3->userid);
1215         $this->assertEquals($m3id, $mua3->messageid);
1216         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1218         $this->assertEquals($user1->id, $mua4->userid);
1219         $this->assertEquals($m4id, $mua4->messageid);
1220         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1221     }
1223     /**
1224      * Tests deleting a conversation by conversation id.
1225      */
1226     public function test_delete_conversation_by_id() {
1227         global $DB;
1229         // Create some users.
1230         $user1 = self::getDataGenerator()->create_user();
1231         $user2 = self::getDataGenerator()->create_user();
1233         // The person doing the search.
1234         $this->setUser($user1);
1236         // Send some messages back and forth.
1237         $time = 1;
1238         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1239         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1240         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1241         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1243         // Delete the conversation as user 1.
1244         $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1245         \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
1247         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1248         $this->assertCount(4, $muas);
1249         // Sort by id.
1250         ksort($muas);
1252         $mua1 = array_shift($muas);
1253         $mua2 = array_shift($muas);
1254         $mua3 = array_shift($muas);
1255         $mua4 = array_shift($muas);
1257         $this->assertEquals($user1->id, $mua1->userid);
1258         $this->assertEquals($m1id, $mua1->messageid);
1259         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1261         $this->assertEquals($user1->id, $mua2->userid);
1262         $this->assertEquals($m2id, $mua2->messageid);
1263         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1265         $this->assertEquals($user1->id, $mua3->userid);
1266         $this->assertEquals($m3id, $mua3->messageid);
1267         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1269         $this->assertEquals($user1->id, $mua4->userid);
1270         $this->assertEquals($m4id, $mua4->messageid);
1271         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1272     }
1274     /**
1275      * Tests counting unread conversations.
1276      */
1277     public function test_count_unread_conversations() {
1278         $this->resetAfterTest(true);
1280         // Create some users.
1281         $user1 = self::getDataGenerator()->create_user();
1282         $user2 = self::getDataGenerator()->create_user();
1283         $user3 = self::getDataGenerator()->create_user();
1284         $user4 = self::getDataGenerator()->create_user();
1286         // The person wanting the conversation count.
1287         $this->setUser($user1);
1289         // Send some messages back and forth, have some different conversations with different users.
1290         $this->send_fake_message($user1, $user2, 'Yo!');
1291         $this->send_fake_message($user2, $user1, 'Sup mang?');
1292         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
1293         $this->send_fake_message($user2, $user1, 'Word.');
1295         $this->send_fake_message($user1, $user3, 'Booyah');
1296         $this->send_fake_message($user3, $user1, 'Whaaat?');
1297         $this->send_fake_message($user1, $user3, 'Nothing.');
1298         $this->send_fake_message($user3, $user1, 'Cool.');
1300         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
1301         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
1302         $this->send_fake_message($user1, $user4, 'Dope.');
1304         // Check the amount for the current user.
1305         $this->assertEquals(3, core_message\api::count_unread_conversations());
1307         // Check the amount for the second user.
1308         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
1309     }
1311     /**
1312      * Tests deleting a conversation.
1313      */
1314     public function test_get_all_message_preferences() {
1315         $user = self::getDataGenerator()->create_user();
1316         $this->setUser($user);
1318         // Set a couple of preferences to test.
1319         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
1320         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
1322         $processors = get_message_processors();
1323         $providers = message_get_providers_for_user($user->id);
1324         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
1326         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
1327         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
1328     }
1330     /**
1331      * Tests the user can post a message.
1332      */
1333     public function test_can_post_message() {
1334         // Create some users.
1335         $user1 = self::getDataGenerator()->create_user();
1336         $user2 = self::getDataGenerator()->create_user();
1338         // Set as the first user.
1339         $this->setUser($user1);
1341         // With the default privacy setting, users can't message them.
1342         $this->assertFalse(\core_message\api::can_post_message($user2));
1344         // Enrol users to the same course.
1345         $course = $this->getDataGenerator()->create_course();
1346         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1347         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1348         // After enrolling users to the course, they should be able to message them with the default privacy setting.
1349         $this->assertTrue(\core_message\api::can_post_message($user2));
1350     }
1352     /**
1353      * Tests the user can't post a message without proper capability.
1354      */
1355     public function test_can_post_message_without_sendmessage_cap() {
1356         global $DB;
1358         // Create some users.
1359         $user1 = self::getDataGenerator()->create_user();
1360         $user2 = self::getDataGenerator()->create_user();
1362         // Set as the user 1.
1363         $this->setUser($user1);
1365         // Remove the capability to send a message.
1366         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
1367         unassign_capability('moodle/site:sendmessage', $roleids['user'],
1368             context_system::instance());
1370         // Check that we can not post a message without the capability.
1371         $this->assertFalse(\core_message\api::can_post_message($user2));
1372     }
1374     /**
1375      * Tests the user can post a message when they are contact.
1376      */
1377     public function test_can_post_message_when_contact() {
1378         // Create some users.
1379         $user1 = self::getDataGenerator()->create_user();
1380         $user2 = self::getDataGenerator()->create_user();
1382         // Set as the first user.
1383         $this->setUser($user1);
1385         // Check that we can not send user2 a message.
1386         $this->assertFalse(\core_message\api::can_post_message($user2));
1388         // Add users as contacts.
1389         \core_message\api::add_contact($user1->id, $user2->id);
1391         // Check that the return result is now true.
1392         $this->assertTrue(\core_message\api::can_post_message($user2));
1393     }
1395     /**
1396      * Tests the user can't post a message if they are not a contact and the user
1397      * has requested messages only from contacts.
1398      */
1399     public function test_can_post_message_when_not_contact() {
1400         // Create some users.
1401         $user1 = self::getDataGenerator()->create_user();
1402         $user2 = self::getDataGenerator()->create_user();
1404         // Set as the first user.
1405         $this->setUser($user1);
1407         // Set the second user's preference to not receive messages from non-contacts.
1408         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1410         // Check that we can not send user 2 a message.
1411         $this->assertFalse(\core_message\api::can_post_message($user2));
1412     }
1414     /**
1415      * Tests the user can't post a message if they are blocked.
1416      */
1417     public function test_can_post_message_when_blocked() {
1418         // Create some users.
1419         $user1 = self::getDataGenerator()->create_user();
1420         $user2 = self::getDataGenerator()->create_user();
1422         // Set the user.
1423         $this->setUser($user1);
1425         // Block the second user.
1426         \core_message\api::block_user($user1->id, $user2->id);
1428         // Check that the second user can no longer send the first user a message.
1429         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
1430     }
1432     /**
1433      * Tests the user can post a message when site-wide messaging setting is enabled,
1434      * even if they are not a contact and are not members of the same course.
1435      */
1436     public function test_can_post_message_site_messaging_setting() {
1437         // Create some users.
1438         $user1 = self::getDataGenerator()->create_user();
1439         $user2 = self::getDataGenerator()->create_user();
1441         // Set as the first user.
1442         $this->setUser($user1);
1444         // By default, user only can be messaged by contacts and members of any of his/her courses.
1445         $this->assertFalse(\core_message\api::can_post_message($user2));
1447         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
1448         set_config('messagingallusers', true);
1450         // Set the second user's preference to receive messages from everybody.
1451         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
1453         // Check that we can send user2 a message.
1454         $this->assertTrue(\core_message\api::can_post_message($user2));
1456         // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
1457         // and members sharing a course with her.
1458         set_config('messagingallusers', false);
1460         // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
1461         $this->assertFalse(\core_message\api::can_post_message($user2));
1463         // Enrol users to the same course.
1464         $course = $this->getDataGenerator()->create_course();
1465         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1466         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1467         // Check that we can send user2 a message because they are sharing a course.
1468         $this->assertTrue(\core_message\api::can_post_message($user2));
1470         // Set the second user's preference to receive messages only from contacts.
1471         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1472         // Check that now the user2 can't be contacted because user1 is not their contact.
1473         $this->assertFalse(\core_message\api::can_post_message($user2));
1475         // Make contacts user1 and user2.
1476         \core_message\api::add_contact($user2->id, $user1->id);
1477         // Check that we can send user2 a message because they are contacts.
1478         $this->assertTrue(\core_message\api::can_post_message($user2));
1479     }
1481     /**
1482      * Tests the user with the messageanyuser capability can post a message.
1483      */
1484     public function test_can_post_message_with_messageanyuser_cap() {
1485         global $DB;
1487         // Create some users.
1488         $teacher1 = self::getDataGenerator()->create_user();
1489         $student1 = self::getDataGenerator()->create_user();
1490         $student2 = self::getDataGenerator()->create_user();
1492         // Create users not enrolled in any course.
1493         $user1 = self::getDataGenerator()->create_user();
1495         // Create a course.
1496         $course1 = $this->getDataGenerator()->create_course();
1498         // Enrol the users in the course.
1499         $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
1500         $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
1501         $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
1503         // Set some student preferences to not receive messages from non-contacts.
1504         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
1506         // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
1507         $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
1508         // Check that the teacher can't contact user1 because it's not his teacher.
1509         $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
1511         // Remove the messageanyuser capability from the course1 for teachers.
1512         $coursecontext = context_course::instance($course1->id);
1513         $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
1514         assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
1515         $coursecontext->mark_dirty();
1517         // Check that we can't send user1 a message because they are not contacts.
1518         $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
1519         // However, teacher can message student2 because they are sharing a course.
1520         $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
1521     }
1523     /**
1524      * Tests get_user_privacy_messaging_preference method.
1525      */
1526     public function test_get_user_privacy_messaging_preference() {
1527         // Create some users.
1528         $user1 = self::getDataGenerator()->create_user();
1529         $user2 = self::getDataGenerator()->create_user();
1530         $user3 = self::getDataGenerator()->create_user();
1532         // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
1533         set_config('messagingallusers', true);
1535         // Set some user preferences.
1536         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
1537         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1539         // Check the returned value for each user.
1540         $this->assertEquals(
1541             \core_message\api::MESSAGE_PRIVACY_SITE,
1542             \core_message\api::get_user_privacy_messaging_preference($user1->id)
1543         );
1544         $this->assertEquals(
1545             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
1546             \core_message\api::get_user_privacy_messaging_preference($user2->id)
1547         );
1548         $this->assertEquals(
1549             \core_message\api::MESSAGE_PRIVACY_SITE,
1550             \core_message\api::get_user_privacy_messaging_preference($user3->id)
1551         );
1553         // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
1554         set_config('messagingallusers', false);
1556         // Check the returned value for each user.
1557         $this->assertEquals(
1558             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
1559             \core_message\api::get_user_privacy_messaging_preference($user1->id)
1560         );
1561         $this->assertEquals(
1562             \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
1563             \core_message\api::get_user_privacy_messaging_preference($user2->id)
1564         );
1565         $this->assertEquals(
1566             \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
1567             \core_message\api::get_user_privacy_messaging_preference($user3->id)
1568         );
1569     }
1571     /**
1572      * Tests that when blocking messages from non-contacts is enabled that
1573      * non-contacts trying to send a message return false.
1574      */
1575     public function test_is_user_non_contact_blocked() {
1576         // Create some users.
1577         $user1 = self::getDataGenerator()->create_user();
1578         $user2 = self::getDataGenerator()->create_user();
1580         // Set as the first user.
1581         $this->setUser($user1);
1583         // By default, user only can be messaged by contacts and members of any of his/her courses.
1584         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
1585         $this->assertDebuggingCalled();
1587         // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
1588         // messages from everybody.
1589         set_config('messagingallusers', true);
1590         // Check that the return result is now false because any site user can contact him/her.
1591         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1592         $this->assertDebuggingCalled();
1594         // Set the second user's preference to not receive messages from non-contacts.
1595         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1596         // Check that the return result is still true (because is even more restricted).
1597         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
1598         $this->assertDebuggingCalled();
1600         // Add the first user as a contact for the second user.
1601         \core_message\api::add_contact($user2->id, $user1->id);
1603         // Check that the return result is now false.
1604         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1605         $this->assertDebuggingCalled();
1607         // Set the second user's preference to receive messages from course members.
1608         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
1609         // Check that the return result is still false (because $user1 is still his/her contact).
1610         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1611         $this->assertDebuggingCalled();
1612     }
1614     /**
1615      * Tests that we return true when a user is blocked, or false
1616      * if they are not blocked.
1617      */
1618     public function test_is_user_blocked() {
1619         // Create some users.
1620         $user1 = self::getDataGenerator()->create_user();
1621         $user2 = self::getDataGenerator()->create_user();
1623         // Set the user.
1624         $this->setUser($user1);
1626         // User shouldn't be blocked.
1627         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1628         $this->assertDebuggingCalled();
1630         // Block the user.
1631         \core_message\api::block_user($user1->id, $user2->id);
1633         // User should be blocked.
1634         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
1635         $this->assertDebuggingCalled();
1637         // Unblock the user.
1638         \core_message\api::unblock_user($user1->id, $user2->id);
1639         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1640         $this->assertDebuggingCalled();
1641     }
1643     /**
1644      * Tests that the admin is not blocked even if someone has chosen to block them.
1645      */
1646     public function test_is_user_blocked_as_admin() {
1647         // Create a user.
1648         $user1 = self::getDataGenerator()->create_user();
1650         // Set the user.
1651         $this->setUser($user1);
1653         // Block the admin user.
1654         \core_message\api::block_user($user1->id, 2);
1656         // Now change to the admin user.
1657         $this->setAdminUser();
1659         // As the admin you should still be able to send messages to the user.
1660         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
1661         $this->assertDebuggingCalled();
1662     }
1664     /*
1665      * Tes get_message_processor api.
1666      */
1667     public function test_get_message_processor() {
1668         $processors = get_message_processors(true);
1669         if (empty($processors)) {
1670             $this->markTestSkipped("No message processors found");
1671         }
1673         $name = key($processors);
1674         $processor = current($processors);
1675         $testprocessor = \core_message\api::get_message_processor($name);
1676         $this->assertEquals($processor->name, $testprocessor->name);
1677         $this->assertEquals($processor->enabled, $testprocessor->enabled);
1678         $this->assertEquals($processor->available, $testprocessor->available);
1679         $this->assertEquals($processor->configured, $testprocessor->configured);
1681         // Disable processor and test.
1682         \core_message\api::update_processor_status($testprocessor, 0);
1683         $testprocessor = \core_message\api::get_message_processor($name, true);
1684         $this->assertEmpty($testprocessor);
1685         $testprocessor = \core_message\api::get_message_processor($name);
1686         $this->assertEquals($processor->name, $testprocessor->name);
1687         $this->assertEquals(0, $testprocessor->enabled);
1689         // Enable again and test.
1690         \core_message\api::update_processor_status($testprocessor, 1);
1691         $testprocessor = \core_message\api::get_message_processor($name, true);
1692         $this->assertEquals($processor->name, $testprocessor->name);
1693         $this->assertEquals(1, $testprocessor->enabled);
1694         $testprocessor = \core_message\api::get_message_processor($name);
1695         $this->assertEquals($processor->name, $testprocessor->name);
1696         $this->assertEquals(1, $testprocessor->enabled);
1697     }
1699     /**
1700      * Test method update_processor_status.
1701      */
1702     public function test_update_processor_status() {
1703         $processors = get_message_processors();
1704         if (empty($processors)) {
1705             $this->markTestSkipped("No message processors found");
1706         }
1707         $name = key($processors);
1708         $testprocessor = current($processors);
1710         // Enable.
1711         \core_message\api::update_processor_status($testprocessor, 1);
1712         $testprocessor = \core_message\api::get_message_processor($name);
1713         $this->assertEquals(1, $testprocessor->enabled);
1715         // Disable.
1716         \core_message\api::update_processor_status($testprocessor, 0);
1717         $testprocessor = \core_message\api::get_message_processor($name);
1718         $this->assertEquals(0, $testprocessor->enabled);
1720         // Enable again.
1721         \core_message\api::update_processor_status($testprocessor, 1);
1722         $testprocessor = \core_message\api::get_message_processor($name);
1723         $this->assertEquals(1, $testprocessor->enabled);
1724     }
1726     /**
1727      * Test method is_user_enabled.
1728      */
1729     public function is_user_enabled() {
1730         $processors = get_message_processors();
1731         if (empty($processors)) {
1732             $this->markTestSkipped("No message processors found");
1733         }
1734         $name = key($processors);
1735         $testprocessor = current($processors);
1737         // Enable.
1738         \core_message\api::update_processor_status($testprocessor, 1);
1739         $status = \core_message\api::is_processor_enabled($name);
1740         $this->assertEquals(1, $status);
1742         // Disable.
1743         \core_message\api::update_processor_status($testprocessor, 0);
1744         $status = \core_message\api::is_processor_enabled($name);
1745         $this->assertEquals(0, $status);
1747         // Enable again.
1748         \core_message\api::update_processor_status($testprocessor, 1);
1749         $status = \core_message\api::is_processor_enabled($name);
1750         $this->assertEquals(1, $status);
1751     }
1753     /**
1754      * Test retrieving messages by providing a minimum timecreated value.
1755      */
1756     public function test_get_messages_time_from_only() {
1757         // Create some users.
1758         $user1 = self::getDataGenerator()->create_user();
1759         $user2 = self::getDataGenerator()->create_user();
1761         // The person doing the search.
1762         $this->setUser($user1);
1764         // Send some messages back and forth.
1765         $time = 1;
1766         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1767         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1768         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1769         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1771         // Retrieve the messages from $time, which should be all of them.
1772         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
1774         // Confirm the message data is correct.
1775         $this->assertEquals(4, count($messages));
1777         $message1 = $messages[0];
1778         $message2 = $messages[1];
1779         $message3 = $messages[2];
1780         $message4 = $messages[3];
1782         $this->assertContains('Message 1', $message1->text);
1783         $this->assertContains('Message 2', $message2->text);
1784         $this->assertContains('Message 3', $message3->text);
1785         $this->assertContains('Message 4', $message4->text);
1787         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1788         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
1790         // Confirm the message data is correct.
1791         $this->assertEquals(2, count($messages));
1793         $message1 = $messages[0];
1794         $message2 = $messages[1];
1796         $this->assertContains('Message 3', $message1->text);
1797         $this->assertContains('Message 4', $message2->text);
1798     }
1800     /**
1801      * Test retrieving messages by providing a maximum timecreated value.
1802      */
1803     public function test_get_messages_time_to_only() {
1804         // Create some users.
1805         $user1 = self::getDataGenerator()->create_user();
1806         $user2 = self::getDataGenerator()->create_user();
1808         // The person doing the search.
1809         $this->setUser($user1);
1811         // Send some messages back and forth.
1812         $time = 1;
1813         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1814         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1815         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1816         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1818         // Retrieve the messages up until $time + 4, which should be all of them.
1819         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
1821         // Confirm the message data is correct.
1822         $this->assertEquals(4, count($messages));
1824         $message1 = $messages[0];
1825         $message2 = $messages[1];
1826         $message3 = $messages[2];
1827         $message4 = $messages[3];
1829         $this->assertContains('Message 1', $message1->text);
1830         $this->assertContains('Message 2', $message2->text);
1831         $this->assertContains('Message 3', $message3->text);
1832         $this->assertContains('Message 4', $message4->text);
1834         // Retrieve the messages up until $time + 2, which should be the first two.
1835         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
1837         // Confirm the message data is correct.
1838         $this->assertEquals(2, count($messages));
1840         $message1 = $messages[0];
1841         $message2 = $messages[1];
1843         $this->assertContains('Message 1', $message1->text);
1844         $this->assertContains('Message 2', $message2->text);
1845     }
1847     /**
1848      * Test retrieving messages by providing a minimum and maximum timecreated value.
1849      */
1850     public function test_get_messages_time_from_and_to() {
1851         // Create some users.
1852         $user1 = self::getDataGenerator()->create_user();
1853         $user2 = self::getDataGenerator()->create_user();
1855         // The person doing the search.
1856         $this->setUser($user1);
1858         // Send some messages back and forth.
1859         $time = 1;
1860         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1861         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1862         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1863         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1865         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1866         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
1868         // Confirm the message data is correct.
1869         $this->assertEquals(2, count($messages));
1871         $message1 = $messages[0];
1872         $message2 = $messages[1];
1874         $this->assertContains('Message 2', $message1->text);
1875         $this->assertContains('Message 3', $message2->text);
1876     }
1878     /**
1879      * Test returning blocked users.
1880      */
1881     public function test_get_blocked_users() {
1882         global $USER;
1884         // Set this user as the admin.
1885         $this->setAdminUser();
1887         // Create a user to add to the admin's contact list.
1888         $user1 = $this->getDataGenerator()->create_user();
1889         $user2 = $this->getDataGenerator()->create_user();
1891         // Add users to the admin's contact list.
1892         \core_message\api::block_user($USER->id, $user2->id);
1894         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
1896         // Block other user.
1897         \core_message\api::block_user($USER->id, $user1->id);
1898         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
1900         // Test deleting users.
1901         delete_user($user1);
1902         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
1903     }
1905     /**
1906      * Test returning contacts with unread message count.
1907      */
1908     public function test_get_contacts_with_unread_message_count() {
1909         global $DB;
1911         $user1 = self::getDataGenerator()->create_user();
1912         $user2 = self::getDataGenerator()->create_user();
1913         $user3 = self::getDataGenerator()->create_user();
1914         $user4 = self::getDataGenerator()->create_user();
1916         // Add the users to each of their contacts.
1917         \core_message\api::add_contact($user1->id, $user2->id);
1918         \core_message\api::add_contact($user2->id, $user3->id);
1920         $this->send_fake_message($user1, $user2);
1921         $this->send_fake_message($user1, $user2);
1922         $this->send_fake_message($user1, $user2);
1923         $message4id = $this->send_fake_message($user1, $user2);
1925         $this->send_fake_message($user3, $user2);
1926         $message6id = $this->send_fake_message($user3, $user2);
1927         $this->send_fake_message($user3, $user2);
1928         $this->send_fake_message($user3, $user2);
1929         $this->send_fake_message($user3, $user2);
1931         // Send a message that should never be included as the user is not a contact.
1932         $this->send_fake_message($user4, $user2);
1934         // Get the contacts and the unread message count.
1935         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
1937         // Confirm the size is correct.
1938         $this->assertCount(2, $messages);
1939         ksort($messages);
1941         $messageinfo1 = array_shift($messages);
1942         $messageinfo2 = array_shift($messages);
1944         $this->assertEquals($user1->id, $messageinfo1->id);
1945         $this->assertEquals(4, $messageinfo1->messagecount);
1946         $this->assertEquals($user3->id, $messageinfo2->id);
1947         $this->assertEquals(5, $messageinfo2->messagecount);
1949         // Mark some of the messages as read.
1950         $m4 = $DB->get_record('messages', ['id' => $message4id]);
1951         $m6 = $DB->get_record('messages', ['id' => $message6id]);
1952         \core_message\api::mark_message_as_read($user2->id, $m4);
1953         \core_message\api::mark_message_as_read($user2->id, $m6);
1955         // Get the contacts and the unread message count.
1956         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
1958         // Confirm the size is correct.
1959         $this->assertCount(2, $messages);
1960         ksort($messages);
1962         // Confirm read messages are not included.
1963         $messageinfo1 = array_shift($messages);
1964         $messageinfo2 = array_shift($messages);
1965         $this->assertEquals($user1->id, $messageinfo1->id);
1966         $this->assertEquals(3, $messageinfo1->messagecount);
1967         $this->assertEquals($user3->id, $messageinfo2->id);
1968         $this->assertEquals(4, $messageinfo2->messagecount);
1970         // Now, let's populate the database with messages from user2 to user 1.
1971         $this->send_fake_message($user2, $user1);
1972         $this->send_fake_message($user2, $user1);
1973         $messageid = $this->send_fake_message($user2, $user1);
1975         // Send a message that should never be included as the user is not a contact.
1976         $this->send_fake_message($user4, $user1);
1978         // Get the contacts and the unread message count.
1979         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
1981         // Confirm the size is correct.
1982         $this->assertCount(1, $messages);
1983         $messageinfo1 = array_shift($messages);
1984         $this->assertEquals($user2->id, $messageinfo1->id);
1985         $this->assertEquals(3, $messageinfo1->messagecount);
1987         // Mark the last message as read.
1988         $m = $DB->get_record('messages', ['id' => $messageid]);
1989         \core_message\api::mark_message_as_read($user1->id, $m);
1991         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
1993         // Confirm the size is correct.
1994         $this->assertCount(1, $messages);
1996         // Confirm read messages are not included.
1997         $messageinfo1 = array_shift($messages);
1998         $this->assertEquals($user2->id, $messageinfo1->id);
1999         $this->assertEquals(2, $messageinfo1->messagecount);
2000     }
2002     /**
2003      * Test returning contacts with unread message count when there are no messages.
2004      */
2005     public function test_get_contacts_with_unread_message_count_no_messages() {
2006         $user1 = self::getDataGenerator()->create_user();
2007         $user2 = self::getDataGenerator()->create_user();
2009         // Add the users to each of their contacts.
2010         \core_message\api::add_contact($user2->id, $user1->id);
2012         // Check we get the correct message count.
2013         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
2015         // Confirm the size is correct.
2016         $this->assertCount(1, $messages);
2018         $messageinfo = array_shift($messages);
2020         $this->assertEquals($user1->id, $messageinfo->id);
2021         $this->assertEquals(0, $messageinfo->messagecount);
2022     }
2024     /**
2025      * Test returning non-contacts with unread message count.
2026      */
2027     public function test_get_non_contacts_with_unread_message_count() {
2028         global $DB;
2030         $user1 = self::getDataGenerator()->create_user();
2031         $user2 = self::getDataGenerator()->create_user();
2032         $user3 = self::getDataGenerator()->create_user();
2033         $user4 = self::getDataGenerator()->create_user();
2035         // Add a user to the contact list of the users we are testing this function with.
2036         \core_message\api::add_contact($user1->id, $user4->id);
2037         \core_message\api::add_contact($user2->id, $user4->id);
2039         $this->send_fake_message($user1, $user2);
2040         $this->send_fake_message($user1, $user2);
2041         $this->send_fake_message($user1, $user2);
2042         $message4id = $this->send_fake_message($user1, $user2);
2044         $this->send_fake_message($user3, $user2);
2045         $message6id = $this->send_fake_message($user3, $user2);
2046         $this->send_fake_message($user3, $user2);
2047         $this->send_fake_message($user3, $user2);
2048         $this->send_fake_message($user3, $user2);
2050         // Send a message that should never be included as the user is a contact.
2051         $this->send_fake_message($user4, $user2);
2053         // Get the non-contacts and the unread message count.
2054         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2056         // Check we get the correct message count.
2057         ksort($messages);
2058         $this->assertCount(2, $messages);
2059         $messageinfo1 = array_shift($messages);
2060         $messageinfo2 = array_shift($messages);
2061         $this->assertEquals($user1->id, $messageinfo1->id);
2062         $this->assertEquals(4, $messageinfo1->messagecount);
2063         $this->assertEquals($user3->id, $messageinfo2->id);
2064         $this->assertEquals(5, $messageinfo2->messagecount);
2066         // Mark some of the messages as read.
2067         $m4 = $DB->get_record('messages', ['id' => $message4id]);
2068         $m6 = $DB->get_record('messages', ['id' => $message6id]);
2069         \core_message\api::mark_message_as_read($user2->id, $m4);
2070         \core_message\api::mark_message_as_read($user2->id, $m6);
2072         // Get the non-contacts and the unread message count.
2073         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
2075         // Check the marked message is not returned in the message count.
2076         ksort($messages);
2077         $this->assertCount(2, $messages);
2078         $messageinfo1 = array_shift($messages);
2079         $messageinfo2 = array_shift($messages);
2080         $this->assertEquals($user1->id, $messageinfo1->id);
2081         $this->assertEquals(3, $messageinfo1->messagecount);
2082         $this->assertEquals($user3->id, $messageinfo2->id);
2083         $this->assertEquals(4, $messageinfo2->messagecount);
2085         // Now, let's populate the database with messages from user2 to user 1.
2086         $this->send_fake_message($user2, $user1);
2087         $this->send_fake_message($user2, $user1);
2088         $messageid = $this->send_fake_message($user2, $user1);
2090         // Send a message that should never be included as the user is a contact.
2091         $this->send_fake_message($user4, $user1);
2093         // Get the non-contacts and the unread message count.
2094         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2096         // Confirm the size is correct.
2097         $this->assertCount(1, $messages);
2098         $messageinfo1 = array_shift($messages);
2099         $this->assertEquals($user2->id, $messageinfo1->id);
2100         $this->assertEquals(3, $messageinfo1->messagecount);
2102         // Mark the last message as read.
2103         $m = $DB->get_record('messages', ['id' => $messageid]);
2104         \core_message\api::mark_message_as_read($user1->id, $m);
2106         // Get the non-contacts and the unread message count.
2107         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
2109         // Check the marked message is not returned in the message count.
2110         $this->assertCount(1, $messages);
2111         $messageinfo1 = array_shift($messages);
2112         $this->assertEquals($user2->id, $messageinfo1->id);
2113         $this->assertEquals(2, $messageinfo1->messagecount);
2114     }
2116     /**
2117      * Test marking a message as read.
2118      */
2119     public function test_mark_message_as_read() {
2120         global $DB;
2122         $user1 = self::getDataGenerator()->create_user();
2123         $user2 = self::getDataGenerator()->create_user();
2125         $this->send_fake_message($user1, $user2);
2126         $m2id = $this->send_fake_message($user1, $user2);
2127         $this->send_fake_message($user2, $user1);
2128         $m4id = $this->send_fake_message($user2, $user1);
2130         $m2 = $DB->get_record('messages', ['id' => $m2id]);
2131         $m4 = $DB->get_record('messages', ['id' => $m4id]);
2132         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
2133         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
2135         // Confirm there are two user actions.
2136         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
2137         $this->assertEquals(2, count($muas));
2139         // Confirm they are correct.
2140         $mua1 = array_shift($muas);
2141         $mua2 = array_shift($muas);
2143         // Confirm first action.
2144         $this->assertEquals($user2->id, $mua1->userid);
2145         $this->assertEquals($m2id, $mua1->messageid);
2146         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
2147         $this->assertEquals(11, $mua1->timecreated);
2149         // Confirm second action.
2150         $this->assertEquals($user1->id, $mua2->userid);
2151         $this->assertEquals($m4id, $mua2->messageid);
2152         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
2153         $this->assertEquals(12, $mua2->timecreated);
2154     }
2156     /**
2157      * Test marking a notification as read.
2158      */
2159     public function test_mark_notification_as_read() {
2160         global $DB;
2162         $user1 = self::getDataGenerator()->create_user();
2163         $user2 = self::getDataGenerator()->create_user();
2165         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
2166         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
2167         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
2168         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
2170         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2171         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2173         \core_message\api::mark_notification_as_read($n2, 11);
2174         \core_message\api::mark_notification_as_read($n4, 12);
2176         // Retrieve the notifications.
2177         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
2178         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
2180         // Confirm they have been marked as read.
2181         $this->assertEquals(11, $n2->timeread);
2182         $this->assertEquals(12, $n4->timeread);
2183     }
2185     /**
2186      * Test a conversation is not returned if there is none.
2187      */
2188     public function test_get_conversation_between_users_no_conversation() {
2189         $user1 = self::getDataGenerator()->create_user();
2190         $user2 = self::getDataGenerator()->create_user();
2192         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2193     }
2195     /**
2196      * Test we can return a conversation that exists between users.
2197      */
2198     public function test_get_conversation_between_users_with_existing_conversation() {
2199         $user1 = self::getDataGenerator()->create_user();
2200         $user2 = self::getDataGenerator()->create_user();
2202         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2204         $this->assertEquals($conversationid,
2205             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
2206     }
2208     /**
2209      * Test can create a contact request.
2210      */
2211     public function test_can_create_contact_request() {
2212         global $CFG;
2214         $user1 = self::getDataGenerator()->create_user();
2215         $user2 = self::getDataGenerator()->create_user();
2217         // Disable messaging.
2218         $CFG->messaging = 0;
2219         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
2221         // Re-enable messaging.
2222         $CFG->messaging = 1;
2224         // Allow users to message anyone site-wide.
2225         $CFG->messagingallusers = 1;
2226         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
2228         // Disallow users from messaging anyone site-wide.
2229         $CFG->messagingallusers = 0;
2230         $this->assertFalse(\core_message\api::can_create_contact($user1->id, $user2->id));
2232         // Put the users in the same course so a contact request should be possible.
2233         $course = self::getDataGenerator()->create_course();
2234         $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2235         $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2236         $this->assertTrue(\core_message\api::can_create_contact($user1->id, $user2->id));
2237     }
2239     /**
2240      * Test creating a contact request.
2241      */
2242     public function test_create_contact_request() {
2243         global $DB;
2245         $user1 = self::getDataGenerator()->create_user();
2246         $user2 = self::getDataGenerator()->create_user();
2248         \core_message\api::create_contact_request($user1->id, $user2->id);
2250         $request = $DB->get_records('message_contact_requests');
2252         $this->assertCount(1, $request);
2254         $request = reset($request);
2256         $this->assertEquals($user1->id, $request->userid);
2257         $this->assertEquals($user2->id, $request->requesteduserid);
2258     }
2260     /**
2261      * Test confirming a contact request.
2262      */
2263     public function test_confirm_contact_request() {
2264         global $DB;
2266         $user1 = self::getDataGenerator()->create_user();
2267         $user2 = self::getDataGenerator()->create_user();
2269         \core_message\api::create_contact_request($user1->id, $user2->id);
2271         \core_message\api::confirm_contact_request($user1->id, $user2->id);
2273         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
2275         $contact = $DB->get_records('message_contacts');
2277         $this->assertCount(1, $contact);
2279         $contact = reset($contact);
2281         $this->assertEquals($user1->id, $contact->userid);
2282         $this->assertEquals($user2->id, $contact->contactid);
2283     }
2285     /**
2286      * Test declining a contact request.
2287      */
2288     public function test_decline_contact_request() {
2289         global $DB;
2291         $user1 = self::getDataGenerator()->create_user();
2292         $user2 = self::getDataGenerator()->create_user();
2294         \core_message\api::create_contact_request($user1->id, $user2->id);
2296         \core_message\api::decline_contact_request($user1->id, $user2->id);
2298         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
2299         $this->assertEquals(0, $DB->count_records('message_contacts'));
2300     }
2302     /**
2303      * Test retrieving contact requests.
2304      */
2305     public function test_get_contact_requests() {
2306         $user1 = self::getDataGenerator()->create_user();
2307         $user2 = self::getDataGenerator()->create_user();
2308         $user3 = self::getDataGenerator()->create_user();
2310         // Block one user, their request should not show up.
2311         \core_message\api::block_user($user1->id, $user3->id);
2313         \core_message\api::create_contact_request($user2->id, $user1->id);
2314         \core_message\api::create_contact_request($user3->id, $user1->id);
2316         $requests = \core_message\api::get_contact_requests($user1->id);
2318         $this->assertCount(1, $requests);
2320         $request = reset($requests);
2322         $this->assertEquals($user2->id, $request->id);
2323         $this->assertEquals($user2->picture, $request->picture);
2324         $this->assertEquals($user2->firstname, $request->firstname);
2325         $this->assertEquals($user2->lastname, $request->lastname);
2326         $this->assertEquals($user2->firstnamephonetic, $request->firstnamephonetic);
2327         $this->assertEquals($user2->lastnamephonetic, $request->lastnamephonetic);
2328         $this->assertEquals($user2->middlename, $request->middlename);
2329         $this->assertEquals($user2->alternatename, $request->alternatename);
2330         $this->assertEquals($user2->email, $request->email);
2331     }
2333     /**
2334      * Test adding contacts.
2335      */
2336     public function test_add_contact() {
2337         global $DB;
2339         $user1 = self::getDataGenerator()->create_user();
2340         $user2 = self::getDataGenerator()->create_user();
2342         \core_message\api::add_contact($user1->id, $user2->id);
2344         $contact = $DB->get_records('message_contacts');
2346         $this->assertCount(1, $contact);
2348         $contact = reset($contact);
2350         $this->assertEquals($user1->id, $contact->userid);
2351         $this->assertEquals($user2->id, $contact->contactid);
2352     }
2354     /**
2355      * Test removing contacts.
2356      */
2357     public function test_remove_contact() {
2358         global $DB;
2360         $user1 = self::getDataGenerator()->create_user();
2361         $user2 = self::getDataGenerator()->create_user();
2363         \core_message\api::add_contact($user1->id, $user2->id);
2364         \core_message\api::remove_contact($user1->id, $user2->id);
2366         $this->assertEquals(0, $DB->count_records('message_contacts'));
2367     }
2369     /**
2370      * Test blocking users.
2371      */
2372     public function test_block_user() {
2373         global $DB;
2375         $user1 = self::getDataGenerator()->create_user();
2376         $user2 = self::getDataGenerator()->create_user();
2378         \core_message\api::block_user($user1->id, $user2->id);
2380         $blockedusers = $DB->get_records('message_users_blocked');
2382         $this->assertCount(1, $blockedusers);
2384         $blockeduser = reset($blockedusers);
2386         $this->assertEquals($user1->id, $blockeduser->userid);
2387         $this->assertEquals($user2->id, $blockeduser->blockeduserid);
2388     }
2390     /**
2391      * Test unblocking users.
2392      */
2393     public function test_unblock_user() {
2394         global $DB;
2396         $user1 = self::getDataGenerator()->create_user();
2397         $user2 = self::getDataGenerator()->create_user();
2399         \core_message\api::block_user($user1->id, $user2->id);
2400         \core_message\api::unblock_user($user1->id, $user2->id);
2402         $this->assertEquals(0, $DB->count_records('message_users_blocked'));
2403     }
2405     /**
2406      * Test is contact check.
2407      */
2408     public function test_is_contact() {
2409         $user1 = self::getDataGenerator()->create_user();
2410         $user2 = self::getDataGenerator()->create_user();
2411         $user3 = self::getDataGenerator()->create_user();
2413         \core_message\api::add_contact($user1->id, $user2->id);
2415         $this->assertTrue(\core_message\api::is_contact($user1->id, $user2->id));
2416         $this->assertTrue(\core_message\api::is_contact($user2->id, $user1->id));
2417         $this->assertFalse(\core_message\api::is_contact($user2->id, $user3->id));
2418     }
2420     /**
2421      * Test get contact.
2422      */
2423     public function test_get_contact() {
2424         $user1 = self::getDataGenerator()->create_user();
2425         $user2 = self::getDataGenerator()->create_user();
2427         \core_message\api::add_contact($user1->id, $user2->id);
2429         $contact = \core_message\api::get_contact($user1->id, $user2->id);
2431         $this->assertEquals($user1->id, $contact->userid);
2432         $this->assertEquals($user2->id, $contact->contactid);
2433     }
2435     /**
2436      * Test is blocked checked.
2437      */
2438     public function test_is_blocked() {
2439         $user1 = self::getDataGenerator()->create_user();
2440         $user2 = self::getDataGenerator()->create_user();
2442         $this->assertFalse(\core_message\api::is_blocked($user1->id, $user2->id));
2443         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
2445         \core_message\api::block_user($user1->id, $user2->id);
2447         $this->assertTrue(\core_message\api::is_blocked($user1->id, $user2->id));
2448         $this->assertFalse(\core_message\api::is_blocked($user2->id, $user1->id));
2449     }
2451     /**
2452      * Test the contact request exist check.
2453      */
2454     public function test_does_contact_request_exist() {
2455         $user1 = self::getDataGenerator()->create_user();
2456         $user2 = self::getDataGenerator()->create_user();
2458         $this->assertFalse(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
2459         $this->assertFalse(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
2461         \core_message\api::create_contact_request($user1->id, $user2->id);
2463         $this->assertTrue(\core_message\api::does_contact_request_exist($user1->id, $user2->id));
2464         $this->assertTrue(\core_message\api::does_contact_request_exist($user2->id, $user1->id));
2465     }
2467     /**
2468      * Test the user in conversation check.
2469      */
2470     public function test_is_user_in_conversation() {
2471         $user1 = self::getDataGenerator()->create_user();
2472         $user2 = self::getDataGenerator()->create_user();
2474         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2476         $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $conversationid));
2477     }
2479     /**
2480      * Test the user in conversation check when they are not.
2481      */
2482     public function test_is_user_in_conversation_when_not() {
2483         $user1 = self::getDataGenerator()->create_user();
2484         $user2 = self::getDataGenerator()->create_user();
2485         $user3 = self::getDataGenerator()->create_user();
2487         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
2489         $this->assertFalse(\core_message\api::is_user_in_conversation($user3->id, $conversationid));
2490     }
2492     /**
2493      * Comparison function for sorting contacts.
2494      *
2495      * @param stdClass $a
2496      * @param stdClass $b
2497      * @return bool
2498      */
2499     protected static function sort_contacts($a, $b) {
2500         return $a->userid > $b->userid;
2501     }