MDL-54708 message: notification popover respects message preferences
[moodle.git] / message / tests / messagelib_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 api's in message lib.
19  *
20  * @package core_message
21  * @category test
22  * @copyright 2014 Rajesh Taneja <rajesh@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;
29 require_once($CFG->dirroot . '/message/lib.php');
31 /**
32  * Test api's in message lib.
33  *
34  * @package core_message
35  * @category test
36  * @copyright 2014 Rajesh Taneja <rajesh@moodle.com>
37  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38  */
39 class core_message_messagelib_testcase extends advanced_testcase {
41     /** @var phpunit_message_sink keep track of messages. */
42     protected $messagesink = null;
44     /**
45      * Test set up.
46      *
47      * This is executed before running any test in this file.
48      */
49     public function setUp() {
50         $this->preventResetByRollback(); // Messaging is not compatible with transactions.
51         $this->messagesink = $this->redirectMessages();
52         $this->resetAfterTest();
53     }
55     /**
56      * Send a fake message.
57      *
58      * {@link message_send()} does not support transaction, this function will simulate a message
59      * sent from a user to another. We should stop using it once {@link message_send()} will support
60      * transactions. This is not clean at all, this is just used to add rows to the table.
61      *
62      * @param stdClass $userfrom user object of the one sending the message.
63      * @param stdClass $userto user object of the one receiving the message.
64      * @param string $message message to send.
65      * @return int the id of the message
66      */
67     protected function send_fake_message($userfrom, $userto, $message = 'Hello world!') {
68         global $DB;
70         $record = new stdClass();
71         $record->useridfrom = $userfrom->id;
72         $record->useridto = $userto->id;
73         $record->subject = 'No subject';
74         $record->fullmessage = $message;
75         $record->smallmessage = $message;
76         $record->timecreated = time();
78         return $DB->insert_record('message', $record);
79     }
81     /**
82      * Send a fake unread popup notification.
83      *
84      * {@link message_send()} does not support transaction, this function will simulate a message
85      * sent from a user to another. We should stop using it once {@link message_send()} will support
86      * transactions. This is not clean at all, this is just used to add rows to the table.
87      *
88      * @param stdClass $userfrom user object of the one sending the message.
89      * @param stdClass $userto user object of the one receiving the message.
90      * @param string $message message to send.
91      * @param int $timecreated time the message was created.
92      * @return int the id of the message
93      */
94     protected function send_fake_unread_popup_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0) {
95         global $DB;
97         $record = new stdClass();
98         $record->useridfrom = $userfrom->id;
99         $record->useridto = $userto->id;
100         $record->notification = 1;
101         $record->subject = 'No subject';
102         $record->fullmessage = $message;
103         $record->smallmessage = $message;
104         $record->timecreated = $timecreated ? $timecreated : time();
106         $id = $DB->insert_record('message', $record);
108         $popup = new stdClass();
109         $popup->messageid = $id;
110         $popup->isread = 0;
112         $DB->insert_record('message_popup', $popup);
114         return $id;
115     }
117     /**
118      * Send a fake read popup notification.
119      *
120      * {@link message_send()} does not support transaction, this function will simulate a message
121      * sent from a user to another. We should stop using it once {@link message_send()} will support
122      * transactions. This is not clean at all, this is just used to add rows to the table.
123      *
124      * @param stdClass $userfrom user object of the one sending the message.
125      * @param stdClass $userto user object of the one receiving the message.
126      * @param string $message message to send.
127      * @param int $timecreated time the message was created.
128      * @return int the id of the message
129      */
130     protected function send_fake_read_popup_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0, $timeread = 0) {
131         global $DB;
133         $record = new stdClass();
134         $record->useridfrom = $userfrom->id;
135         $record->useridto = $userto->id;
136         $record->notification = 1;
137         $record->subject = 'No subject';
138         $record->fullmessage = $message;
139         $record->smallmessage = $message;
140         $record->timecreated = $timecreated ? $timecreated : time();
141         $record->timeread = $timeread ? $timeread : time();
143         $id = $DB->insert_record('message_read', $record);
145         $popup = new stdClass();
146         $popup->messageid = $id;
147         $popup->isread = 1;
149         $DB->insert_record('message_popup', $popup);
151         return $id;
152     }
154     /**
155      * Test message_get_blocked_users.
156      */
157     public function test_message_get_blocked_users() {
158         // Set this user as the admin.
159         $this->setAdminUser();
161         // Create a user to add to the admin's contact list.
162         $user1 = $this->getDataGenerator()->create_user();
163         $user2 = $this->getDataGenerator()->create_user();
165         // Add users to the admin's contact list.
166         message_add_contact($user1->id);
167         message_add_contact($user2->id, 1);
169         $this->assertCount(1, message_get_blocked_users());
171         // Block other user.
172         message_block_contact($user1->id);
173         $this->assertCount(2, message_get_blocked_users());
175         // Test deleting users.
176         delete_user($user1);
177         $this->assertCount(1, message_get_blocked_users());
178     }
180     /**
181      * Test message_get_contacts.
182      */
183     public function test_message_get_contacts() {
184         global $USER, $CFG;
186         // Set this user as the admin.
187         $this->setAdminUser();
189         $noreplyuser = core_user::get_noreply_user();
190         $supportuser = core_user::get_support_user();
192         // Create a user to add to the admin's contact list.
193         $user1 = $this->getDataGenerator()->create_user();
194         $user2 = $this->getDataGenerator()->create_user();
195         $user3 = $this->getDataGenerator()->create_user(); // Stranger.
197         // Add users to the admin's contact list.
198         message_add_contact($user1->id);
199         message_add_contact($user2->id);
201         // Send some messages.
202         $this->send_fake_message($user1, $USER);
203         $this->send_fake_message($user2, $USER);
204         $this->send_fake_message($user3, $USER);
206         list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
207         $this->assertCount(0, $onlinecontacts);
208         $this->assertCount(2, $offlinecontacts);
209         $this->assertCount(1, $strangers);
211         // Send message from noreply and support users.
212         $this->send_fake_message($noreplyuser, $USER);
213         $this->send_fake_message($supportuser, $USER);
214         list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
215         $this->assertCount(0, $onlinecontacts);
216         $this->assertCount(2, $offlinecontacts);
217         $this->assertCount(3, $strangers);
219         // Block 1 user.
220         message_block_contact($user2->id);
221         list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
222         $this->assertCount(0, $onlinecontacts);
223         $this->assertCount(1, $offlinecontacts);
224         $this->assertCount(3, $strangers);
226         // Noreply user being valid user.
227         core_user::reset_internal_users();
228         $CFG->noreplyuserid = $user3->id;
229         $noreplyuser = core_user::get_noreply_user();
230         list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
231         $this->assertCount(0, $onlinecontacts);
232         $this->assertCount(1, $offlinecontacts);
233         $this->assertCount(2, $strangers);
235         // Test deleting users.
236         delete_user($user1);
237         delete_user($user3);
239         list($onlinecontacts, $offlinecontacts, $strangers) = message_get_contacts();
240         $this->assertCount(0, $onlinecontacts);
241         $this->assertCount(0, $offlinecontacts);
242         $this->assertCount(1, $strangers);
243     }
245     /**
246      * Test message_count_messages.
247      */
248     public function test_message_count_messages() {
249         global $DB;
251         // Create users to send and receive message.
252         $userfrom = $this->getDataGenerator()->create_user();
253         $userto = $this->getDataGenerator()->create_user();
255         message_post_message($userfrom, $userto, 'Message 1', FORMAT_PLAIN);
256         message_post_message($userfrom, $userto, 'Message 2', FORMAT_PLAIN);
257         message_post_message($userto, $userfrom, 'Message 3', FORMAT_PLAIN);
259         // Return 0 when no message.
260         $messages = array();
261         $this->assertEquals(0, message_count_messages($messages, 'Test', 'Test'));
263         // Check number of messages from userfrom and userto.
264         $messages = $this->messagesink->get_messages();
265         $this->assertEquals(2, message_count_messages($messages, 'useridfrom', $userfrom->id));
266         $this->assertEquals(1, message_count_messages($messages, 'useridfrom', $userto->id));
267     }
269     /**
270      * Test message_count_unread_messages.
271      */
272     public function test_message_count_unread_messages() {
273         // Create users to send and receive message.
274         $userfrom1 = $this->getDataGenerator()->create_user();
275         $userfrom2 = $this->getDataGenerator()->create_user();
276         $userto = $this->getDataGenerator()->create_user();
278         $this->assertEquals(0, message_count_unread_messages($userto));
280         // Send fake messages.
281         $this->send_fake_message($userfrom1, $userto);
282         $this->send_fake_message($userfrom2, $userto);
284         $this->assertEquals(2, message_count_unread_messages($userto));
285         $this->assertEquals(1, message_count_unread_messages($userto, $userfrom1));
286     }
288     /**
289      * Test message_count_blocked_users.
290      *
291      */
292     public function test_message_count_blocked_users() {
293         // Set this user as the admin.
294         $this->setAdminUser();
296         // Create users to add to the admin's contact list.
297         $user1 = $this->getDataGenerator()->create_user();
298         $user2 = $this->getDataGenerator()->create_user();
300         $this->assertEquals(0, message_count_blocked_users());
302         // Add 1 blocked and 1 normal contact to admin's contact list.
303         message_add_contact($user1->id);
304         message_add_contact($user2->id, 1);
306         $this->assertEquals(0, message_count_blocked_users($user2));
307         $this->assertEquals(1, message_count_blocked_users());
308     }
310     /**
311      * Test message_add_contact.
312      */
313     public function test_message_add_contact() {
314         // Set this user as the admin.
315         $this->setAdminUser();
317         // Create a user to add to the admin's contact list.
318         $user1 = $this->getDataGenerator()->create_user();
319         $user2 = $this->getDataGenerator()->create_user();
320         $user3 = $this->getDataGenerator()->create_user();
322         message_add_contact($user1->id);
323         message_add_contact($user2->id, 0);
324         // Add duplicate contact and make sure only 1 record exists.
325         message_add_contact($user2->id, 1);
327         $this->assertNotEmpty(message_get_contact($user1->id));
328         $this->assertNotEmpty(message_get_contact($user2->id));
329         $this->assertEquals(false, message_get_contact($user3->id));
330         $this->assertEquals(1, message_count_blocked_users());
331     }
333     /**
334      * Test message_remove_contact.
335      */
336     public function test_message_remove_contact() {
337         // Set this user as the admin.
338         $this->setAdminUser();
340         // Create a user to add to the admin's contact list.
341         $user = $this->getDataGenerator()->create_user();
343         // Add the user to the admin's contact list.
344         message_add_contact($user->id);
345         $this->assertNotEmpty(message_get_contact($user->id));
347         // Remove user from admin's contact list.
348         message_remove_contact($user->id);
349         $this->assertEquals(false, message_get_contact($user->id));
350     }
352     /**
353      * Test message_block_contact.
354      */
355     public function test_message_block_contact() {
356         // Set this user as the admin.
357         $this->setAdminUser();
359         // Create a user to add to the admin's contact list.
360         $user1 = $this->getDataGenerator()->create_user();
361         $user2 = $this->getDataGenerator()->create_user();
363         // Add users to the admin's contact list.
364         message_add_contact($user1->id);
365         message_add_contact($user2->id);
367         $this->assertEquals(0, message_count_blocked_users());
369         // Block 1 user.
370         message_block_contact($user2->id);
371         $this->assertEquals(1, message_count_blocked_users());
373     }
375     /**
376      * Test message_unblock_contact.
377      */
378     public function test_message_unblock_contact() {
379         // Set this user as the admin.
380         $this->setAdminUser();
382         // Create a user to add to the admin's contact list.
383         $user1 = $this->getDataGenerator()->create_user();
384         $user2 = $this->getDataGenerator()->create_user();
386         // Add users to the admin's contact list.
387         message_add_contact($user1->id);
388         message_add_contact($user2->id, 1); // Add blocked contact.
390         $this->assertEquals(1, message_count_blocked_users());
392         // Unblock user.
393         message_unblock_contact($user2->id);
394         $this->assertEquals(0, message_count_blocked_users());
395     }
397     /**
398      * Test message_search_users.
399      */
400     public function test_message_search_users() {
401         // Set this user as the admin.
402         $this->setAdminUser();
404         // Create a user to add to the admin's contact list.
405         $user1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'user1'));
406         $user2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'user2'));
408         // Add users to the admin's contact list.
409         message_add_contact($user1->id);
410         message_add_contact($user2->id); // Add blocked contact.
412         $this->assertCount(1, message_search_users(0, 'Test1'));
413         $this->assertCount(2, message_search_users(0, 'Test'));
414         $this->assertCount(1, message_search_users(0, 'user1'));
415         $this->assertCount(2, message_search_users(0, 'user'));
416     }
418     /**
419      * Test message_search.
420      */
421     public function test_message_search() {
422         global $USER;
424         // Set this user as the admin.
425         $this->setAdminUser();
427         // Create a user to add to the admin's contact list.
428         $user1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'user1'));
429         $user2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'user2'));
431         // Send few messages, real (read).
432         message_post_message($user1, $USER, 'Message 1', FORMAT_PLAIN);
433         message_post_message($USER, $user1, 'Message 2', FORMAT_PLAIN);
434         message_post_message($USER, $user2, 'Message 3', FORMAT_PLAIN);
436         $this->assertCount(2, message_search(array('Message'), true, false));
437         $this->assertCount(3, message_search(array('Message'), true, true));
439         // Send fake message (not-read).
440         $this->send_fake_message($USER, $user1, 'Message 4');
441         $this->send_fake_message($user1, $USER, 'Message 5');
442         $this->assertCount(3, message_search(array('Message'), true, false));
443         $this->assertCount(5, message_search(array('Message'), true, true));
445         // If courseid given then should be 0.
446         $this->assertEquals(false, message_search(array('Message'), true, true, ''));
447         $this->assertEquals(false, message_search(array('Message'), true, true, 2));
448         $this->assertCount(5, message_search(array('Message'), true, true, SITEID));
449     }
451     /**
452      * The data provider for message_get_recent_conversations.
453      *
454      * This provides sets of data to for testing.
455      * @return array
456      */
457     public function message_get_recent_conversations_provider() {
458         return array(
459             'Test that conversations with messages contacts is correctly ordered.' => array(
460                 'users' => array(
461                     'user1',
462                     'user2',
463                     'user3',
464                 ),
465                 'contacts' => array(
466                 ),
467                 'messages' => array(
468                     array(
469                         'from'          => 'user1',
470                         'to'            => 'user2',
471                         'state'         => 'unread',
472                         'subject'       => 'S1',
473                     ),
474                     array(
475                         'from'          => 'user2',
476                         'to'            => 'user1',
477                         'state'         => 'unread',
478                         'subject'       => 'S2',
479                     ),
480                     array(
481                         'from'          => 'user1',
482                         'to'            => 'user2',
483                         'state'         => 'unread',
484                         'timecreated'   => 0,
485                         'subject'       => 'S3',
486                     ),
487                     array(
488                         'from'          => 'user1',
489                         'to'            => 'user3',
490                         'state'         => 'read',
491                         'timemodifier'  => 1,
492                         'subject'       => 'S4',
493                     ),
494                     array(
495                         'from'          => 'user3',
496                         'to'            => 'user1',
497                         'state'         => 'read',
498                         'timemodifier'  => 1,
499                         'subject'       => 'S5',
500                     ),
501                     array(
502                         'from'          => 'user1',
503                         'to'            => 'user3',
504                         'state'         => 'read',
505                         'timecreated'   => 0,
506                         'subject'       => 'S6',
507                     ),
508                 ),
509                 'expectations' => array(
510                     'user1' => array(
511                         // User1 has conversed most recently with user3. The most recent message is M5.
512                         array(
513                             'messageposition'   => 0,
514                             'with'              => 'user3',
515                             'subject'           => 'S5',
516                         ),
517                         // User1 has also conversed with user2. The most recent message is S2.
518                         array(
519                             'messageposition'   => 1,
520                             'with'              => 'user2',
521                             'subject'           => 'S2',
522                         ),
523                     ),
524                     'user2' => array(
525                         // User2 has only conversed with user1. Their most recent shared message was S2.
526                         array(
527                             'messageposition'   => 0,
528                             'with'              => 'user1',
529                             'subject'           => 'S2',
530                         ),
531                     ),
532                     'user3' => array(
533                         // User3 has only conversed with user1. Their most recent shared message was S5.
534                         array(
535                             'messageposition'   => 0,
536                             'with'              => 'user1',
537                             'subject'           => 'S5',
538                         ),
539                     ),
540                 ),
541             ),
542             'Test that users with contacts and messages to self work as expected' => array(
543                 'users' => array(
544                     'user1',
545                     'user2',
546                     'user3',
547                 ),
548                 'contacts' => array(
549                     'user1' => array(
550                         'user2' => 0,
551                         'user3' => 0,
552                     ),
553                     'user2' => array(
554                         'user3' => 0,
555                     ),
556                 ),
557                 'messages' => array(
558                     array(
559                         'from'          => 'user1',
560                         'to'            => 'user1',
561                         'state'         => 'unread',
562                         'subject'       => 'S1',
563                     ),
564                     array(
565                         'from'          => 'user1',
566                         'to'            => 'user1',
567                         'state'         => 'unread',
568                         'subject'       => 'S2',
569                     ),
570                 ),
571                 'expectations' => array(
572                     'user1' => array(
573                         // User1 has conversed most recently with user1. The most recent message is S2.
574                         array(
575                             'messageposition'   => 0,
576                             'with'              => 'user1',
577                             'subject'           => 'S2',
578                         ),
579                     ),
580                 ),
581             ),
582             'Test conversations with a single user, where some messages are read and some are not.' => array(
583                 'users' => array(
584                     'user1',
585                     'user2',
586                 ),
587                 'contacts' => array(
588                 ),
589                 'messages' => array(
590                     array(
591                         'from'          => 'user1',
592                         'to'            => 'user2',
593                         'state'         => 'read',
594                         'subject'       => 'S1',
595                     ),
596                     array(
597                         'from'          => 'user2',
598                         'to'            => 'user1',
599                         'state'         => 'read',
600                         'subject'       => 'S2',
601                     ),
602                     array(
603                         'from'          => 'user1',
604                         'to'            => 'user2',
605                         'state'         => 'unread',
606                         'timemodifier'  => 1,
607                         'subject'       => 'S3',
608                     ),
609                     array(
610                         'from'          => 'user1',
611                         'to'            => 'user2',
612                         'state'         => 'unread',
613                         'timemodifier'  => 1,
614                         'subject'       => 'S4',
615                     ),
616                 ),
617                 'expectations' => array(
618                     // The most recent message between user1 and user2 was S4.
619                     'user1' => array(
620                         array(
621                             'messageposition'   => 0,
622                             'with'              => 'user2',
623                             'subject'           => 'S4',
624                         ),
625                     ),
626                     'user2' => array(
627                         // The most recent message between user1 and user2 was S4.
628                         array(
629                             'messageposition'   => 0,
630                             'with'              => 'user1',
631                             'subject'           => 'S4',
632                         ),
633                     ),
634                 ),
635             ),
636             'Test conversations with a single user, where some messages are read and some are not, and messages ' .
637             'are out of order' => array(
638             // This can happen through a combination of factors including multi-master DB replication with messages
639             // read somehow (e.g. API).
640                 'users' => array(
641                     'user1',
642                     'user2',
643                 ),
644                 'contacts' => array(
645                 ),
646                 'messages' => array(
647                     array(
648                         'from'          => 'user1',
649                         'to'            => 'user2',
650                         'state'         => 'read',
651                         'subject'       => 'S1',
652                         'timemodifier'  => 1,
653                     ),
654                     array(
655                         'from'          => 'user2',
656                         'to'            => 'user1',
657                         'state'         => 'read',
658                         'subject'       => 'S2',
659                         'timemodifier'  => 2,
660                     ),
661                     array(
662                         'from'          => 'user1',
663                         'to'            => 'user2',
664                         'state'         => 'unread',
665                         'subject'       => 'S3',
666                     ),
667                     array(
668                         'from'          => 'user1',
669                         'to'            => 'user2',
670                         'state'         => 'unread',
671                         'subject'       => 'S4',
672                     ),
673                 ),
674                 'expectations' => array(
675                     // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
676                     'user1' => array(
677                         array(
678                             'messageposition'   => 0,
679                             'with'              => 'user2',
680                             'subject'           => 'S2',
681                         ),
682                     ),
683                     'user2' => array(
684                         array(
685                             'messageposition'   => 0,
686                             'with'              => 'user1',
687                             'subject'           => 'S2',
688                         ),
689                     ),
690                 ),
691             ),
692         );
693     }
695     /**
696      * Test message_get_recent_conversations with a mixture of messages.
697      *
698      * @dataProvider message_get_recent_conversations_provider
699      * @param array $usersdata The list of users to create for this test.
700      * @param array $messagesdata The list of messages to create.
701      * @param array $expectations The list of expected outcomes.
702      */
703     public function test_message_get_recent_conversations($usersdata, $contacts, $messagesdata, $expectations) {
704         global $DB;
706         // Create all of the users.
707         $users = array();
708         foreach ($usersdata as $username) {
709             $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
710         }
712         foreach ($contacts as $username => $contact) {
713             foreach ($contact as $contactname => $blocked) {
714                 $record = new stdClass();
715                 $record->userid     = $users[$username]->id;
716                 $record->contactid  = $users[$contactname]->id;
717                 $record->blocked    = $blocked;
718                 $record->id = $DB->insert_record('message_contacts', $record);
719             }
720         }
722         $defaulttimecreated = time();
723         foreach ($messagesdata as $messagedata) {
724             $from       = $users[$messagedata['from']];
725             $to         = $users[$messagedata['to']];
726             $subject    = $messagedata['subject'];
728             if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
729                 $table = 'message';
730                 $messageid = $this->send_fake_message($from, $to, $subject, FORMAT_PLAIN);
731             } else {
732                 // If there is no state, or the state is not 'unread', assume the message is read.
733                 $table = 'message_read';
734                 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
735             }
737             $updatemessage = new stdClass();
738             $updatemessage->id = $messageid;
739             if (isset($messagedata['timecreated'])) {
740                 $updatemessage->timecreated = $messagedata['timecreated'];
741             } else if (isset($messagedata['timemodifier'])) {
742                 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
743             } else {
744                 $updatemessage->timecreated = $defaulttimecreated;
745             }
746             $DB->update_record($table, $updatemessage);
747         }
749         foreach ($expectations as $username => $data) {
750             // Get the recent conversations for the specified user.
751             $user = $users[$username];
752             $conversations = message_get_recent_conversations($user);
753             foreach ($data as $expectation) {
754                 $otheruser = $users[$expectation['with']];
755                 $conversation = $conversations[$expectation['messageposition']];
756                 $this->assertEquals($otheruser->id, $conversation->id);
757                 $this->assertEquals($expectation['subject'], $conversation->smallmessage);
758             }
759         }
760     }
762     /**
763      * Test message_get_recent_notifications.
764      */
765     public function test_message_get_recent_notifications() {
766         global $DB, $USER;
768         // Set this user as the admin.
769         $this->setAdminUser();
771         // Create a user to send messages from.
772         $user1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'user1'));
774         // Add two messages - will mark them as notifications later.
775         $m1 = message_post_message($user1, $USER, 'Message 1', FORMAT_PLAIN);
776         $m2 = message_post_message($user1, $USER, 'Message 2', FORMAT_PLAIN);
778         // Mark the second message as a notification.
779         $updatemessage = new stdClass();
780         $updatemessage->id = $m2;
781         $updatemessage->notification = 1;
782         $DB->update_record('message_read', $updatemessage);
784         // Mark the first message as a notification and change the timecreated to 0.
785         $updatemessage->id = $m1;
786         $updatemessage->notification = 1;
787         $updatemessage->timecreated = 0;
788         $DB->update_record('message_read', $updatemessage);
790         $notifications = message_get_recent_notifications($USER);
792         // Get the messages.
793         $firstmessage = array_shift($notifications);
794         $secondmessage = array_shift($notifications);
796         // Confirm that we have received the notifications with the maximum timecreated, rather than the max id.
797         $this->assertEquals('Message 2', $firstmessage->smallmessage);
798         $this->assertEquals('Message 1', $secondmessage->smallmessage);
799     }
801     /**
802      * Test that message_can_post_message returns false if the sender does not have the
803      * moode/site:sendmessage capability.
804      */
805     public function test_message_can_post_message_returns_false_without_capability() {
806         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
807         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
808         $context = context_system::instance();
809         $roleid = $this->getDataGenerator()->create_role();
810         $this->getDataGenerator()->role_assign($roleid, $sender->id, $context->id);
812         assign_capability('moodle/site:sendmessage', CAP_PROHIBIT, $roleid, $context);
814         $this->assertFalse(message_can_post_message($recipient, $sender));
815     }
817     /**
818      * Test that message_can_post_message returns false if the receiver only accepts
819      * messages from contacts and the sender isn't a contact.
820      */
821     public function test_message_can_post_message_returns_false_non_contact_blocked() {
822         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
823         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
825         set_user_preference('message_blocknoncontacts', true, $recipient);
827         $this->assertFalse(message_can_post_message($recipient, $sender));
828     }
830     /**
831      * Test that message_can_post_message returns false if the receiver has blocked the
832      * sender from messaging them.
833      */
834     public function test_message_can_post_message_returns_false_if_blocked() {
835         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
836         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
838         $this->setUser($recipient);
839         message_block_contact($sender->id);
841         $this->assertFalse(message_can_post_message($recipient, $sender));
842     }
844     /**
845      * Test that message_can_post_message returns false if the receiver has blocked the
846      * sender from messaging them.
847      */
848     public function test_message_can_post_message_returns_true() {
849         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
850         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
852         $this->assertTrue(message_can_post_message($recipient, $sender));
853     }
855     /**
856      * Test that message_is_user_non_contact_blocked returns false if the recipient allows
857      * messages from non-contacts.
858      */
859     public function test_message_is_user_non_contact_blocked_false_without_preference() {
860         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
861         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
863         set_user_preference('message_blocknoncontacts', false, $recipient);
865         $this->assertFalse(message_is_user_non_contact_blocked($recipient, $sender));
866     }
868     /**
869      * Test that message_is_user_non_contact_blocked returns true if the recipient doesn't
870      * allow messages from non-contacts and the sender isn't a contact.
871      */
872     public function test_message_is_user_non_contact_blocked_true_with_preference() {
873         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
874         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
876         set_user_preference('message_blocknoncontacts', true, $recipient);
878         $this->assertTrue(message_is_user_non_contact_blocked($recipient, $sender));
879     }
881     /**
882      * Test that message_is_user_non_contact_blocked returns false if the recipient doesn't
883      * allow messages from non-contacts but the sender is a contact.
884      */
885     public function test_message_is_user_non_contact_blocked_false_with_if_contact() {
886         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
887         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
889         $this->setUser($recipient);
890         set_user_preference('message_blocknoncontacts', true, $recipient);
891         message_add_contact($sender->id);
893         $this->assertFalse(message_is_user_non_contact_blocked($recipient, $sender));
894     }
896     /**
897      * Test that message_is_user_blocked returns false if the sender is not a contact of
898      * the recipient.
899      */
900     public function test_message_is_user_blocked_false_no_contact() {
901         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
902         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
904         $this->assertFalse(message_is_user_blocked($recipient, $sender));
905     }
907     /**
908      * Test that message_is_user_blocked returns false if the sender is a contact that is
909      * blocked by the recipient but has the moodle/site:readallmessages capability.
910      */
911     public function test_message_is_user_blocked_false_if_readallmessages() {
912         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
913         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
915         $this->setUser($recipient);
916         message_block_contact($sender->id);
918         $context = context_system::instance();
919         $roleid = $this->getDataGenerator()->create_role();
920         $this->getDataGenerator()->role_assign($roleid, $sender->id, $context->id);
922         assign_capability('moodle/site:readallmessages', CAP_ALLOW, $roleid, $context);
924         $this->assertFalse(message_is_user_blocked($recipient, $sender));
925     }
927     /**
928      * Test that message_is_user_blocked returns true if the sender is a contact that is
929      * blocked by the recipient and does not have the moodle/site:readallmessages capability.
930      */
931     public function test_message_is_user_blocked_true_if_blocked() {
932         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
933         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
935         $this->setUser($recipient);
936         message_block_contact($sender->id);
938         $context = context_system::instance();
939         $roleid = $this->getDataGenerator()->create_role();
940         $this->getDataGenerator()->role_assign($roleid, $sender->id, $context->id);
942         assign_capability('moodle/site:readallmessages', CAP_PROHIBIT, $roleid, $context);
944         $this->assertTrue(message_is_user_blocked($recipient, $sender));
945     }
947     /**
948      * Test that the message_get_popup_notifications function will return only read notifications if requested.
949      */
950     public function test_message_get_popup_notifications_read_only() {
951         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
952         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
954         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 2);
955         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 2', 4);
957         $notifications = message_get_popup_notifications($recipient->id, MESSAGE_READ);
959         $this->assertEquals($notifications[0]->fullmessage, 'Message 2');
960         $this->assertEquals($notifications[1]->fullmessage, 'Message 1');
962         // Check if we request read and unread but there are only read messages, it should
963         // still return those correctly.
964         $notifications = message_get_popup_notifications($recipient->id, '');
966         $this->assertEquals($notifications[0]->fullmessage, 'Message 2');
967         $this->assertEquals($notifications[1]->fullmessage, 'Message 1');
968     }
970     /**
971      * Test that the message_get_popup_notifications function will return only unread notifications if requested.
972      */
973     public function test_message_get_popup_notifications_unread_only() {
974         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
975         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
977         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 1', 2);
978         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 4);
980         $notifications = message_get_popup_notifications($recipient->id, MESSAGE_UNREAD);
982         $this->assertEquals($notifications[0]->fullmessage, 'Message 2');
983         $this->assertEquals($notifications[1]->fullmessage, 'Message 1');
985         // Check if we request read and unread but there are only read messages, it should
986         // still return those correctly.
987         $notifications = message_get_popup_notifications($recipient->id, '');
989         $this->assertEquals($notifications[0]->fullmessage, 'Message 2');
990         $this->assertEquals($notifications[1]->fullmessage, 'Message 1');
991     }
993     /**
994      * Test that the message_get_popup_notifications function will return the correct notifications when both
995      * read and unread notifications are included.
996      */
997     public function test_message_get_popup_notifications_mixed() {
998         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
999         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1001         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 1);
1002         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 2);
1003         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 3', 3, 1);
1004         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 4', 3, 2);
1005         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 5', 4);
1007         $notifications = message_get_popup_notifications($recipient->id);
1009         $this->assertEquals($notifications[0]->fullmessage, 'Message 5');
1010         $this->assertEquals($notifications[1]->fullmessage, 'Message 4');
1011         $this->assertEquals($notifications[2]->fullmessage, 'Message 3');
1012         $this->assertEquals($notifications[3]->fullmessage, 'Message 2');
1013         $this->assertEquals($notifications[4]->fullmessage, 'Message 1');
1015         $notifications = message_get_popup_notifications($recipient->id, MESSAGE_READ);
1017         $this->assertEquals($notifications[0]->fullmessage, 'Message 4');
1018         $this->assertEquals($notifications[1]->fullmessage, 'Message 3');
1019         $this->assertEquals($notifications[2]->fullmessage, 'Message 1');
1021         $notifications = message_get_popup_notifications($recipient->id, MESSAGE_UNREAD);
1023         $this->assertEquals($notifications[0]->fullmessage, 'Message 5');
1024         $this->assertEquals($notifications[1]->fullmessage, 'Message 2');
1025     }
1027     /**
1028      * Test that the message_get_popup_notifications function works correctly with limiting and offsetting
1029      * the result set if requested.
1030      */
1031     public function test_message_get_popup_notifications_all_with_limit_and_offset() {
1032         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1033         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1035         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 1);
1036         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 2);
1037         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 3', 3, 1);
1038         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 4', 3, 2);
1039         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 5', 4);
1040         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 6', 5);
1042         $notifications = message_get_popup_notifications($recipient->id, '', false, false, 'DESC', 2, 0);
1044         $this->assertEquals($notifications[0]->fullmessage, 'Message 6');
1045         $this->assertEquals($notifications[1]->fullmessage, 'Message 5');
1047         $notifications = message_get_popup_notifications($recipient->id, '', false, false, 'DESC', 2, 2);
1049         $this->assertEquals($notifications[0]->fullmessage, 'Message 4');
1050         $this->assertEquals($notifications[1]->fullmessage, 'Message 3');
1052         $notifications = message_get_popup_notifications($recipient->id, '', false, false, 'DESC', 0, 3);
1054         $this->assertEquals($notifications[0]->fullmessage, 'Message 3');
1055         $this->assertEquals($notifications[1]->fullmessage, 'Message 2');
1056         $this->assertEquals($notifications[2]->fullmessage, 'Message 1');
1057     }
1059     /**
1060      * Test that the message_get_popup_notifications function returns embedded user details for the
1061      * sender if requested.
1062      */
1063     public function test_message_get_popup_notifications_embed_sender() {
1064         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1065         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1067         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 1);
1068         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 2);
1070         $notifications = message_get_popup_notifications($recipient->id, '', false, true, 'DESC');
1072         $func = function($type) {
1073             return function($notification) use ($type) {
1074                 $user = new stdClass();
1075                 $user = username_load_fields_from_object($user, $notification, $type);
1076                 return $user;
1077             };
1078         };
1079         $senders = array_map($func('userfrom'), $notifications);
1080         $recipients = array_map($func('userto'), $notifications);
1082         $this->assertEquals($senders[0]->firstname, 'Test1');
1083         $this->assertEquals($senders[0]->lastname, 'User1');
1084         $this->assertEquals($senders[1]->firstname, 'Test1');
1085         $this->assertEquals($senders[1]->lastname, 'User1');
1087         // Make sure we didn't get recipient details when they weren't requested.
1088         $this->assertEmpty($recipients[0]->firstname);
1089         $this->assertEmpty($recipients[0]->lastname);
1090         $this->assertEmpty($recipients[1]->firstname);
1091         $this->assertEmpty($recipients[1]->lastname);
1092     }
1094     /**
1095      * Test that the message_get_popup_notifications function returns embedded user details for the
1096      * recipient if requested.
1097      */
1098     public function test_message_get_popup_notifications_embed_recipient() {
1099         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1100         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1102         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 1);
1103         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 2);
1105         $notifications = message_get_popup_notifications($recipient->id, '', true, false, 'DESC');
1107         $func = function($type) {
1108             return function($notification) use ($type) {
1109                 $user = new stdClass();
1110                 $user = username_load_fields_from_object($user, $notification, $type);
1111                 return $user;
1112             };
1113         };
1114         $senders = array_map($func('userfrom'), $notifications);
1115         $recipients = array_map($func('userto'), $notifications);
1117         $this->assertEquals($recipients[0]->firstname, 'Test2');
1118         $this->assertEquals($recipients[0]->lastname, 'User2');
1119         $this->assertEquals($recipients[1]->firstname, 'Test2');
1120         $this->assertEquals($recipients[1]->lastname, 'User2');
1122         // Make sure we didn't get sender details when they weren't requested.
1123         $this->assertEmpty($senders[0]->firstname);
1124         $this->assertEmpty($senders[0]->lastname);
1125         $this->assertEmpty($senders[1]->firstname);
1126         $this->assertEmpty($senders[1]->lastname);
1127     }
1129     /**
1130      * Test that the message_get_popup_notifications function returns embedded all user details.
1131      */
1132     public function test_message_get_popup_notifications_embed_both() {
1133         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1134         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1136         $this->send_fake_read_popup_notification($sender, $recipient, 'Message 1', 1);
1137         $this->send_fake_unread_popup_notification($sender, $recipient, 'Message 2', 2);
1139         $notifications = message_get_popup_notifications($recipient->id, '', true, true, 'DESC');
1141         $func = function($type) {
1142             return function($notification) use ($type) {
1143                 $user = new stdClass();
1144                 $user = username_load_fields_from_object($user, $notification, $type);
1145                 return $user;
1146             };
1147         };
1148         $senders = array_map($func('userfrom'), $notifications);
1149         $recipients = array_map($func('userto'), $notifications);
1151         $this->assertEquals($recipients[0]->firstname, 'Test2');
1152         $this->assertEquals($recipients[0]->lastname, 'User2');
1153         $this->assertEquals($recipients[1]->firstname, 'Test2');
1154         $this->assertEquals($recipients[1]->lastname, 'User2');
1156         // Make sure we didn't get sender details when they weren't requested.
1157         $this->assertEquals($senders[0]->firstname, 'Test1');
1158         $this->assertEquals($senders[0]->lastname, 'User1');
1159         $this->assertEquals($senders[1]->firstname, 'Test1');
1160         $this->assertEquals($senders[1]->lastname, 'User1');
1161     }
1163     /**
1164      * Test message_count_unread_popup_notifications.
1165      */
1166     public function test_message_count_unread_popup_notifications() {
1167         $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1168         $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1169         $recipient1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
1170         $recipient2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test4', 'lastname' => 'User4'));
1172         $this->send_fake_unread_popup_notification($sender1, $recipient1);
1173         $this->send_fake_unread_popup_notification($sender1, $recipient1);
1174         $this->send_fake_unread_popup_notification($sender2, $recipient1);
1175         $this->send_fake_unread_popup_notification($sender1, $recipient2);
1176         $this->send_fake_unread_popup_notification($sender2, $recipient2);
1177         $this->send_fake_unread_popup_notification($sender2, $recipient2);
1178         $this->send_fake_unread_popup_notification($sender2, $recipient2);
1179         $this->send_fake_unread_popup_notification($sender2, $recipient2);
1181         $this->assertEquals(message_count_unread_popup_notifications($recipient1->id), 3);
1182         $this->assertEquals(message_count_unread_popup_notifications($recipient2->id), 5);
1183     }
1186     public function test_message_mark_all_read_for_user_touser() {
1187         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1188         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1190         $this->send_fake_unread_popup_notification($sender, $recipient);
1191         $this->send_fake_unread_popup_notification($sender, $recipient);
1192         $this->send_fake_unread_popup_notification($sender, $recipient);
1193         $this->send_fake_message($sender, $recipient);
1194         $this->send_fake_message($sender, $recipient);
1195         $this->send_fake_message($sender, $recipient);
1197         message_mark_all_read_for_user($recipient->id);
1198         $this->assertEquals(message_count_unread_messages($recipient), 0);
1199     }
1201     public function test_message_mark_all_read_for_user_touser_with_fromuser() {
1202         $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1203         $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
1204         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1206         $this->send_fake_unread_popup_notification($sender1, $recipient);
1207         $this->send_fake_unread_popup_notification($sender1, $recipient);
1208         $this->send_fake_unread_popup_notification($sender1, $recipient);
1209         $this->send_fake_message($sender1, $recipient);
1210         $this->send_fake_message($sender1, $recipient);
1211         $this->send_fake_message($sender1, $recipient);
1212         $this->send_fake_unread_popup_notification($sender2, $recipient);
1213         $this->send_fake_unread_popup_notification($sender2, $recipient);
1214         $this->send_fake_unread_popup_notification($sender2, $recipient);
1215         $this->send_fake_message($sender2, $recipient);
1216         $this->send_fake_message($sender2, $recipient);
1217         $this->send_fake_message($sender2, $recipient);
1219         message_mark_all_read_for_user($recipient->id, $sender1->id);
1220         $this->assertEquals(message_count_unread_messages($recipient), 6);
1221     }
1223     public function test_message_mark_all_read_for_user_touser_with_type() {
1224         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
1225         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
1227         $this->send_fake_unread_popup_notification($sender, $recipient);
1228         $this->send_fake_unread_popup_notification($sender, $recipient);
1229         $this->send_fake_unread_popup_notification($sender, $recipient);
1230         $this->send_fake_message($sender, $recipient);
1231         $this->send_fake_message($sender, $recipient);
1232         $this->send_fake_message($sender, $recipient);
1234         message_mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_NOTIFICATION);
1235         $this->assertEquals(message_count_unread_messages($recipient), 3);
1237         message_mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_MESSAGE);
1238         $this->assertEquals(message_count_unread_messages($recipient), 0);
1239     }