MDL-63426 repository_dropbox: Use post 2017 icon
[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         // Set this user as the admin.
106         $this->setAdminUser();
108         // Create users to add to the admin's contact list.
109         $user1 = $this->getDataGenerator()->create_user();
110         $user2 = $this->getDataGenerator()->create_user();
112         $this->assertEquals(0, \core_message\api::count_blocked_users());
114         // Add 1 blocked and 1 normal contact to admin's contact list.
115         message_add_contact($user1->id);
116         message_add_contact($user2->id, 1);
118         $this->assertEquals(0, \core_message\api::count_blocked_users($user2));
119         $this->assertEquals(1, \core_message\api::count_blocked_users());
120     }
122     /**
123      * Tests searching users in a course.
124      */
125     public function test_search_users_in_course() {
126         // Create some users.
127         $user1 = new stdClass();
128         $user1->firstname = 'User';
129         $user1->lastname = 'One';
130         $user1 = self::getDataGenerator()->create_user($user1);
132         // The person doing the search.
133         $this->setUser($user1);
135         // Second user is going to have their last access set to now, so they are online.
136         $user2 = new stdClass();
137         $user2->firstname = 'User';
138         $user2->lastname = 'Two';
139         $user2->lastaccess = time();
140         $user2 = self::getDataGenerator()->create_user($user2);
142         // Block the second user.
143         message_block_contact($user2->id, $user1->id);
145         $user3 = new stdClass();
146         $user3->firstname = 'User';
147         $user3->lastname = 'Three';
148         $user3 = self::getDataGenerator()->create_user($user3);
150         // Create a course.
151         $course1 = new stdClass();
152         $course1->fullname = 'Course';
153         $course1->shortname = 'One';
154         $course1 = $this->getDataGenerator()->create_course($course1);
156         // Enrol the searcher and one user in the course.
157         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
158         $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
160         // Perform a search.
161         $results = \core_message\api::search_users_in_course($user1->id, $course1->id, 'User');
163         $this->assertEquals(1, count($results));
165         $user = $results[0];
166         $this->assertEquals($user2->id, $user->userid);
167         $this->assertEquals(fullname($user2), $user->fullname);
168         $this->assertFalse($user->ismessaging);
169         $this->assertNull($user->lastmessage);
170         $this->assertNull($user->messageid);
171         $this->assertNull($user->isonline);
172         $this->assertFalse($user->isread);
173         $this->assertTrue($user->isblocked);
174         $this->assertNull($user->unreadcount);
175     }
177     /**
178      * Tests searching users.
179      */
180     public function test_search_users() {
181         global $DB;
183         // Create some users.
184         $user1 = new stdClass();
185         $user1->firstname = 'User';
186         $user1->lastname = 'One';
187         $user1 = self::getDataGenerator()->create_user($user1);
189         // Set as the user performing the search.
190         $this->setUser($user1);
192         $user2 = new stdClass();
193         $user2->firstname = 'User search';
194         $user2->lastname = 'Two';
195         $user2 = self::getDataGenerator()->create_user($user2);
197         $user3 = new stdClass();
198         $user3->firstname = 'User search';
199         $user3->lastname = 'Three';
200         $user3 = self::getDataGenerator()->create_user($user3);
202         $user4 = new stdClass();
203         $user4->firstname = 'User';
204         $user4->lastname = 'Four';
205         $user4 = self::getDataGenerator()->create_user($user4);
207         $user5 = new stdClass();
208         $user5->firstname = 'User search';
209         $user5->lastname = 'Five';
210         $user5 = self::getDataGenerator()->create_user($user5);
212         $user6 = new stdClass();
213         $user6->firstname = 'User';
214         $user6->lastname = 'Six';
215         $user6 = self::getDataGenerator()->create_user($user6);
217         // Create some courses.
218         $course1 = new stdClass();
219         $course1->fullname = 'Course search';
220         $course1->shortname = 'One';
221         $course1 = $this->getDataGenerator()->create_course($course1);
223         $course2 = new stdClass();
224         $course2->fullname = 'Course';
225         $course2->shortname = 'Two';
226         $course2 = $this->getDataGenerator()->create_course($course2);
228         $course3 = new stdClass();
229         $course3->fullname = 'Course';
230         $course3->shortname = 'Three search';
231         $course3 = $this->getDataGenerator()->create_course($course3);
233         $course4 = new stdClass();
234         $course4->fullname = 'Course Four';
235         $course4->shortname = 'CF100';
236         $course4 = $this->getDataGenerator()->create_course($course4);
238         $course5 = new stdClass();
239         $course5->fullname = 'Course';
240         $course5->shortname = 'Five search';
241         $course5 = $this->getDataGenerator()->create_course($course5);
243         $role = $DB->get_record('role', ['shortname' => 'student']);
244         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $role->id);
245         $this->getDataGenerator()->enrol_user($user1->id, $course2->id, $role->id);
246         $this->getDataGenerator()->enrol_user($user1->id, $course3->id, $role->id);
247         $this->getDataGenerator()->enrol_user($user1->id, $course5->id, $role->id);
249         // Add some users as contacts.
250         message_add_contact($user2->id, 0, $user1->id);
251         message_add_contact($user3->id, 0, $user1->id);
252         message_add_contact($user4->id, 0, $user1->id);
254         // Remove the viewparticipants capability from one of the courses.
255         $course5context = context_course::instance($course5->id);
256         assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $role->id, $course5context->id);
258         // Perform a search.
259         list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
261         // Check that we retrieved the correct contacts.
262         $this->assertEquals(2, count($contacts));
263         $this->assertEquals($user3->id, $contacts[0]->userid);
264         $this->assertEquals($user2->id, $contacts[1]->userid);
266         // Check that we retrieved the correct courses.
267         $this->assertEquals(2, count($courses));
268         $this->assertEquals($course3->id, $courses[0]->id);
269         $this->assertEquals($course1->id, $courses[1]->id);
271         // Check that we retrieved the correct non-contacts.
272         $this->assertEquals(1, count($noncontacts));
273         $this->assertEquals($user5->id, $noncontacts[0]->userid);
274     }
276     /**
277      * Tests searching messages.
278      */
279     public function test_search_messages() {
280         // Create some users.
281         $user1 = self::getDataGenerator()->create_user();
282         $user2 = self::getDataGenerator()->create_user();
284         // The person doing the search.
285         $this->setUser($user1);
287         // Send some messages back and forth.
288         $time = 1;
289         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time);
290         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 1);
291         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
292         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 3);
294         // Perform a search.
295         $messages = \core_message\api::search_messages($user1->id, 'o');
297         // Confirm the data is correct.
298         $this->assertEquals(2, count($messages));
300         $message1 = $messages[0];
301         $message2 = $messages[1];
303         $this->assertEquals($user2->id, $message1->userid);
304         $this->assertEquals($user2->id, $message1->useridfrom);
305         $this->assertEquals(fullname($user2), $message1->fullname);
306         $this->assertTrue($message1->ismessaging);
307         $this->assertEquals('Word.', $message1->lastmessage);
308         $this->assertNotEmpty($message1->messageid);
309         $this->assertNull($message1->isonline);
310         $this->assertFalse($message1->isread);
311         $this->assertFalse($message1->isblocked);
312         $this->assertNull($message1->unreadcount);
314         $this->assertEquals($user2->id, $message2->userid);
315         $this->assertEquals($user1->id, $message2->useridfrom);
316         $this->assertEquals(fullname($user2), $message2->fullname);
317         $this->assertTrue($message2->ismessaging);
318         $this->assertEquals('Yo!', $message2->lastmessage);
319         $this->assertNotEmpty($message2->messageid);
320         $this->assertNull($message2->isonline);
321         $this->assertTrue($message2->isread);
322         $this->assertFalse($message2->isblocked);
323         $this->assertNull($message2->unreadcount);
324     }
326     /**
327      * Tests retrieving conversations.
328      */
329     public function test_get_conversations() {
330         // Create some users.
331         $user1 = self::getDataGenerator()->create_user();
332         $user2 = self::getDataGenerator()->create_user();
333         $user3 = self::getDataGenerator()->create_user();
334         $user4 = self::getDataGenerator()->create_user();
336         // The person doing the search.
337         $this->setUser($user1);
339         // No conversations yet.
340         $this->assertEquals([], \core_message\api::get_conversations($user1->id));
342         // Send some messages back and forth, have some different conversations with different users.
343         $time = 1;
344         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
345         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
346         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
347         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
349         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
350         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
351         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
352         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
354         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
355         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
356         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
358         // Retrieve the conversations.
359         $conversations = \core_message\api::get_conversations($user1->id);
361         // Confirm the data is correct.
362         $this->assertEquals(3, count($conversations));
364         $message1 = array_shift($conversations);
365         $message2 = array_shift($conversations);
366         $message3 = array_shift($conversations);
368         $this->assertEquals($user4->id, $message1->userid);
369         $this->assertEquals($user1->id, $message1->useridfrom);
370         $this->assertTrue($message1->ismessaging);
371         $this->assertEquals('Dope.', $message1->lastmessage);
372         $this->assertEquals($messageid3, $message1->messageid);
373         $this->assertNull($message1->isonline);
374         $this->assertFalse($message1->isread);
375         $this->assertFalse($message1->isblocked);
376         $this->assertEquals(1, $message1->unreadcount);
378         $this->assertEquals($user3->id, $message2->userid);
379         $this->assertEquals($user3->id, $message2->useridfrom);
380         $this->assertTrue($message2->ismessaging);
381         $this->assertEquals('Cool.', $message2->lastmessage);
382         $this->assertEquals($messageid2, $message2->messageid);
383         $this->assertNull($message2->isonline);
384         $this->assertFalse($message2->isread);
385         $this->assertFalse($message2->isblocked);
386         $this->assertEquals(2, $message2->unreadcount);
388         $this->assertEquals($user2->id, $message3->userid);
389         $this->assertEquals($user2->id, $message3->useridfrom);
390         $this->assertTrue($message3->ismessaging);
391         $this->assertEquals('Word.', $message3->lastmessage);
392         $this->assertEquals($messageid1, $message3->messageid);
393         $this->assertNull($message3->isonline);
394         $this->assertFalse($message3->isread);
395         $this->assertFalse($message3->isblocked);
396         $this->assertEquals(2, $message3->unreadcount);
397     }
399     /**
400      * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
401      */
402     public function test_get_conversations_limit_offset() {
403         // Create some users.
404         $user1 = self::getDataGenerator()->create_user();
405         $user2 = self::getDataGenerator()->create_user();
406         $user3 = self::getDataGenerator()->create_user();
407         $user4 = self::getDataGenerator()->create_user();
409         // The person doing the search.
410         $this->setUser($user1);
412         // Send some messages back and forth, have some different conversations with different users.
413         $time = 1;
414         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
415         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
416         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
417         $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
419         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
420         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
421         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
422         $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
424         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
425         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
426         $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
428         // Retrieve the conversations.
429         $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
431         // We should only have one conversation because of the limit.
432         $this->assertCount(1, $conversations);
434         $conversation = array_shift($conversations);
436         $this->assertEquals($user3->id, $conversation->userid);
437         $this->assertEquals($user3->id, $conversation->useridfrom);
438         $this->assertTrue($conversation->ismessaging);
439         $this->assertEquals('Cool.', $conversation->lastmessage);
440         $this->assertEquals($messageid2, $conversation->messageid);
441         $this->assertNull($conversation->isonline);
442         $this->assertFalse($conversation->isread);
443         $this->assertFalse($conversation->isblocked);
444         $this->assertEquals(2, $conversation->unreadcount);
446         // Retrieve the next conversation.
447         $conversations = \core_message\api::get_conversations($user1->id, 2, 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($user2->id, $conversation->userid);
455         $this->assertEquals($user2->id, $conversation->useridfrom);
456         $this->assertTrue($conversation->ismessaging);
457         $this->assertEquals('Word.', $conversation->lastmessage);
458         $this->assertEquals($messageid1, $conversation->messageid);
459         $this->assertNull($conversation->isonline);
460         $this->assertFalse($conversation->isread);
461         $this->assertFalse($conversation->isblocked);
462         $this->assertEquals(2, $conversation->unreadcount);
464         // Ask for an offset that doesn't exist.
465         $conversations = \core_message\api::get_conversations($user1->id, 4, 1);
467         // We should not get any conversations back.
468         $this->assertCount(0, $conversations);
469     }
471     /**
472      * Tests retrieving conversations when a conversation contains a deleted user.
473      */
474     public function test_get_conversations_with_deleted_user() {
475         // Create some users.
476         $user1 = self::getDataGenerator()->create_user();
477         $user2 = self::getDataGenerator()->create_user();
478         $user3 = self::getDataGenerator()->create_user();
480         // Send some messages back and forth, have some different conversations with different users.
481         $time = 1;
482         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
483         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
484         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
485         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
487         $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
488         $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
489         $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
490         $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
492         // Delete the second user.
493         delete_user($user2);
495         // Retrieve the conversations.
496         $conversations = \core_message\api::get_conversations($user1->id);
498         // We should only have one conversation because the other user was deleted.
499         $this->assertCount(1, $conversations);
501         // Confirm the conversation is from the non-deleted user.
502         $conversation = reset($conversations);
503         $this->assertEquals($user3->id, $conversation->userid);
504     }
506    /**
507     * The data provider for get_conversations_mixed.
508     *
509     * This provides sets of data to for testing.
510     * @return array
511     */
512    public function get_conversations_mixed_provider() {
513        return array(
514             'Test that conversations with messages contacts is correctly ordered.' => array(
515                 'users' => array(
516                     'user1',
517                     'user2',
518                     'user3',
519                 ),
520                 'contacts' => array(
521                 ),
522                 'messages' => array(
523                     array(
524                         'from'          => 'user1',
525                         'to'            => 'user2',
526                         'state'         => 'unread',
527                         'subject'       => 'S1',
528                     ),
529                     array(
530                         'from'          => 'user2',
531                         'to'            => 'user1',
532                         'state'         => 'unread',
533                         'subject'       => 'S2',
534                     ),
535                     array(
536                         'from'          => 'user1',
537                         'to'            => 'user2',
538                         'state'         => 'unread',
539                         'timecreated'   => 0,
540                         'subject'       => 'S3',
541                     ),
542                     array(
543                         'from'          => 'user1',
544                         'to'            => 'user3',
545                         'state'         => 'read',
546                         'timemodifier'  => 1,
547                         'subject'       => 'S4',
548                     ),
549                     array(
550                         'from'          => 'user3',
551                         'to'            => 'user1',
552                         'state'         => 'read',
553                         'timemodifier'  => 1,
554                         'subject'       => 'S5',
555                     ),
556                     array(
557                         'from'          => 'user1',
558                         'to'            => 'user3',
559                         'state'         => 'read',
560                         'timecreated'   => 0,
561                         'subject'       => 'S6',
562                     ),
563                 ),
564                 'expectations' => array(
565                     'user1' => array(
566                         // User1 has conversed most recently with user3. The most recent message is M5.
567                         array(
568                             'messageposition'   => 0,
569                             'with'              => 'user3',
570                             'subject'           => 'S5',
571                             'unreadcount'       => 0,
572                         ),
573                         // User1 has also conversed with user2. The most recent message is S2.
574                         array(
575                             'messageposition'   => 1,
576                             'with'              => 'user2',
577                             'subject'           => 'S2',
578                             'unreadcount'       => 1,
579                         ),
580                     ),
581                     'user2' => array(
582                         // User2 has only conversed with user1. Their most recent shared message was S2.
583                         array(
584                             'messageposition'   => 0,
585                             'with'              => 'user1',
586                             'subject'           => 'S2',
587                             'unreadcount'       => 2,
588                         ),
589                     ),
590                     'user3' => array(
591                         // User3 has only conversed with user1. Their most recent shared message was S5.
592                         array(
593                             'messageposition'   => 0,
594                             'with'              => 'user1',
595                             'subject'           => 'S5',
596                             'unreadcount'       => 0,
597                         ),
598                     ),
599                 ),
600             ),
601             'Test that users with contacts and messages to self work as expected' => array(
602                 'users' => array(
603                     'user1',
604                     'user2',
605                     'user3',
606                 ),
607                 'contacts' => array(
608                     'user1' => array(
609                         'user2' => 0,
610                         'user3' => 0,
611                     ),
612                     'user2' => array(
613                         'user3' => 0,
614                     ),
615                 ),
616                 'messages' => array(
617                     array(
618                         'from'          => 'user1',
619                         'to'            => 'user1',
620                         'state'         => 'unread',
621                         'subject'       => 'S1',
622                     ),
623                     array(
624                         'from'          => 'user1',
625                         'to'            => 'user1',
626                         'state'         => 'unread',
627                         'subject'       => 'S2',
628                     ),
629                 ),
630                 'expectations' => array(
631                     'user1' => array(
632                         // User1 has conversed most recently with user1. The most recent message is S2.
633                         array(
634                             'messageposition'   => 0,
635                             'with'              => 'user1',
636                             'subject'           => 'S2',
637                             'unreadcount'       => 0, // Messages sent to and from the same user are counted as read.
638                         ),
639                     ),
640                 ),
641             ),
642             'Test conversations with a single user, where some messages are read and some are not.' => array(
643                 'users' => array(
644                     'user1',
645                     'user2',
646                 ),
647                 'contacts' => array(
648                 ),
649                 'messages' => array(
650                     array(
651                         'from'          => 'user1',
652                         'to'            => 'user2',
653                         'state'         => 'read',
654                         'subject'       => 'S1',
655                     ),
656                     array(
657                         'from'          => 'user2',
658                         'to'            => 'user1',
659                         'state'         => 'read',
660                         'subject'       => 'S2',
661                     ),
662                     array(
663                         'from'          => 'user1',
664                         'to'            => 'user2',
665                         'state'         => 'unread',
666                         'timemodifier'  => 1,
667                         'subject'       => 'S3',
668                     ),
669                     array(
670                         'from'          => 'user1',
671                         'to'            => 'user2',
672                         'state'         => 'unread',
673                         'timemodifier'  => 1,
674                         'subject'       => 'S4',
675                     ),
676                 ),
677                 'expectations' => array(
678                     // The most recent message between user1 and user2 was S4.
679                     'user1' => array(
680                         array(
681                             'messageposition'   => 0,
682                             'with'              => 'user2',
683                             'subject'           => 'S4',
684                             'unreadcount'       => 0,
685                         ),
686                     ),
687                     'user2' => array(
688                         // The most recent message between user1 and user2 was S4.
689                         array(
690                             'messageposition'   => 0,
691                             'with'              => 'user1',
692                             'subject'           => 'S4',
693                             'unreadcount'       => 2,
694                         ),
695                     ),
696                 ),
697             ),
698             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
699             'are out of order' => array(
700             // This can happen through a combination of factors including multi-master DB replication with messages
701             // read somehow (e.g. API).
702                 'users' => array(
703                     'user1',
704                     'user2',
705                 ),
706                 'contacts' => array(
707                 ),
708                 'messages' => array(
709                     array(
710                         'from'          => 'user1',
711                         'to'            => 'user2',
712                         'state'         => 'read',
713                         'subject'       => 'S1',
714                         'timemodifier'  => 1,
715                     ),
716                     array(
717                         'from'          => 'user2',
718                         'to'            => 'user1',
719                         'state'         => 'read',
720                         'subject'       => 'S2',
721                         'timemodifier'  => 2,
722                     ),
723                     array(
724                         'from'          => 'user1',
725                         'to'            => 'user2',
726                         'state'         => 'unread',
727                         'subject'       => 'S3',
728                     ),
729                     array(
730                         'from'          => 'user1',
731                         'to'            => 'user2',
732                         'state'         => 'unread',
733                         'subject'       => 'S4',
734                     ),
735                 ),
736                 'expectations' => array(
737                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
738                     'user1' => array(
739                         array(
740                             'messageposition'   => 0,
741                             'with'              => 'user2',
742                             'subject'           => 'S2',
743                             'unreadcount'       => 0,
744                         ),
745                     ),
746                     'user2' => array(
747                         array(
748                             'messageposition'   => 0,
749                             'with'              => 'user1',
750                             'subject'           => 'S2',
751                             'unreadcount'       => 2
752                         ),
753                     ),
754                 ),
755             ),
756             'Test unread message count is correct for both users' => array(
757                 'users' => array(
758                     'user1',
759                     'user2',
760                 ),
761                 'contacts' => array(
762                 ),
763                 'messages' => array(
764                     array(
765                         'from'          => 'user1',
766                         'to'            => 'user2',
767                         'state'         => 'read',
768                         'subject'       => 'S1',
769                         'timemodifier'  => 1,
770                     ),
771                     array(
772                         'from'          => 'user2',
773                         'to'            => 'user1',
774                         'state'         => 'read',
775                         'subject'       => 'S2',
776                         'timemodifier'  => 2,
777                     ),
778                     array(
779                         'from'          => 'user1',
780                         'to'            => 'user2',
781                         'state'         => 'read',
782                         'subject'       => 'S3',
783                         'timemodifier'  => 3,
784                     ),
785                     array(
786                         'from'          => 'user1',
787                         'to'            => 'user2',
788                         'state'         => 'read',
789                         'subject'       => 'S4',
790                         'timemodifier'  => 4,
791                     ),
792                     array(
793                         'from'          => 'user1',
794                         'to'            => 'user2',
795                         'state'         => 'unread',
796                         'subject'       => 'S5',
797                         'timemodifier'  => 5,
798                     ),
799                     array(
800                         'from'          => 'user2',
801                         'to'            => 'user1',
802                         'state'         => 'unread',
803                         'subject'       => 'S6',
804                         'timemodifier'  => 6,
805                     ),
806                     array(
807                         'from'          => 'user1',
808                         'to'            => 'user2',
809                         'state'         => 'unread',
810                         'subject'       => 'S7',
811                         'timemodifier'  => 7,
812                     ),
813                     array(
814                         'from'          => 'user1',
815                         'to'            => 'user2',
816                         'state'         => 'unread',
817                         'subject'       => 'S8',
818                         'timemodifier'  => 8,
819                     ),
820                 ),
821                 'expectations' => array(
822                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
823                     'user1' => array(
824                         array(
825                             'messageposition'   => 0,
826                             'with'              => 'user2',
827                             'subject'           => 'S8',
828                             'unreadcount'       => 1,
829                         ),
830                     ),
831                     'user2' => array(
832                         array(
833                             'messageposition'   => 0,
834                             'with'              => 'user1',
835                             'subject'           => 'S8',
836                             'unreadcount'       => 3,
837                         ),
838                     ),
839                 ),
840             ),
841         );
842     }
844     /**
845      * Test get_conversations with a mixture of messages.
846      *
847      * @dataProvider get_conversations_mixed_provider
848      * @param array $usersdata The list of users to create for this test.
849      * @param array $messagesdata The list of messages to create.
850      * @param array $expectations The list of expected outcomes.
851      */
852     public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
853         global $DB;
855         // Create all of the users.
856         $users = array();
857         foreach ($usersdata as $username) {
858             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
859         }
861         foreach ($contacts as $username => $contact) {
862             foreach ($contact as $contactname => $blocked) {
863                 $record = new stdClass();
864                 $record->userid     = $users[$username]->id;
865                 $record->contactid  = $users[$contactname]->id;
866                 $record->blocked    = $blocked;
867                 $record->id = $DB->insert_record('message_contacts', $record);
868             }
869         }
871         $defaulttimecreated = time();
872         foreach ($messagesdata as $messagedata) {
873             $from       = $users[$messagedata['from']];
874             $to         = $users[$messagedata['to']];
875             $subject    = $messagedata['subject'];
877             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
878                 $messageid = $this->send_fake_message($from, $to, $subject);
879             } else {
880                 // If there is no state, or the state is not 'unread', assume the message is read.
881                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
882             }
884             $updatemessage = new stdClass();
885             $updatemessage->id = $messageid;
886             if (isset($messagedata['timecreated'])) {
887                 $updatemessage->timecreated = $messagedata['timecreated'];
888             } else if (isset($messagedata['timemodifier'])) {
889                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
890             } else {
891                 $updatemessage->timecreated = $defaulttimecreated;
892             }
894             $DB->update_record('messages', $updatemessage);
895         }
897         foreach ($expectations as $username => $data) {
898             // Get the recent conversations for the specified user.
899             $user = $users[$username];
900             $conversations = array_values(\core_message\api::get_conversations($user->id));
901             foreach ($data as $expectation) {
902                 $otheruser = $users[$expectation['with']];
903                 $conversation = $conversations[$expectation['messageposition']];
904                 $this->assertEquals($otheruser->id, $conversation->userid);
905                 $this->assertEquals($expectation['subject'], $conversation->lastmessage);
906                 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
907             }
908         }
909     }
911     /**
912      * Tests retrieving contacts.
913      */
914     public function test_get_contacts() {
915         // Create some users.
916         $user1 = self::getDataGenerator()->create_user();
918         // Set as the user.
919         $this->setUser($user1);
921         $user2 = new stdClass();
922         $user2->firstname = 'User';
923         $user2->lastname = 'A';
924         $user2 = self::getDataGenerator()->create_user($user2);
926         $user3 = new stdClass();
927         $user3->firstname = 'User';
928         $user3->lastname = 'B';
929         $user3 = self::getDataGenerator()->create_user($user3);
931         $user4 = new stdClass();
932         $user4->firstname = 'User';
933         $user4->lastname = 'C';
934         $user4 = self::getDataGenerator()->create_user($user4);
936         $user5 = new stdClass();
937         $user5->firstname = 'User';
938         $user5->lastname = 'D';
939         $user5 = self::getDataGenerator()->create_user($user5);
941         // Add some users as contacts.
942         message_add_contact($user2->id, 0, $user1->id);
943         message_add_contact($user3->id, 0, $user1->id);
944         message_add_contact($user4->id, 0, $user1->id);
946         // Retrieve the contacts.
947         $contacts = \core_message\api::get_contacts($user1->id);
949         // Confirm the data is correct.
950         $this->assertEquals(3, count($contacts));
952         $contact1 = $contacts[0];
953         $contact2 = $contacts[1];
954         $contact3 = $contacts[2];
956         $this->assertEquals($user2->id, $contact1->userid);
957         $this->assertEmpty($contact1->useridfrom);
958         $this->assertFalse($contact1->ismessaging);
959         $this->assertNull($contact1->lastmessage);
960         $this->assertNull($contact1->messageid);
961         $this->assertNull($contact1->isonline);
962         $this->assertFalse($contact1->isread);
963         $this->assertFalse($contact1->isblocked);
964         $this->assertNull($contact1->unreadcount);
966         $this->assertEquals($user3->id, $contact2->userid);
967         $this->assertEmpty($contact2->useridfrom);
968         $this->assertFalse($contact2->ismessaging);
969         $this->assertNull($contact2->lastmessage);
970         $this->assertNull($contact2->messageid);
971         $this->assertNull($contact2->isonline);
972         $this->assertFalse($contact2->isread);
973         $this->assertFalse($contact2->isblocked);
974         $this->assertNull($contact2->unreadcount);
976         $this->assertEquals($user4->id, $contact3->userid);
977         $this->assertEmpty($contact3->useridfrom);
978         $this->assertFalse($contact3->ismessaging);
979         $this->assertNull($contact3->lastmessage);
980         $this->assertNull($contact3->messageid);
981         $this->assertNull($contact3->isonline);
982         $this->assertFalse($contact3->isread);
983         $this->assertFalse($contact3->isblocked);
984         $this->assertNull($contact3->unreadcount);
985     }
987     /**
988      * Tests retrieving messages.
989      */
990     public function test_get_messages() {
991         // Create some users.
992         $user1 = self::getDataGenerator()->create_user();
993         $user2 = self::getDataGenerator()->create_user();
995         // The person doing the search.
996         $this->setUser($user1);
998         // Send some messages back and forth.
999         $time = 1;
1000         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1001         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1002         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1003         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1005         // Retrieve the messages.
1006         $messages = \core_message\api::get_messages($user1->id, $user2->id);
1008         // Confirm the message data is correct.
1009         $this->assertEquals(4, count($messages));
1011         $message1 = $messages[0];
1012         $message2 = $messages[1];
1013         $message3 = $messages[2];
1014         $message4 = $messages[3];
1016         $this->assertEquals($user1->id, $message1->useridfrom);
1017         $this->assertEquals($user2->id, $message1->useridto);
1018         $this->assertTrue($message1->displayblocktime);
1019         $this->assertContains('Yo!', $message1->text);
1021         $this->assertEquals($user2->id, $message2->useridfrom);
1022         $this->assertEquals($user1->id, $message2->useridto);
1023         $this->assertFalse($message2->displayblocktime);
1024         $this->assertContains('Sup mang?', $message2->text);
1026         $this->assertEquals($user1->id, $message3->useridfrom);
1027         $this->assertEquals($user2->id, $message3->useridto);
1028         $this->assertFalse($message3->displayblocktime);
1029         $this->assertContains('Writing PHPUnit tests!', $message3->text);
1031         $this->assertEquals($user2->id, $message4->useridfrom);
1032         $this->assertEquals($user1->id, $message4->useridto);
1033         $this->assertFalse($message4->displayblocktime);
1034         $this->assertContains('Word.', $message4->text);
1035     }
1037     /**
1038      * Tests retrieving most recent message.
1039      */
1040     public function test_get_most_recent_message() {
1041         // Create some users.
1042         $user1 = self::getDataGenerator()->create_user();
1043         $user2 = self::getDataGenerator()->create_user();
1045         // The person doing the search.
1046         $this->setUser($user1);
1048         // Send some messages back and forth.
1049         $time = 1;
1050         $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1051         $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1052         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1053         $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1055         // Retrieve the most recent messages.
1056         $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
1058         // Check the results are correct.
1059         $this->assertEquals($user2->id, $message->useridfrom);
1060         $this->assertEquals($user1->id, $message->useridto);
1061         $this->assertContains('Word.', $message->text);
1062     }
1064     /**
1065      * Tests retrieving a user's profile.
1066      */
1067     public function test_get_profile() {
1068         // Create some users.
1069         $user1 = self::getDataGenerator()->create_user();
1071         $user2 = new stdClass();
1072         $user2->country = 'AU';
1073         $user2->city = 'Perth';
1074         $user2 = self::getDataGenerator()->create_user($user2);
1076         // The person doing the search.
1077         $this->setUser($user1);
1079         // Get the profile.
1080         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1082         $this->assertEquals($user2->id, $profile->userid);
1083         $this->assertEmpty($profile->email);
1084         $this->assertEmpty($profile->country);
1085         $this->assertEmpty($profile->city);
1086         $this->assertEquals(fullname($user2), $profile->fullname);
1087         $this->assertNull($profile->isonline);
1088         $this->assertFalse($profile->isblocked);
1089         $this->assertFalse($profile->iscontact);
1090     }
1092     /**
1093      * Tests retrieving a user's profile.
1094      */
1095     public function test_get_profile_as_admin() {
1096         // The person doing the search.
1097         $this->setAdminUser();
1099         // Create some users.
1100         $user1 = self::getDataGenerator()->create_user();
1102         $user2 = new stdClass();
1103         $user2->country = 'AU';
1104         $user2->city = 'Perth';
1105         $user2 = self::getDataGenerator()->create_user($user2);
1107         // Get the profile.
1108         $profile = \core_message\api::get_profile($user1->id, $user2->id);
1110         $this->assertEquals($user2->id, $profile->userid);
1111         $this->assertEquals($user2->email, $profile->email);
1112         $this->assertEquals($user2->country, $profile->country);
1113         $this->assertEquals($user2->city, $profile->city);
1114         $this->assertEquals(fullname($user2), $profile->fullname);
1115         $this->assertFalse($profile->isonline);
1116         $this->assertFalse($profile->isblocked);
1117         $this->assertFalse($profile->iscontact);
1118     }
1120     /**
1121      * Tests checking if a user can delete a conversation.
1122      */
1123     public function test_can_delete_conversation() {
1124         // Set as the admin.
1125         $this->setAdminUser();
1127         // Create some users.
1128         $user1 = self::getDataGenerator()->create_user();
1129         $user2 = self::getDataGenerator()->create_user();
1131         // The admin can do anything.
1132         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id));
1134         // Set as the user 1.
1135         $this->setUser($user1);
1137         // They can delete their own messages.
1138         $this->assertTrue(\core_message\api::can_delete_conversation($user1->id));
1140         // They can't delete someone elses.
1141         $this->assertFalse(\core_message\api::can_delete_conversation($user2->id));
1142     }
1144     /**
1145      * Tests deleting a conversation.
1146      */
1147     public function test_delete_conversation() {
1148         global $DB;
1150         // Create some users.
1151         $user1 = self::getDataGenerator()->create_user();
1152         $user2 = self::getDataGenerator()->create_user();
1154         // The person doing the search.
1155         $this->setUser($user1);
1157         // Send some messages back and forth.
1158         $time = 1;
1159         $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1160         $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1161         $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1162         $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1164         // Delete the conversation as user 1.
1165         \core_message\api::delete_conversation($user1->id, $user2->id);
1167         $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
1168         $this->assertCount(4, $muas);
1169         // Sort by id.
1170         ksort($muas);
1172         $mua1 = array_shift($muas);
1173         $mua2 = array_shift($muas);
1174         $mua3 = array_shift($muas);
1175         $mua4 = array_shift($muas);
1177         $this->assertEquals($user1->id, $mua1->userid);
1178         $this->assertEquals($m1id, $mua1->messageid);
1179         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1181         $this->assertEquals($user1->id, $mua2->userid);
1182         $this->assertEquals($m2id, $mua2->messageid);
1183         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1185         $this->assertEquals($user1->id, $mua3->userid);
1186         $this->assertEquals($m3id, $mua3->messageid);
1187         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1189         $this->assertEquals($user1->id, $mua4->userid);
1190         $this->assertEquals($m4id, $mua4->messageid);
1191         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1192     }
1194     /**
1195      * Tests counting unread conversations.
1196      */
1197     public function test_count_unread_conversations() {
1198         $this->resetAfterTest(true);
1200         // Create some users.
1201         $user1 = self::getDataGenerator()->create_user();
1202         $user2 = self::getDataGenerator()->create_user();
1203         $user3 = self::getDataGenerator()->create_user();
1204         $user4 = self::getDataGenerator()->create_user();
1206         // The person wanting the conversation count.
1207         $this->setUser($user1);
1209         // Send some messages back and forth, have some different conversations with different users.
1210         $this->send_fake_message($user1, $user2, 'Yo!');
1211         $this->send_fake_message($user2, $user1, 'Sup mang?');
1212         $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
1213         $this->send_fake_message($user2, $user1, 'Word.');
1215         $this->send_fake_message($user1, $user3, 'Booyah');
1216         $this->send_fake_message($user3, $user1, 'Whaaat?');
1217         $this->send_fake_message($user1, $user3, 'Nothing.');
1218         $this->send_fake_message($user3, $user1, 'Cool.');
1220         $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
1221         $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
1222         $this->send_fake_message($user1, $user4, 'Dope.');
1224         // Check the amount for the current user.
1225         $this->assertEquals(3, core_message\api::count_unread_conversations());
1227         // Check the amount for the second user.
1228         $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
1229     }
1231     /**
1232      * Tests deleting a conversation.
1233      */
1234     public function test_get_all_message_preferences() {
1235         $user = self::getDataGenerator()->create_user();
1236         $this->setUser($user);
1238         // Set a couple of preferences to test.
1239         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
1240         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
1242         $processors = get_message_processors();
1243         $providers = message_get_providers_for_user($user->id);
1244         $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
1246         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
1247         $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
1248     }
1250     /**
1251      * Tests the user can post a message.
1252      */
1253     public function test_can_post_message() {
1254         // Create some users.
1255         $user1 = self::getDataGenerator()->create_user();
1256         $user2 = self::getDataGenerator()->create_user();
1258         // Set as the user 1.
1259         $this->setUser($user1);
1261         // They can post to someone else.
1262         $this->assertTrue(\core_message\api::can_post_message($user2));
1263     }
1265     /**
1266      * Tests the user can't post a message without proper capability.
1267      */
1268     public function test_can_post_message_without_cap() {
1269         global $DB;
1271         // Create some users.
1272         $user1 = self::getDataGenerator()->create_user();
1273         $user2 = self::getDataGenerator()->create_user();
1275         // Set as the user 1.
1276         $this->setUser($user1);
1278         // Remove the capability to send a message.
1279         $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
1280         unassign_capability('moodle/site:sendmessage', $roleids['user'],
1281             context_system::instance());
1283         // Check that we can not post a message without the capability.
1284         $this->assertFalse(\core_message\api::can_post_message($user2));
1285     }
1287     /**
1288      * Tests the user can't post a message if they are not a contact and the user
1289      * has requested messages only from contacts.
1290      */
1291     public function test_can_post_message_when_not_contact() {
1292         // Create some users.
1293         $user1 = self::getDataGenerator()->create_user();
1294         $user2 = self::getDataGenerator()->create_user();
1296         // Set as the first user.
1297         $this->setUser($user1);
1299         // Set the second user's preference to not receive messages from non-contacts.
1300         set_user_preference('message_blocknoncontacts', 1, $user2->id);
1302         // Check that we can not send user 2 a message.
1303         $this->assertFalse(\core_message\api::can_post_message($user2));
1304     }
1306     /**
1307      * Tests the user can't post a message if they are blocked.
1308      */
1309     public function test_can_post_message_when_blocked() {
1310         // Create some users.
1311         $user1 = self::getDataGenerator()->create_user();
1312         $user2 = self::getDataGenerator()->create_user();
1314         // Set the user.
1315         $this->setUser($user1);
1317         // Block the second user.
1318         message_block_contact($user2->id);
1320         // Check that the second user can no longer send the first user a message.
1321         $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
1322     }
1324     /**
1325      * Tests that when blocking messages from non-contacts is enabled that
1326      * non-contacts trying to send a message return false.
1327      */
1328     public function test_is_user_non_contact_blocked() {
1329         // Create some users.
1330         $user1 = self::getDataGenerator()->create_user();
1331         $user2 = self::getDataGenerator()->create_user();
1333         // Set as the first user.
1334         $this->setUser($user1);
1336         // User hasn't sent their preference to block non-contacts, so should return false.
1337         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1339         // Set the second user's preference to not receive messages from non-contacts.
1340         set_user_preference('message_blocknoncontacts', 1, $user2->id);
1342         // Check that the return result is now true.
1343         $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
1345         // Add the first user as a contact for the second user.
1346         message_add_contact($user1->id, 0, $user2->id);
1348         // Check that the return result is now false.
1349         $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
1350     }
1352     /**
1353      * Tests that we return true when a user is blocked, or false
1354      * if they are not blocked.
1355      */
1356     public function test_is_user_blocked() {
1357         // Create some users.
1358         $user1 = self::getDataGenerator()->create_user();
1359         $user2 = self::getDataGenerator()->create_user();
1361         // Set the user.
1362         $this->setUser($user1);
1364         // User shouldn't be blocked.
1365         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1367         // Block the user.
1368         message_block_contact($user2->id);
1370         // User should be blocked.
1371         $this->assertTrue(\core_message\api::is_user_blocked($user1->id, $user2->id));
1373         // Unblock the user.
1374         message_unblock_contact($user2->id);
1375         $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
1376     }
1378     /**
1379      * Tests that the admin is not blocked even if someone has chosen to block them.
1380      */
1381     public function test_is_user_blocked_as_admin() {
1382         // Create a user.
1383         $user1 = self::getDataGenerator()->create_user();
1385         // Set the user.
1386         $this->setUser($user1);
1388         // Block the admin user.
1389         message_block_contact(2);
1391         // Now change to the admin user.
1392         $this->setAdminUser();
1394         // As the admin you should still be able to send messages to the user.
1395         $this->assertFalse(\core_message\api::is_user_blocked($user1->id));
1396     }
1398     /*
1399      * Tes get_message_processor api.
1400      */
1401     public function test_get_message_processor() {
1402         $processors = get_message_processors(true);
1403         if (empty($processors)) {
1404             $this->markTestSkipped("No message processors found");
1405         }
1407         $name = key($processors);
1408         $processor = current($processors);
1409         $testprocessor = \core_message\api::get_message_processor($name);
1410         $this->assertEquals($processor->name, $testprocessor->name);
1411         $this->assertEquals($processor->enabled, $testprocessor->enabled);
1412         $this->assertEquals($processor->available, $testprocessor->available);
1413         $this->assertEquals($processor->configured, $testprocessor->configured);
1415         // Disable processor and test.
1416         \core_message\api::update_processor_status($testprocessor, 0);
1417         $testprocessor = \core_message\api::get_message_processor($name, true);
1418         $this->assertEmpty($testprocessor);
1419         $testprocessor = \core_message\api::get_message_processor($name);
1420         $this->assertEquals($processor->name, $testprocessor->name);
1421         $this->assertEquals(0, $testprocessor->enabled);
1423         // Enable again and test.
1424         \core_message\api::update_processor_status($testprocessor, 1);
1425         $testprocessor = \core_message\api::get_message_processor($name, true);
1426         $this->assertEquals($processor->name, $testprocessor->name);
1427         $this->assertEquals(1, $testprocessor->enabled);
1428         $testprocessor = \core_message\api::get_message_processor($name);
1429         $this->assertEquals($processor->name, $testprocessor->name);
1430         $this->assertEquals(1, $testprocessor->enabled);
1431     }
1433     /**
1434      * Test method update_processor_status.
1435      */
1436     public function test_update_processor_status() {
1437         $processors = get_message_processors();
1438         if (empty($processors)) {
1439             $this->markTestSkipped("No message processors found");
1440         }
1441         $name = key($processors);
1442         $testprocessor = current($processors);
1444         // Enable.
1445         \core_message\api::update_processor_status($testprocessor, 1);
1446         $testprocessor = \core_message\api::get_message_processor($name);
1447         $this->assertEquals(1, $testprocessor->enabled);
1449         // Disable.
1450         \core_message\api::update_processor_status($testprocessor, 0);
1451         $testprocessor = \core_message\api::get_message_processor($name);
1452         $this->assertEquals(0, $testprocessor->enabled);
1454         // Enable again.
1455         \core_message\api::update_processor_status($testprocessor, 1);
1456         $testprocessor = \core_message\api::get_message_processor($name);
1457         $this->assertEquals(1, $testprocessor->enabled);
1458     }
1460     /**
1461      * Test method is_user_enabled.
1462      */
1463     public function is_user_enabled() {
1464         $processors = get_message_processors();
1465         if (empty($processors)) {
1466             $this->markTestSkipped("No message processors found");
1467         }
1468         $name = key($processors);
1469         $testprocessor = current($processors);
1471         // Enable.
1472         \core_message\api::update_processor_status($testprocessor, 1);
1473         $status = \core_message\api::is_processor_enabled($name);
1474         $this->assertEquals(1, $status);
1476         // Disable.
1477         \core_message\api::update_processor_status($testprocessor, 0);
1478         $status = \core_message\api::is_processor_enabled($name);
1479         $this->assertEquals(0, $status);
1481         // Enable again.
1482         \core_message\api::update_processor_status($testprocessor, 1);
1483         $status = \core_message\api::is_processor_enabled($name);
1484         $this->assertEquals(1, $status);
1485     }
1487     /**
1488      * Test retrieving messages by providing a minimum timecreated value.
1489      */
1490     public function test_get_messages_time_from_only() {
1491         // Create some users.
1492         $user1 = self::getDataGenerator()->create_user();
1493         $user2 = self::getDataGenerator()->create_user();
1495         // The person doing the search.
1496         $this->setUser($user1);
1498         // Send some messages back and forth.
1499         $time = 1;
1500         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1501         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1502         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1503         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1505         // Retrieve the messages from $time, which should be all of them.
1506         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time);
1508         // Confirm the message data is correct.
1509         $this->assertEquals(4, count($messages));
1511         $message1 = $messages[0];
1512         $message2 = $messages[1];
1513         $message3 = $messages[2];
1514         $message4 = $messages[3];
1516         $this->assertContains('Message 1', $message1->text);
1517         $this->assertContains('Message 2', $message2->text);
1518         $this->assertContains('Message 3', $message3->text);
1519         $this->assertContains('Message 4', $message4->text);
1521         // Retrieve the messages from $time + 3, which should only be the 2 last messages.
1522         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 3);
1524         // Confirm the message data is correct.
1525         $this->assertEquals(2, count($messages));
1527         $message1 = $messages[0];
1528         $message2 = $messages[1];
1530         $this->assertContains('Message 3', $message1->text);
1531         $this->assertContains('Message 4', $message2->text);
1532     }
1534     /**
1535      * Test retrieving messages by providing a maximum timecreated value.
1536      */
1537     public function test_get_messages_time_to_only() {
1538         // Create some users.
1539         $user1 = self::getDataGenerator()->create_user();
1540         $user2 = self::getDataGenerator()->create_user();
1542         // The person doing the search.
1543         $this->setUser($user1);
1545         // Send some messages back and forth.
1546         $time = 1;
1547         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1548         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1549         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1550         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1552         // Retrieve the messages up until $time + 4, which should be all of them.
1553         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 4);
1555         // Confirm the message data is correct.
1556         $this->assertEquals(4, count($messages));
1558         $message1 = $messages[0];
1559         $message2 = $messages[1];
1560         $message3 = $messages[2];
1561         $message4 = $messages[3];
1563         $this->assertContains('Message 1', $message1->text);
1564         $this->assertContains('Message 2', $message2->text);
1565         $this->assertContains('Message 3', $message3->text);
1566         $this->assertContains('Message 4', $message4->text);
1568         // Retrieve the messages up until $time + 2, which should be the first two.
1569         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', 0, $time + 2);
1571         // Confirm the message data is correct.
1572         $this->assertEquals(2, count($messages));
1574         $message1 = $messages[0];
1575         $message2 = $messages[1];
1577         $this->assertContains('Message 1', $message1->text);
1578         $this->assertContains('Message 2', $message2->text);
1579     }
1581     /**
1582      * Test retrieving messages by providing a minimum and maximum timecreated value.
1583      */
1584     public function test_get_messages_time_from_and_to() {
1585         // Create some users.
1586         $user1 = self::getDataGenerator()->create_user();
1587         $user2 = self::getDataGenerator()->create_user();
1589         // The person doing the search.
1590         $this->setUser($user1);
1592         // Send some messages back and forth.
1593         $time = 1;
1594         $this->send_fake_message($user1, $user2, 'Message 1', 0, $time + 1);
1595         $this->send_fake_message($user2, $user1, 'Message 2', 0, $time + 2);
1596         $this->send_fake_message($user1, $user2, 'Message 3', 0, $time + 3);
1597         $this->send_fake_message($user2, $user1, 'Message 4', 0, $time + 4);
1599         // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
1600         $messages = \core_message\api::get_messages($user1->id, $user2->id, 0, 0, 'timecreated ASC', $time + 2, $time + 3);
1602         // Confirm the message data is correct.
1603         $this->assertEquals(2, count($messages));
1605         $message1 = $messages[0];
1606         $message2 = $messages[1];
1608         $this->assertContains('Message 2', $message1->text);
1609         $this->assertContains('Message 3', $message2->text);
1610     }
1612     /**
1613      * Test returning blocked users.
1614      */
1615     public function test_get_blocked_users() {
1616         global $USER;
1618         // Set this user as the admin.
1619         $this->setAdminUser();
1621         // Create a user to add to the admin's contact list.
1622         $user1 = $this->getDataGenerator()->create_user();
1623         $user2 = $this->getDataGenerator()->create_user();
1625         // Add users to the admin's contact list.
1626         message_add_contact($user1->id);
1627         message_add_contact($user2->id, 1);
1629         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
1631         // Block other user.
1632         message_block_contact($user1->id);
1633         $this->assertCount(2, \core_message\api::get_blocked_users($USER->id));
1635         // Test deleting users.
1636         delete_user($user1);
1637         $this->assertCount(1, \core_message\api::get_blocked_users($USER->id));
1638     }
1640     /**
1641      * Test returning contacts with unread message count.
1642      */
1643     public function test_get_contacts_with_unread_message_count() {
1644         global $DB;
1646         $user1 = self::getDataGenerator()->create_user();
1647         $user2 = self::getDataGenerator()->create_user();
1648         $user3 = self::getDataGenerator()->create_user();
1649         $user4 = self::getDataGenerator()->create_user();
1651         // Add the users to each of their contacts.
1652         message_add_contact($user1->id, 0, $user2->id);
1653         message_add_contact($user2->id, 0, $user1->id);
1654         message_add_contact($user3->id, 0, $user2->id);
1656         $this->send_fake_message($user1, $user2);
1657         $this->send_fake_message($user1, $user2);
1658         $this->send_fake_message($user1, $user2);
1659         $message4id = $this->send_fake_message($user1, $user2);
1661         $this->send_fake_message($user3, $user2);
1662         $message6id = $this->send_fake_message($user3, $user2);
1663         $this->send_fake_message($user3, $user2);
1664         $this->send_fake_message($user3, $user2);
1665         $this->send_fake_message($user3, $user2);
1667         // Send a message that should never be included as the user is not a contact.
1668         $this->send_fake_message($user4, $user2);
1670         // Get the contacts and the unread message count.
1671         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
1673         // Confirm the size is correct.
1674         $this->assertCount(2, $messages);
1675         ksort($messages);
1677         $messageinfo1 = array_shift($messages);
1678         $messageinfo2 = array_shift($messages);
1679         $this->assertEquals($user1->id, $messageinfo1->id);
1680         $this->assertEquals(4, $messageinfo1->messagecount);
1681         $this->assertEquals($user3->id, $messageinfo2->id);
1682         $this->assertEquals(5, $messageinfo2->messagecount);
1684         // Mark some of the messages as read.
1685         $m4 = $DB->get_record('messages', ['id' => $message4id]);
1686         $m6 = $DB->get_record('messages', ['id' => $message6id]);
1687         \core_message\api::mark_message_as_read($user2->id, $m4);
1688         \core_message\api::mark_message_as_read($user2->id, $m6);
1690         // Get the contacts and the unread message count.
1691         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
1693         // Confirm the size is correct.
1694         $this->assertCount(2, $messages);
1695         ksort($messages);
1697         // Confirm read messages are not included.
1698         $messageinfo1 = array_shift($messages);
1699         $messageinfo2 = array_shift($messages);
1700         $this->assertEquals($user1->id, $messageinfo1->id);
1701         $this->assertEquals(3, $messageinfo1->messagecount);
1702         $this->assertEquals($user3->id, $messageinfo2->id);
1703         $this->assertEquals(4, $messageinfo2->messagecount);
1705         // Now, let's populate the database with messages from user2 to user 1.
1706         $this->send_fake_message($user2, $user1);
1707         $this->send_fake_message($user2, $user1);
1708         $messageid = $this->send_fake_message($user2, $user1);
1710         // Send a message that should never be included as the user is not a contact.
1711         $this->send_fake_message($user4, $user1);
1713         // Get the contacts and the unread message count.
1714         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
1716         // Confirm the size is correct.
1717         $this->assertCount(1, $messages);
1718         $messageinfo1 = array_shift($messages);
1719         $this->assertEquals($user2->id, $messageinfo1->id);
1720         $this->assertEquals(3, $messageinfo1->messagecount);
1722         // Mark the last message as read.
1723         $m = $DB->get_record('messages', ['id' => $messageid]);
1724         \core_message\api::mark_message_as_read($user1->id, $m);
1726         $messages = \core_message\api::get_contacts_with_unread_message_count($user1->id);
1728         // Confirm the size is correct.
1729         $this->assertCount(1, $messages);
1731         // Confirm read messages are not included.
1732         $messageinfo1 = array_shift($messages);
1733         $this->assertEquals($user2->id, $messageinfo1->id);
1734         $this->assertEquals(2, $messageinfo1->messagecount);
1735     }
1737     /**
1738      * Test returning contacts with unread message count when there are no messages.
1739      */
1740     public function test_get_contacts_with_unread_message_count_no_messages() {
1741         $user1 = self::getDataGenerator()->create_user();
1742         $user2 = self::getDataGenerator()->create_user();
1744         // Add the users to each of their contacts.
1745         message_add_contact($user1->id, 0, $user2->id);
1747         // Check we get the correct message count.
1748         $messages = \core_message\api::get_contacts_with_unread_message_count($user2->id);
1750         // Confirm the size is correct.
1751         $this->assertCount(1, $messages);
1753         $messageinfo = array_shift($messages);
1755         $this->assertEquals($user1->id, $messageinfo->id);
1756         $this->assertEquals(0, $messageinfo->messagecount);
1757     }
1759     /**
1760      * Test returning non-contacts with unread message count.
1761      */
1762     public function test_get_non_contacts_with_unread_message_count() {
1763         global $DB;
1765         $user1 = self::getDataGenerator()->create_user();
1766         $user2 = self::getDataGenerator()->create_user();
1767         $user3 = self::getDataGenerator()->create_user();
1768         $user4 = self::getDataGenerator()->create_user();
1770         // Add a user to the contact list of the users we are testing this function with.
1771         message_add_contact($user4->id, 0, $user1->id);
1772         message_add_contact($user4->id, 0, $user2->id);
1774         $this->send_fake_message($user1, $user2);
1775         $this->send_fake_message($user1, $user2);
1776         $this->send_fake_message($user1, $user2);
1777         $message4id = $this->send_fake_message($user1, $user2);
1779         $this->send_fake_message($user3, $user2);
1780         $message6id = $this->send_fake_message($user3, $user2);
1781         $this->send_fake_message($user3, $user2);
1782         $this->send_fake_message($user3, $user2);
1783         $this->send_fake_message($user3, $user2);
1785         // Send a message that should never be included as the user is a contact.
1786         $this->send_fake_message($user4, $user2);
1788         // Get the non-contacts and the unread message count.
1789         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
1791         // Check we get the correct message count.
1792         ksort($messages);
1793         $this->assertCount(2, $messages);
1794         $messageinfo1 = array_shift($messages);
1795         $messageinfo2 = array_shift($messages);
1796         $this->assertEquals($user1->id, $messageinfo1->id);
1797         $this->assertEquals(4, $messageinfo1->messagecount);
1798         $this->assertEquals($user3->id, $messageinfo2->id);
1799         $this->assertEquals(5, $messageinfo2->messagecount);
1801         // Mark some of the messages as read.
1802         $m4 = $DB->get_record('messages', ['id' => $message4id]);
1803         $m6 = $DB->get_record('messages', ['id' => $message6id]);
1804         \core_message\api::mark_message_as_read($user2->id, $m4);
1805         \core_message\api::mark_message_as_read($user2->id, $m6);
1807         // Get the non-contacts and the unread message count.
1808         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user2->id);
1810         // Check the marked message is not returned in the message count.
1811         ksort($messages);
1812         $this->assertCount(2, $messages);
1813         $messageinfo1 = array_shift($messages);
1814         $messageinfo2 = array_shift($messages);
1815         $this->assertEquals($user1->id, $messageinfo1->id);
1816         $this->assertEquals(3, $messageinfo1->messagecount);
1817         $this->assertEquals($user3->id, $messageinfo2->id);
1818         $this->assertEquals(4, $messageinfo2->messagecount);
1820         // Now, let's populate the database with messages from user2 to user 1.
1821         $this->send_fake_message($user2, $user1);
1822         $this->send_fake_message($user2, $user1);
1823         $messageid = $this->send_fake_message($user2, $user1);
1825         // Send a message that should never be included as the user is a contact.
1826         $this->send_fake_message($user4, $user1);
1828         // Get the non-contacts and the unread message count.
1829         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
1831         // Confirm the size is correct.
1832         $this->assertCount(1, $messages);
1833         $messageinfo1 = array_shift($messages);
1834         $this->assertEquals($user2->id, $messageinfo1->id);
1835         $this->assertEquals(3, $messageinfo1->messagecount);
1837         // Mark the last message as read.
1838         $m = $DB->get_record('messages', ['id' => $messageid]);
1839         \core_message\api::mark_message_as_read($user1->id, $m);
1841         // Get the non-contacts and the unread message count.
1842         $messages = \core_message\api::get_non_contacts_with_unread_message_count($user1->id);
1844         // Check the marked message is not returned in the message count.
1845         $this->assertCount(1, $messages);
1846         $messageinfo1 = array_shift($messages);
1847         $this->assertEquals($user2->id, $messageinfo1->id);
1848         $this->assertEquals(2, $messageinfo1->messagecount);
1849     }
1851     /**
1852      * Test marking a message as read.
1853      */
1854     public function test_mark_message_as_read() {
1855         global $DB;
1857         $user1 = self::getDataGenerator()->create_user();
1858         $user2 = self::getDataGenerator()->create_user();
1860         $this->send_fake_message($user1, $user2);
1861         $m2id = $this->send_fake_message($user1, $user2);
1862         $this->send_fake_message($user2, $user1);
1863         $m4id = $this->send_fake_message($user2, $user1);
1865         $m2 = $DB->get_record('messages', ['id' => $m2id]);
1866         $m4 = $DB->get_record('messages', ['id' => $m4id]);
1867         \core_message\api::mark_message_as_read($user2->id, $m2, 11);
1868         \core_message\api::mark_message_as_read($user1->id, $m4, 12);
1870         // Confirm there are two user actions.
1871         $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
1872         $this->assertEquals(2, count($muas));
1874         // Confirm they are correct.
1875         $mua1 = array_shift($muas);
1876         $mua2 = array_shift($muas);
1878         // Confirm first action.
1879         $this->assertEquals($user2->id, $mua1->userid);
1880         $this->assertEquals($m2id, $mua1->messageid);
1881         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua1->action);
1882         $this->assertEquals(11, $mua1->timecreated);
1884         // Confirm second action.
1885         $this->assertEquals($user1->id, $mua2->userid);
1886         $this->assertEquals($m4id, $mua2->messageid);
1887         $this->assertEquals(\core_message\api::MESSAGE_ACTION_READ, $mua2->action);
1888         $this->assertEquals(12, $mua2->timecreated);
1889     }
1891     /**
1892      * Test marking a notification as read.
1893      */
1894     public function test_mark_notification_as_read() {
1895         global $DB;
1897         $user1 = self::getDataGenerator()->create_user();
1898         $user2 = self::getDataGenerator()->create_user();
1900         $this->send_fake_message($user1, $user2, 'Notification 1', 1);
1901         $n2id = $this->send_fake_message($user1, $user2, 'Notification 2', 1);
1902         $this->send_fake_message($user2, $user1, 'Notification 3', 1);
1903         $n4id = $this->send_fake_message($user2, $user1, 'Notification 4', 1);
1905         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
1906         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
1908         \core_message\api::mark_notification_as_read($n2, 11);
1909         \core_message\api::mark_notification_as_read($n4, 12);
1911         // Retrieve the notifications.
1912         $n2 = $DB->get_record('notifications', ['id' => $n2id]);
1913         $n4 = $DB->get_record('notifications', ['id' => $n4id]);
1915         // Confirm they have been marked as read.
1916         $this->assertEquals(11, $n2->timeread);
1917         $this->assertEquals(12, $n4->timeread);
1918     }
1920     /**
1921      * Test a conversation is not returned if there is none.
1922      */
1923     public function test_get_conversation_between_users_no_conversation() {
1924         $user1 = self::getDataGenerator()->create_user();
1925         $user2 = self::getDataGenerator()->create_user();
1927         $this->assertFalse(\core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
1928     }
1930     /**
1931      * Test we can return a conversation that exists between users.
1932      */
1933     public function test_get_conversation_between_users_with_existing_conversation() {
1934         $user1 = self::getDataGenerator()->create_user();
1935         $user2 = self::getDataGenerator()->create_user();
1937         $conversationid = \core_message\api::create_conversation_between_users([$user1->id, $user2->id]);
1939         $this->assertEquals($conversationid,
1940             \core_message\api::get_conversation_between_users([$user1->id, $user2->id]));
1941     }