2d7dea85ac57498f3f939b3937c932342321842e
[moodle.git] / message / tests / externallib_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  * External message functions unit tests
19  *
20  * @package    core_message
21  * @category   external
22  * @copyright  2012 Jerome Mouneyrac
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 . '/webservice/tests/helpers.php');
31 require_once($CFG->dirroot . '/message/externallib.php');
33 use \core_message\tests\helper as testhelper;
35 class core_message_externallib_testcase extends externallib_advanced_testcase {
37     /**
38      * Tests set up
39      */
40     protected function setUp() {
41         global $CFG;
43         require_once($CFG->dirroot . '/message/lib.php');
44     }
46     /**
47      * Send a fake message.
48      *
49      * {@link message_send()} does not support transaction, this function will simulate a message
50      * sent from a user to another. We should stop using it once {@link message_send()} will support
51      * transactions. This is not clean at all, this is just used to add rows to the table.
52      *
53      * @param stdClass $userfrom user object of the one sending the message.
54      * @param stdClass $userto user object of the one receiving the message.
55      * @param string $message message to send.
56      * @param int $notification is the message a notification.
57      * @param int $time the time the message was sent
58      */
59     protected function send_message($userfrom, $userto, $message = 'Hello world!', $notification = 0, $time = 0) {
60         global $DB;
62         if (empty($time)) {
63             $time = time();
64         }
66         if ($notification) {
67             $record = new stdClass();
68             $record->useridfrom = $userfrom->id;
69             $record->useridto = $userto->id;
70             $record->subject = 'No subject';
71             $record->fullmessage = $message;
72             $record->smallmessage = $message;
73             $record->timecreated = $time;
75             return $DB->insert_record('notifications', $record);
76         }
78         if (!$conversationid = \core_message\api::get_conversation_between_users([$userfrom->id, $userto->id])) {
79             $conversation = \core_message\api::create_conversation(
80                 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
81                 [
82                     $userfrom->id,
83                     $userto->id
84                 ]
85             );
86             $conversationid = $conversation->id;
87         }
89         // Ok, send the message.
90         $record = new stdClass();
91         $record->useridfrom = $userfrom->id;
92         $record->conversationid = $conversationid;
93         $record->subject = 'No subject';
94         $record->fullmessage = $message;
95         $record->smallmessage = $message;
96         $record->timecreated = $time;
98         return $DB->insert_record('messages', $record);
99     }
101     /**
102      * Test send_instant_messages.
103      */
104     public function test_send_instant_messages() {
105         global $DB, $USER;
107         $this->resetAfterTest();
109         // Transactions used in tests, tell phpunit use alternative reset method.
110         $this->preventResetByRollback();
112         $user1 = self::getDataGenerator()->create_user();
113         $user2 = self::getDataGenerator()->create_user();
115         $this->setUser($user1);
117         // Create test message data.
118         $message1 = array();
119         $message1['touserid'] = $user2->id;
120         $message1['text'] = 'the message.';
121         $message1['clientmsgid'] = 4;
122         $messages = array($message1);
124         $sentmessages = core_message_external::send_instant_messages($messages);
125         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
126         $this->assertEquals(
127             get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message1['touserid']))),
128             array_pop($sentmessages)['errormessage']
129         );
131         // Add the user1 as a contact.
132         \core_message\api::add_contact($user1->id, $user2->id);
134         // Send message again. Now it should work properly.
135         $sentmessages = core_message_external::send_instant_messages($messages);
136         // We need to execute the return values cleaning process to simulate the web service server.
137         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
139         $sentmessage = reset($sentmessages);
141         $sql = "SELECT m.*, mcm.userid as useridto
142                  FROM {messages} m
143            INNER JOIN {message_conversations} mc
144                    ON m.conversationid = mc.id
145            INNER JOIN {message_conversation_members} mcm
146                    ON mcm.conversationid = mc.id
147                 WHERE mcm.userid != ?
148                   AND m.id = ?";
149         $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]);
151         // Confirm that the message was inserted correctly.
152         $this->assertEquals($themessage->useridfrom, $user1->id);
153         $this->assertEquals($themessage->useridto, $message1['touserid']);
154         $this->assertEquals($themessage->smallmessage, $message1['text']);
155         $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']);
156     }
158     /**
159      * Test send_instant_messages to a user who has blocked you.
160      */
161     public function test_send_instant_messages_blocked_user() {
162         global $DB;
164         $this->resetAfterTest();
166         // Transactions used in tests, tell phpunit use alternative reset method.
167         $this->preventResetByRollback();
169         $user1 = self::getDataGenerator()->create_user();
170         $user2 = self::getDataGenerator()->create_user();
172         $this->setUser($user1);
174         \core_message\api::block_user($user2->id, $user1->id);
176         // Create test message data.
177         $message1 = array();
178         $message1['touserid'] = $user2->id;
179         $message1['text'] = 'the message.';
180         $message1['clientmsgid'] = 4;
181         $messages = array($message1);
183         $sentmessages = core_message_external::send_instant_messages($messages);
184         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
186         $sentmessage = reset($sentmessages);
188         $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']);
190         $this->assertEquals(0, $DB->count_records('messages'));
191     }
193     /**
194      * Test send_instant_messages when sending a message to a non-contact who has blocked non-contacts.
195      */
196     public function test_send_instant_messages_block_non_contacts() {
197         global $DB;
199         $this->resetAfterTest(true);
201         // Transactions used in tests, tell phpunit use alternative reset method.
202         $this->preventResetByRollback();
204         $user1 = self::getDataGenerator()->create_user();
205         $user2 = self::getDataGenerator()->create_user();
207         $this->setUser($user1);
209         // Set the user preference so user 2 does not accept messages from non-contacts.
210         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2);
212         // Create test message data.
213         $message1 = array();
214         $message1['touserid'] = $user2->id;
215         $message1['text'] = 'the message.';
216         $message1['clientmsgid'] = 4;
217         $messages = array($message1);
219         $sentmessages = core_message_external::send_instant_messages($messages);
220         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
222         $sentmessage = reset($sentmessages);
224         $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']);
226         $this->assertEquals(0, $DB->count_records('messages'));
227     }
229     /**
230      * Test send_instant_messages when sending a message to a contact who has blocked non-contacts.
231      */
232     public function test_send_instant_messages_block_non_contacts_but_am_contact() {
233         global $DB, $USER;
235         $this->resetAfterTest(true);
237         // Transactions used in tests, tell phpunit use alternative reset method.
238         $this->preventResetByRollback();
240         $user1 = self::getDataGenerator()->create_user();
241         $user2 = self::getDataGenerator()->create_user();
243         $this->setUser($user1);
245         // Set the user preference so user 2 does not accept messages from non-contacts.
246         set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2);
248         \core_message\api::add_contact($user1->id, $user2->id);
250         // Create test message data.
251         $message1 = array();
252         $message1['touserid'] = $user2->id;
253         $message1['text'] = 'the message.';
254         $message1['clientmsgid'] = 4;
255         $messages = array($message1);
257         $sentmessages = core_message_external::send_instant_messages($messages);
258         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
260         $sentmessage = reset($sentmessages);
262         $sql = "SELECT m.*, mcm.userid as useridto
263                  FROM {messages} m
264            INNER JOIN {message_conversations} mc
265                    ON m.conversationid = mc.id
266            INNER JOIN {message_conversation_members} mcm
267                    ON mcm.conversationid = mc.id
268                 WHERE mcm.userid != ?
269                   AND m.id = ?";
270         $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]);
272         // Confirm that the message was inserted correctly.
273         $this->assertEquals($themessage->useridfrom, $user1->id);
274         $this->assertEquals($themessage->useridto, $message1['touserid']);
275         $this->assertEquals($themessage->smallmessage, $message1['text']);
276         $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']);
277     }
279     /**
280      * Test send_instant_messages with no capabilities
281      */
282     public function test_send_instant_messages_no_capability() {
283         global $DB;
285         $this->resetAfterTest(true);
287         // Transactions used in tests, tell phpunit use alternative reset method.
288         $this->preventResetByRollback();
290         $user1 = self::getDataGenerator()->create_user();
291         $user2 = self::getDataGenerator()->create_user();
293         $this->setUser($user1);
295         // Unset the required capabilities by the external function.
296         $contextid = context_system::instance()->id;
297         $userrole = $DB->get_record('role', array('shortname' => 'user'));
298         $this->unassignUserCapability('moodle/site:sendmessage', $contextid, $userrole->id);
300         // Create test message data.
301         $message1 = array();
302         $message1['touserid'] = $user2->id;
303         $message1['text'] = 'the message.';
304         $message1['clientmsgid'] = 4;
305         $messages = array($message1);
307         $this->expectException('required_capability_exception');
308         core_message_external::send_instant_messages($messages);
309     }
311     /**
312      * Test send_instant_messages when messaging is disabled.
313      */
314     public function test_send_instant_messages_messaging_disabled() {
315         global $CFG;
317         $this->resetAfterTest(true);
319         // Transactions used in tests, tell phpunit use alternative reset method.
320         $this->preventResetByRollback();
322         $user1 = self::getDataGenerator()->create_user();
323         $user2 = self::getDataGenerator()->create_user();
325         $this->setUser($user1);
327         // Disable messaging.
328         $CFG->messaging = 0;
330         // Create test message data.
331         $message1 = array();
332         $message1['touserid'] = $user2->id;
333         $message1['text'] = 'the message.';
334         $message1['clientmsgid'] = 4;
335         $messages = array($message1);
337         $this->expectException('moodle_exception');
338         core_message_external::send_instant_messages($messages);
339     }
341     /**
342      * Test create_contacts.
343      */
344     public function test_create_contacts() {
345         $this->resetAfterTest(true);
347         $user1 = self::getDataGenerator()->create_user();
348         $user2 = self::getDataGenerator()->create_user();
349         $user3 = self::getDataGenerator()->create_user();
350         $user4 = self::getDataGenerator()->create_user();
351         $user5 = self::getDataGenerator()->create_user();
352         $this->setUser($user1);
354         // Adding a contact.
355         $return = core_message_external::create_contacts(array($user2->id));
356         $this->assertDebuggingCalled();
357         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
358         $this->assertEquals(array(), $return);
360         // Adding a contact who is already a contact.
361         $return = core_message_external::create_contacts(array($user2->id));
362         $this->assertDebuggingCalled();
363         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
364         $this->assertEquals(array(), $return);
366         // Adding multiple contacts.
367         $return = core_message_external::create_contacts(array($user3->id, $user4->id));
368         $this->assertDebuggingCalledCount(2);
369         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
370         $this->assertEquals(array(), $return);
372         // Adding a non-existing user.
373         $return = core_message_external::create_contacts(array(99999));
374         $this->assertDebuggingCalled();
375         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
376         $this->assertCount(1, $return);
377         $return = array_pop($return);
378         $this->assertEquals($return['warningcode'], 'contactnotcreated');
379         $this->assertEquals($return['itemid'], 99999);
381         // Adding contacts with valid and invalid parameters.
382         $return = core_message_external::create_contacts(array($user5->id, 99999));
383         $this->assertDebuggingCalledCount(2);
384         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
385         $this->assertCount(1, $return);
386         $return = array_pop($return);
387         $this->assertEquals($return['warningcode'], 'contactnotcreated');
388         $this->assertEquals($return['itemid'], 99999);
390         // Try to add a contact to another user, should throw an exception.
391         // All assertions must be added before this point.
392         $this->expectException('required_capability_exception');
393         core_message_external::create_contacts(array($user2->id), $user3->id);
394     }
396     /**
397      * Test delete_contacts.
398      */
399     public function test_delete_contacts() {
400         $this->resetAfterTest(true);
402         $user1 = self::getDataGenerator()->create_user();
403         $user2 = self::getDataGenerator()->create_user();
404         $user3 = self::getDataGenerator()->create_user();
405         $user4 = self::getDataGenerator()->create_user();
406         $user5 = self::getDataGenerator()->create_user();
407         $user6 = self::getDataGenerator()->create_user();
408         $this->setUser($user1);
410         \core_message\api::add_contact($user1->id, $user3->id);
411         \core_message\api::add_contact($user1->id, $user4->id);
412         \core_message\api::add_contact($user1->id, $user5->id);
413         \core_message\api::add_contact($user1->id, $user6->id);
415         // Removing a non-contact.
416         $return = core_message_external::delete_contacts(array($user2->id));
417         $this->assertNull($return);
419         // Removing one contact.
420         $return = core_message_external::delete_contacts(array($user3->id));
421         $this->assertNull($return);
423         // Removing multiple contacts.
424         $return = core_message_external::delete_contacts(array($user4->id, $user5->id));
425         $this->assertNull($return);
427         // Removing contact from unexisting user.
428         $return = core_message_external::delete_contacts(array(99999));
429         $this->assertNull($return);
431         // Removing mixed valid and invalid data.
432         $return = core_message_external::delete_contacts(array($user6->id, 99999));
433         $this->assertNull($return);
435         // Try to delete a contact of another user contact list, should throw an exception.
436         // All assertions must be added before this point.
437         $this->expectException('required_capability_exception');
438         core_message_external::delete_contacts(array($user2->id), $user3->id);
439     }
441     /**
442      * Test block_contacts.
443      */
444     public function test_block_contacts() {
445         $this->resetAfterTest(true);
447         $user1 = self::getDataGenerator()->create_user();
448         $user2 = self::getDataGenerator()->create_user();
449         $user3 = self::getDataGenerator()->create_user();
450         $user4 = self::getDataGenerator()->create_user();
451         $user5 = self::getDataGenerator()->create_user();
452         $this->setUser($user1);
454         \core_message\api::add_contact($user1->id, $user3->id);
455         \core_message\api::add_contact($user1->id, $user4->id);
456         \core_message\api::add_contact($user1->id, $user5->id);
458         // Blocking a contact.
459         $return = core_message_external::block_contacts(array($user2->id));
460         $this->assertDebuggingCalled();
461         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
462         $this->assertEquals(array(), $return);
464         // Blocking a contact who is already a contact.
465         $return = core_message_external::block_contacts(array($user2->id));
466         $this->assertDebuggingCalled();
467         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
468         $this->assertEquals(array(), $return);
470         // Blocking multiple contacts.
471         $return = core_message_external::block_contacts(array($user3->id, $user4->id));
472         $this->assertDebuggingCalledCount(2);
473         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
474         $this->assertEquals(array(), $return);
476         // Blocking a non-existing user.
477         $return = core_message_external::block_contacts(array(99999));
478         $this->assertDebuggingCalled();
479         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
480         $this->assertCount(1, $return);
481         $return = array_pop($return);
482         $this->assertEquals($return['warningcode'], 'contactnotblocked');
483         $this->assertEquals($return['itemid'], 99999);
485         // Blocking contacts with valid and invalid parameters.
486         $return = core_message_external::block_contacts(array($user5->id, 99999));
487         $this->assertDebuggingCalledCount(2);
488         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
489         $this->assertCount(1, $return);
490         $return = array_pop($return);
491         $this->assertEquals($return['warningcode'], 'contactnotblocked');
492         $this->assertEquals($return['itemid'], 99999);
494         // Try to block a contact of another user contact list, should throw an exception.
495         // All assertions must be added before this point.
496         $this->expectException('required_capability_exception');
497         core_message_external::block_contacts(array($user2->id), $user3->id);
498     }
500     /**
501      * Test unblock_contacts.
502      */
503     public function test_unblock_contacts() {
504         $this->resetAfterTest(true);
506         $user1 = self::getDataGenerator()->create_user();
507         $user2 = self::getDataGenerator()->create_user();
508         $user3 = self::getDataGenerator()->create_user();
509         $user4 = self::getDataGenerator()->create_user();
510         $user5 = self::getDataGenerator()->create_user();
511         $user6 = self::getDataGenerator()->create_user();
512         $this->setUser($user1);
514         \core_message\api::add_contact($user1->id, $user3->id);
515         \core_message\api::add_contact($user1->id, $user4->id);
516         \core_message\api::add_contact($user1->id, $user5->id);
517         \core_message\api::add_contact($user1->id, $user6->id);
519         // Removing a non-contact.
520         $return = core_message_external::unblock_contacts(array($user2->id));
521         $this->assertDebuggingCalled();
522         $this->assertNull($return);
524         // Removing one contact.
525         $return = core_message_external::unblock_contacts(array($user3->id));
526         $this->assertDebuggingCalled();
527         $this->assertNull($return);
529         // Removing multiple contacts.
530         $return = core_message_external::unblock_contacts(array($user4->id, $user5->id));
531         $this->assertDebuggingCalledCount(2);
532         $this->assertNull($return);
534         // Removing contact from unexisting user.
535         $return = core_message_external::unblock_contacts(array(99999));
536         $this->assertDebuggingCalled();
537         $this->assertNull($return);
539         // Removing mixed valid and invalid data.
540         $return = core_message_external::unblock_contacts(array($user6->id, 99999));
541         $this->assertDebuggingCalledCount(2);
542         $this->assertNull($return);
544         // Try to unblock a contact of another user contact list, should throw an exception.
545         // All assertions must be added before this point.
546         $this->expectException('required_capability_exception');
547         core_message_external::unblock_contacts(array($user2->id), $user3->id);
548         $this->assertDebuggingCalled();
549     }
551     /**
552      * Test getting contact requests.
553      */
554     public function test_get_contact_requests() {
555         global $PAGE;
557         $this->resetAfterTest();
559         $user1 = self::getDataGenerator()->create_user();
560         $user2 = self::getDataGenerator()->create_user();
561         $user3 = self::getDataGenerator()->create_user();
563         $this->setUser($user1);
565         // Block one user, their request should not show up.
566         \core_message\api::block_user($user1->id, $user3->id);
568         \core_message\api::create_contact_request($user2->id, $user1->id);
569         \core_message\api::create_contact_request($user3->id, $user1->id);
571         $requests = core_message_external::get_contact_requests($user1->id);
572         $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
574         $this->assertCount(1, $requests);
576         $request = reset($requests);
577         $userpicture = new \user_picture($user2);
578         $profileimageurl = $userpicture->get_url($PAGE)->out(false);
580         $this->assertEquals($user2->id, $request['id']);
581         $this->assertEquals(fullname($user2), $request['fullname']);
582         $this->assertArrayHasKey('profileimageurl', $request);
583         $this->assertArrayHasKey('profileimageurlsmall', $request);
584         $this->assertArrayHasKey('isonline', $request);
585         $this->assertArrayHasKey('showonlinestatus', $request);
586         $this->assertArrayHasKey('isblocked', $request);
587         $this->assertArrayHasKey('iscontact', $request);
588     }
590     /**
591      * Test getting contact requests when there are none.
592      */
593     public function test_get_contact_requests_no_requests() {
594         $this->resetAfterTest();
596         $user1 = self::getDataGenerator()->create_user();
598         $this->setUser($user1);
600         $requests = core_message_external::get_contact_requests($user1->id);
601         $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
603         $this->assertEmpty($requests);
604     }
606     /**
607      * Test getting contact requests with limits.
608      */
609     public function test_get_contact_requests_with_limits() {
610         $this->resetAfterTest();
612         $user1 = self::getDataGenerator()->create_user();
613         $user2 = self::getDataGenerator()->create_user();
614         $user3 = self::getDataGenerator()->create_user();
616         $this->setUser($user1);
618         \core_message\api::create_contact_request($user2->id, $user1->id);
619         \core_message\api::create_contact_request($user3->id, $user1->id);
621         $requests = core_message_external::get_contact_requests($user1->id, 0, 1);
622         $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
624         $this->assertCount(1, $requests);
625     }
627     /**
628      * Test getting contact requests with messaging disabled.
629      */
630     public function test_get_contact_requests_messaging_disabled() {
631         global $CFG;
633         $this->resetAfterTest();
635         // Create some skeleton data just so we can call the WS.
636         $user1 = self::getDataGenerator()->create_user();
638         $this->setUser($user1);
640         // Disable messaging.
641         $CFG->messaging = 0;
643         // Ensure an exception is thrown.
644         $this->expectException('moodle_exception');
645         core_message_external::get_contact_requests($user1->id);
646     }
648     /**
649      * Test getting contact requests with no permission.
650      */
651     public function test_get_contact_requests_no_permission() {
652         $this->resetAfterTest();
654         // Create some skeleton data just so we can call the WS.
655         $user1 = self::getDataGenerator()->create_user();
656         $user2 = self::getDataGenerator()->create_user();
657         $user3 = self::getDataGenerator()->create_user();
659         $this->setUser($user3);
661         // Ensure an exception is thrown.
662         $this->expectException('required_capability_exception');
663         core_message_external::create_contact_request($user1->id, $user2->id);
664     }
666     /**
667      * Test getting the number of received contact requests.
668      */
669     public function test_get_received_contact_requests_count() {
670         $this->resetAfterTest();
672         $user1 = self::getDataGenerator()->create_user();
673         $user2 = self::getDataGenerator()->create_user();
674         $user3 = self::getDataGenerator()->create_user();
675         $user4 = self::getDataGenerator()->create_user();
677         $this->setUser($user1);
679         $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
680         $contactrequestnumber = external_api::clean_returnvalue(
681             core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
682         $this->assertEquals(0, $contactrequestnumber);
684         \core_message\api::create_contact_request($user2->id, $user1->id);
686         $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
687         $contactrequestnumber = external_api::clean_returnvalue(
688             core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
689         $this->assertEquals(1, $contactrequestnumber);
691         \core_message\api::create_contact_request($user3->id, $user1->id);
693         $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
694         $contactrequestnumber = external_api::clean_returnvalue(
695             core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
696         $this->assertEquals(2, $contactrequestnumber);
698         \core_message\api::create_contact_request($user1->id, $user4->id);
700         // Web service should ignore sent requests.
701         $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
702         $contactrequestnumber = external_api::clean_returnvalue(
703             core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
704         $this->assertEquals(2, $contactrequestnumber);
705     }
707     /**
708      * Test getting the number of received contact requests with no permissions.
709      */
710     public function test_get_received_contact_requests_count_no_permission() {
711         $this->resetAfterTest();
713         // Create some skeleton data just so we can call the WS.
714         $user1 = self::getDataGenerator()->create_user();
715         $user2 = self::getDataGenerator()->create_user();
717         $this->setUser($user2);
719         // Ensure an exception is thrown.
720         $this->expectException('required_capability_exception');
721         core_message_external::get_received_contact_requests_count($user1->id);
722     }
724     /**
725      * Test getting the number of received contact requests with messaging disabled.
726      */
727     public function test_get_received_contact_requests_count_messaging_disabled() {
728         global $CFG;
730         $this->resetAfterTest();
732         // Create some skeleton data just so we can call the WS.
733         $user1 = self::getDataGenerator()->create_user();
735         $this->setUser($user1);
737         // Disable messaging.
738         $CFG->messaging = 0;
740         // Ensure an exception is thrown.
741         $this->expectException('moodle_exception');
742         core_message_external::get_received_contact_requests_count($user1->id);
743     }
745     /**
746      * Test creating a contact request.
747      */
748     public function test_create_contact_request() {
749         global $CFG, $DB;
751         $this->resetAfterTest();
753         $user1 = self::getDataGenerator()->create_user();
754         $user2 = self::getDataGenerator()->create_user();
756         $this->setUser($user1);
758         // Allow users to message anyone site-wide.
759         $CFG->messagingallusers = 1;
761         $return = core_message_external::create_contact_request($user1->id, $user2->id);
762         $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
763         $this->assertEquals([], $return['warnings']);
765         $request = $DB->get_records('message_contact_requests');
767         $this->assertCount(1, $request);
769         $request = reset($request);
771         $this->assertEquals($request->id, $return['request']['id']);
772         $this->assertEquals($request->userid, $return['request']['userid']);
773         $this->assertEquals($request->requesteduserid, $return['request']['requesteduserid']);
774         $this->assertEquals($request->timecreated, $return['request']['timecreated']);
775     }
777     /**
778      * Test creating a contact request when not allowed.
779      */
780     public function test_create_contact_request_not_allowed() {
781         global $CFG;
783         $this->resetAfterTest();
785         $user1 = self::getDataGenerator()->create_user();
786         $user2 = self::getDataGenerator()->create_user();
788         $this->setUser($user1);
790         $CFG->messagingallusers = 0;
792         $return = core_message_external::create_contact_request($user1->id, $user2->id);
793         $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
795         $warning = reset($return['warnings']);
797         $this->assertEquals('user', $warning['item']);
798         $this->assertEquals($user2->id, $warning['itemid']);
799         $this->assertEquals('cannotcreatecontactrequest', $warning['warningcode']);
800         $this->assertEquals('You are unable to create a contact request for this user', $warning['message']);
801     }
803     /**
804      * Test creating a contact request with messaging disabled.
805      */
806     public function test_create_contact_request_messaging_disabled() {
807         global $CFG;
809         $this->resetAfterTest();
811         // Create some skeleton data just so we can call the WS.
812         $user1 = self::getDataGenerator()->create_user();
813         $user2 = self::getDataGenerator()->create_user();
815         $this->setUser($user1);
817         // Disable messaging.
818         $CFG->messaging = 0;
820         // Ensure an exception is thrown.
821         $this->expectException('moodle_exception');
822         core_message_external::create_contact_request($user1->id, $user2->id);
823     }
825     /**
826      * Test creating a contact request with no permission.
827      */
828     public function test_create_contact_request_no_permission() {
829         $this->resetAfterTest();
831         // Create some skeleton data just so we can call the WS.
832         $user1 = self::getDataGenerator()->create_user();
833         $user2 = self::getDataGenerator()->create_user();
834         $user3 = self::getDataGenerator()->create_user();
836         $this->setUser($user3);
838         // Ensure an exception is thrown.
839         $this->expectException('required_capability_exception');
840         core_message_external::create_contact_request($user1->id, $user2->id);
841     }
843     /**
844      * Test confirming a contact request.
845      */
846     public function test_confirm_contact_request() {
847         global $DB;
849         $this->resetAfterTest();
851         $user1 = self::getDataGenerator()->create_user();
852         $user2 = self::getDataGenerator()->create_user();
854         $this->setUser($user1);
856         \core_message\api::create_contact_request($user1->id, $user2->id);
858         $this->setUser($user2);
860         $return = core_message_external::confirm_contact_request($user1->id, $user2->id);
861         $return = external_api::clean_returnvalue(core_message_external::confirm_contact_request_returns(), $return);
862         $this->assertEquals(array(), $return);
864         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
866         $contact = $DB->get_records('message_contacts');
868         $this->assertCount(1, $contact);
870         $contact = reset($contact);
872         $this->assertEquals($user1->id, $contact->userid);
873         $this->assertEquals($user2->id, $contact->contactid);
874     }
876     /**
877      * Test confirming a contact request with messaging disabled.
878      */
879     public function test_confirm_contact_request_messaging_disabled() {
880         global $CFG;
882         $this->resetAfterTest();
884         // Create some skeleton data just so we can call the WS.
885         $user1 = self::getDataGenerator()->create_user();
886         $user2 = self::getDataGenerator()->create_user();
888         $this->setUser($user1);
890         // Disable messaging.
891         $CFG->messaging = 0;
893         // Ensure an exception is thrown.
894         $this->expectException('moodle_exception');
895         core_message_external::confirm_contact_request($user1->id, $user2->id);
896     }
898     /**
899      * Test confirming a contact request with no permission.
900      */
901     public function test_confirm_contact_request_no_permission() {
902         $this->resetAfterTest();
904         // Create some skeleton data just so we can call the WS.
905         $user1 = self::getDataGenerator()->create_user();
906         $user2 = self::getDataGenerator()->create_user();
907         $user3 = self::getDataGenerator()->create_user();
909         $this->setUser($user3);
911         // Ensure an exception is thrown.
912         $this->expectException('required_capability_exception');
913         core_message_external::confirm_contact_request($user1->id, $user2->id);
914     }
916     /**
917      * Test declining a contact request.
918      */
919     public function test_decline_contact_request() {
920         global $DB;
922         $this->resetAfterTest();
924         $user1 = self::getDataGenerator()->create_user();
925         $user2 = self::getDataGenerator()->create_user();
927         $this->setUser($user1);
929         \core_message\api::create_contact_request($user1->id, $user2->id);
931         $this->setUser($user2);
933         $return = core_message_external::decline_contact_request($user1->id, $user2->id);
934         $return = external_api::clean_returnvalue(core_message_external::decline_contact_request_returns(), $return);
935         $this->assertEquals(array(), $return);
937         $this->assertEquals(0, $DB->count_records('message_contact_requests'));
938         $this->assertEquals(0, $DB->count_records('message_contacts'));
939     }
941     /**
942      * Test declining a contact request with messaging disabled.
943      */
944     public function test_decline_contact_request_messaging_disabled() {
945         global $CFG;
947         $this->resetAfterTest();
949         // Create some skeleton data just so we can call the WS.
950         $user1 = self::getDataGenerator()->create_user();
951         $user2 = self::getDataGenerator()->create_user();
953         $this->setUser($user1);
955         // Disable messaging.
956         $CFG->messaging = 0;
958         // Ensure an exception is thrown.
959         $this->expectException('moodle_exception');
960         core_message_external::decline_contact_request($user1->id, $user2->id);
961     }
963     /**
964      * Test declining a contact request with no permission.
965      */
966     public function test_decline_contact_request_no_permission() {
967         $this->resetAfterTest();
969         // Create some skeleton data just so we can call the WS.
970         $user1 = self::getDataGenerator()->create_user();
971         $user2 = self::getDataGenerator()->create_user();
972         $user3 = self::getDataGenerator()->create_user();
974         $this->setUser($user3);
976         // Ensure an exception is thrown.
977         $this->expectException('required_capability_exception');
978         core_message_external::decline_contact_request($user1->id, $user2->id);
979     }
981     /**
982      * Test blocking a user.
983      */
984     public function test_block_user() {
985         global $DB;
987         $this->resetAfterTest(true);
989         $user1 = self::getDataGenerator()->create_user();
990         $user2 = self::getDataGenerator()->create_user();
992         $this->setUser($user1);
994         // Blocking a user.
995         $return = core_message_external::block_user($user1->id, $user2->id);
996         $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
997         $this->assertEquals(array(), $return);
999         // Get list of blocked users.
1000         $record = $DB->get_record('message_users_blocked', []);
1002         $this->assertEquals($user1->id, $record->userid);
1003         $this->assertEquals($user2->id, $record->blockeduserid);
1005         // Blocking a user who is already blocked.
1006         $return = core_message_external::block_user($user1->id, $user2->id);
1007         $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
1008         $this->assertEquals(array(), $return);
1010         $this->assertEquals(1, $DB->count_records('message_users_blocked'));
1011     }
1013     /**
1014      * Test blocking a user with messaging disabled.
1015      */
1016     public function test_block_user_messaging_disabled() {
1017         global $CFG;
1019         $this->resetAfterTest();
1021         // Create some skeleton data just so we can call the WS.
1022         $user1 = self::getDataGenerator()->create_user();
1023         $user2 = self::getDataGenerator()->create_user();
1025         $this->setUser($user1);
1027         // Disable messaging.
1028         $CFG->messaging = 0;
1030         // Ensure an exception is thrown.
1031         $this->expectException('moodle_exception');
1032         core_message_external::block_user($user1->id, $user2->id);
1033     }
1035     /**
1036      * Test blocking a user with no permission.
1037      */
1038     public function test_block_user_no_permission() {
1039         $this->resetAfterTest();
1041         // Create some skeleton data just so we can call the WS.
1042         $user1 = self::getDataGenerator()->create_user();
1043         $user2 = self::getDataGenerator()->create_user();
1044         $user3 = self::getDataGenerator()->create_user();
1046         $this->setUser($user3);
1048         // Ensure an exception is thrown.
1049         $this->expectException('required_capability_exception');
1050         core_message_external::block_user($user1->id, $user2->id);
1051     }
1053     /**
1054      * Test unblocking a user.
1055      */
1056     public function test_unblock_user() {
1057         global $DB;
1059         $this->resetAfterTest(true);
1061         $user1 = self::getDataGenerator()->create_user();
1062         $user2 = self::getDataGenerator()->create_user();
1064         $this->setUser($user1);
1066         // Block the user.
1067         \core_message\api::block_user($user1->id, $user2->id);
1069         // Unblocking a user.
1070         $return = core_message_external::unblock_user($user1->id, $user2->id);
1071         $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
1072         $this->assertEquals(array(), $return);
1074         $this->assertEquals(0, $DB->count_records('message_users_blocked'));
1076         // Unblocking a user who is already unblocked.
1077         $return = core_message_external::unblock_user($user1->id, $user2->id);
1078         $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
1079         $this->assertEquals(array(), $return);
1081         $this->assertEquals(0, $DB->count_records('message_users_blocked'));
1082     }
1084     /**
1085      * Test unblocking a user with messaging disabled.
1086      */
1087     public function test_unblock_user_messaging_disabled() {
1088         global $CFG;
1090         $this->resetAfterTest();
1092         // Create some skeleton data just so we can call the WS.
1093         $user1 = self::getDataGenerator()->create_user();
1094         $user2 = self::getDataGenerator()->create_user();
1096         $this->setUser($user1);
1098         // Disable messaging.
1099         $CFG->messaging = 0;
1101         // Ensure an exception is thrown.
1102         $this->expectException('moodle_exception');
1103         core_message_external::unblock_user($user1->id, $user2->id);
1104     }
1106     /**
1107      * Test unblocking a user with no permission.
1108      */
1109     public function test_unblock_user_no_permission() {
1110         $this->resetAfterTest();
1112         // Create some skeleton data just so we can call the WS.
1113         $user1 = self::getDataGenerator()->create_user();
1114         $user2 = self::getDataGenerator()->create_user();
1115         $user3 = self::getDataGenerator()->create_user();
1117         $this->setUser($user3);
1119         // Ensure an exception is thrown.
1120         $this->expectException('required_capability_exception');
1121         core_message_external::unblock_user($user1->id, $user2->id);
1122     }
1124     /**
1125      * Test get_contacts.
1126      */
1127     public function test_get_contacts() {
1128         $this->resetAfterTest(true);
1130         $user1 = self::getDataGenerator()->create_user();
1131         $user_stranger = self::getDataGenerator()->create_user();
1132         $user_offline1 = self::getDataGenerator()->create_user();
1133         $user_offline2 = self::getDataGenerator()->create_user();
1134         $user_offline3 = self::getDataGenerator()->create_user();
1135         $user_online = new stdClass();
1136         $user_online->lastaccess = time();
1137         $user_online = self::getDataGenerator()->create_user($user_online);
1138         $user_blocked = self::getDataGenerator()->create_user();
1139         $noreplyuser = core_user::get_user(core_user::NOREPLY_USER);
1141         // Login as user1.
1142         $this->setUser($user1);
1143         \core_message\api::add_contact($user1->id, $user_offline1->id);
1144         \core_message\api::add_contact($user1->id, $user_offline2->id);
1145         \core_message\api::add_contact($user1->id, $user_offline3->id);
1146         \core_message\api::add_contact($user1->id, $user_online->id);
1148         // User_stranger sends a couple of messages to user1.
1149         $this->send_message($user_stranger, $user1, 'Hello there!');
1150         $this->send_message($user_stranger, $user1, 'How you goin?');
1151         $this->send_message($user_stranger, $user1, 'Cya!');
1152         $this->send_message($noreplyuser, $user1, 'I am not a real user');
1154         // User_blocked sends a message to user1.
1155         $this->send_message($user_blocked, $user1, 'Here, have some spam.');
1157         // Retrieve the contacts of the user.
1158         $this->setUser($user1);
1159         $contacts = core_message_external::get_contacts();
1160         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1161         $this->assertCount(3, $contacts['offline']);
1162         $this->assertCount(1, $contacts['online']);
1163         $this->assertCount(3, $contacts['strangers']);
1164         core_message_external::block_contacts(array($user_blocked->id));
1165         $this->assertDebuggingCalled();
1166         $contacts = core_message_external::get_contacts();
1167         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1168         $this->assertCount(3, $contacts['offline']);
1169         $this->assertCount(1, $contacts['online']);
1170         $this->assertCount(2, $contacts['strangers']);
1172         // Checking some of the fields returned.
1173         $stranger = array_pop($contacts['strangers']);
1175         $this->assertEquals(core_user::NOREPLY_USER, $stranger['id']);
1176         $this->assertEquals(1, $stranger['unread']);
1178         // Check that deleted users are not returned.
1179         delete_user($user_offline1);
1180         delete_user($user_stranger);
1181         delete_user($user_online);
1182         $contacts = core_message_external::get_contacts();
1183         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1184         $this->assertCount(2, $contacts['offline']);
1185         $this->assertCount(0, $contacts['online']);
1186         $this->assertCount(1, $contacts['strangers']);
1187     }
1189     /**
1190      * Test search_contacts.
1191      * @expectedException moodle_exception
1192      */
1193     public function test_search_contacts() {
1194         global $DB;
1195         $this->resetAfterTest(true);
1197         $course1 = $this->getDataGenerator()->create_course();
1198         $course2 = $this->getDataGenerator()->create_course();
1200         $user1 = new stdClass();
1201         $user1->firstname = 'X';
1202         $user1->lastname = 'X';
1203         $user1 = $this->getDataGenerator()->create_user($user1);
1204         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1205         $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1207         $user2 = new stdClass();
1208         $user2->firstname = 'Eric';
1209         $user2->lastname = 'Cartman';
1210         $user2 = self::getDataGenerator()->create_user($user2);
1211         $user3 = new stdClass();
1212         $user3->firstname = 'Stan';
1213         $user3->lastname = 'Marsh';
1214         $user3 = self::getDataGenerator()->create_user($user3);
1215         self::getDataGenerator()->enrol_user($user3->id, $course1->id);
1216         $user4 = new stdClass();
1217         $user4->firstname = 'Kyle';
1218         $user4->lastname = 'Broflovski';
1219         $user4 = self::getDataGenerator()->create_user($user4);
1220         $user5 = new stdClass();
1221         $user5->firstname = 'Kenny';
1222         $user5->lastname = 'McCormick';
1223         $user5 = self::getDataGenerator()->create_user($user5);
1224         self::getDataGenerator()->enrol_user($user5->id, $course2->id);
1226         $this->setUser($user1);
1228         $results = core_message_external::search_contacts('r');
1229         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1230         $this->assertCount(5, $results); // Users 2 through 5 + admin
1232         $results = core_message_external::search_contacts('r', true);
1233         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1234         $this->assertCount(2, $results);
1236         $results = core_message_external::search_contacts('Kyle', false);
1237         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1238         $this->assertCount(1, $results);
1239         $result = reset($results);
1240         $this->assertEquals($user4->id, $result['id']);
1242         $results = core_message_external::search_contacts('y', false);
1243         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1244         $this->assertCount(2, $results);
1246         $results = core_message_external::search_contacts('y', true);
1247         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1248         $this->assertCount(1, $results);
1249         $result = reset($results);
1250         $this->assertEquals($user5->id, $result['id']);
1252         // Empty query, will throw an exception.
1253         $results = core_message_external::search_contacts('');
1254     }
1256     /**
1257      * Test get_messages.
1258      */
1259     public function test_get_messages() {
1260         global $CFG, $DB;
1261         $this->resetAfterTest(true);
1263         $this->preventResetByRollback();
1264         // This mark the messages as read!.
1265         $sink = $this->redirectMessages();
1267         $user1 = self::getDataGenerator()->create_user();
1268         $user2 = self::getDataGenerator()->create_user();
1269         $user3 = self::getDataGenerator()->create_user();
1271         $course = self::getDataGenerator()->create_course();
1273         // Send a message from one user to another.
1274         message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
1275         message_post_message($user1, $user3, 'some random text 2', FORMAT_MOODLE);
1276         message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
1277         message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
1278         message_post_message($user3, $user1, 'some random text 5', FORMAT_MOODLE);
1280         $this->setUser($user1);
1281         // Get read conversations from user1 to user2.
1282         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
1283         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1284         $this->assertCount(1, $messages['messages']);
1286         // Delete the message.
1287         $message = array_shift($messages['messages']);
1288         \core_message\api::delete_message($user1->id, $message['id']);
1290         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
1291         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1292         $this->assertCount(0, $messages['messages']);
1294         // Get unread conversations from user1 to user2.
1295         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', false, true, 0, 0);
1296         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1297         $this->assertCount(0, $messages['messages']);
1299         // Get read messages send from user1.
1300         $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1301         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1302         $this->assertCount(1, $messages['messages']);
1304         $this->setUser($user2);
1305         // Get read conversations from any user to user2.
1306         $messages = core_message_external::get_messages($user2->id, 0, 'conversations', true, true, 0, 0);
1307         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1308         $this->assertCount(2, $messages['messages']);
1310         // Conversations from user3 to user2.
1311         $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
1312         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1313         $this->assertCount(1, $messages['messages']);
1315         // Delete the message.
1316         $message = array_shift($messages['messages']);
1317         \core_message\api::delete_message($user2->id, $message['id']);
1319         $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
1320         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1321         $this->assertCount(0, $messages['messages']);
1323         $this->setUser($user3);
1324         // Get read notifications received by user3.
1325         $messages = core_message_external::get_messages($user3->id, 0, 'notifications', true, true, 0, 0);
1326         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1327         $this->assertCount(0, $messages['messages']);
1329         // Now, create some notifications...
1330         // We are creating fake notifications but based on real ones.
1332         // This one comes from a disabled plugin's provider and therefore is not sent.
1333         $eventdata = new \core\message\message();
1334         $eventdata->courseid          = $course->id;
1335         $eventdata->notification      = 1;
1336         $eventdata->modulename        = 'moodle';
1337         $eventdata->component         = 'enrol_paypal';
1338         $eventdata->name              = 'paypal_enrolment';
1339         $eventdata->userfrom          = get_admin();
1340         $eventdata->userto            = $user1;
1341         $eventdata->subject           = "Moodle: PayPal payment";
1342         $eventdata->fullmessage       = "Your PayPal payment is pending.";
1343         $eventdata->fullmessageformat = FORMAT_PLAIN;
1344         $eventdata->fullmessagehtml   = '';
1345         $eventdata->smallmessage      = '';
1346         message_send($eventdata);
1347         $this->assertDebuggingCalled('Attempt to send msg from a provider enrol_paypal/paypal_enrolment '.
1348             'that is inactive or not allowed for the user id='.$user1->id);
1350         // This one omits notification = 1.
1351         $message = new \core\message\message();
1352         $message->courseid          = $course->id;
1353         $message->component         = 'enrol_manual';
1354         $message->name              = 'expiry_notification';
1355         $message->userfrom          = $user2;
1356         $message->userto            = $user1;
1357         $message->subject           = 'Test: This is not a notification but otherwise is valid';
1358         $message->fullmessage       = 'Test: Full message';
1359         $message->fullmessageformat = FORMAT_MARKDOWN;
1360         $message->fullmessagehtml   = markdown_to_html($message->fullmessage);
1361         $message->smallmessage      = $message->subject;
1362         $message->contexturlname    = $course->fullname;
1363         $message->contexturl        = (string)new moodle_url('/course/view.php', array('id' => $course->id));
1364         message_send($message);
1366         $message = new \core\message\message();
1367         $message->courseid          = $course->id;
1368         $message->notification      = 1;
1369         $message->component         = 'enrol_manual';
1370         $message->name              = 'expiry_notification';
1371         $message->userfrom          = $user2;
1372         $message->userto            = $user1;
1373         $message->subject           = 'Enrolment expired';
1374         $message->fullmessage       = 'Enrolment expired blah blah blah';
1375         $message->fullmessageformat = FORMAT_MARKDOWN;
1376         $message->fullmessagehtml   = markdown_to_html($message->fullmessage);
1377         $message->smallmessage      = $message->subject;
1378         $message->contexturlname    = $course->fullname;
1379         $message->contexturl        = (string)new moodle_url('/course/view.php', array('id' => $course->id));
1380         message_send($message);
1382         $userfrom = core_user::get_noreply_user();
1383         $userfrom->maildisplay = true;
1384         $eventdata = new \core\message\message();
1385         $eventdata->courseid          = $course->id;
1386         $eventdata->component         = 'moodle';
1387         $eventdata->name              = 'badgecreatornotice';
1388         $eventdata->userfrom          = $userfrom;
1389         $eventdata->userto            = $user1;
1390         $eventdata->notification      = 1;
1391         $eventdata->subject           = 'New badge';
1392         $eventdata->fullmessage       = format_text_email($eventdata->subject, FORMAT_HTML);
1393         $eventdata->fullmessageformat = FORMAT_PLAIN;
1394         $eventdata->fullmessagehtml   = $eventdata->subject;
1395         $eventdata->smallmessage      = $eventdata->subject;
1396         message_send($eventdata);
1398         $eventdata = new \core\message\message();
1399         $eventdata->courseid         = $course->id;
1400         $eventdata->name             = 'submission';
1401         $eventdata->component        = 'mod_feedback';
1402         $eventdata->userfrom         = $user1;
1403         $eventdata->userto           = $user2;
1404         $eventdata->subject          = 'Feedback submitted';
1405         $eventdata->fullmessage      = 'Feedback submitted from an user';
1406         $eventdata->fullmessageformat = FORMAT_PLAIN;
1407         $eventdata->fullmessagehtml  = '<strong>Feedback submitted</strong>';
1408         $eventdata->smallmessage     = '';
1409         message_send($eventdata);
1411         $this->setUser($user1);
1412         // Get read notifications from any user to user1.
1413         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 0);
1414         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1415         $this->assertCount(3, $messages['messages']);
1417         // Get one read notifications from any user to user1.
1418         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 1);
1419         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1420         $this->assertCount(1, $messages['messages']);
1422         // Get unread notifications from any user to user1.
1423         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', false, true, 0, 0);
1424         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1425         $this->assertCount(0, $messages['messages']);
1427         // Get read both type of messages from any user to user1.
1428         $messages = core_message_external::get_messages($user1->id, 0, 'both', true, true, 0, 0);
1429         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1430         $this->assertCount(4, $messages['messages']);
1432         // Get read notifications from no-reply-user to user1.
1433         $messages = core_message_external::get_messages($user1->id, $userfrom->id, 'notifications', true, true, 0, 0);
1434         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1435         $this->assertCount(1, $messages['messages']);
1437         // Get notifications send by user1 to any user.
1438         $messages = core_message_external::get_messages(0, $user1->id, 'notifications', true, true, 0, 0);
1439         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1440         $this->assertCount(1, $messages['messages']);
1442         // Test warnings.
1443         $CFG->messaging = 0;
1445         $messages = core_message_external::get_messages(0, $user1->id, 'both', true, true, 0, 0);
1446         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1447         $this->assertCount(1, $messages['warnings']);
1449         // Test exceptions.
1451         // Messaging disabled.
1452         try {
1453             $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1454             $this->fail('Exception expected due messaging disabled.');
1455         } catch (moodle_exception $e) {
1456             $this->assertEquals('disabled', $e->errorcode);
1457         }
1459         $CFG->messaging = 1;
1461         // Invalid users.
1462         try {
1463             $messages = core_message_external::get_messages(0, 0, 'conversations', true, true, 0, 0);
1464             $this->fail('Exception expected due invalid users.');
1465         } catch (moodle_exception $e) {
1466             $this->assertEquals('accessdenied', $e->errorcode);
1467         }
1469         // Invalid user ids.
1470         try {
1471             $messages = core_message_external::get_messages(2500, 0, 'conversations', true, true, 0, 0);
1472             $this->fail('Exception expected due invalid users.');
1473         } catch (moodle_exception $e) {
1474             $this->assertEquals('invaliduser', $e->errorcode);
1475         }
1477         // Invalid users (permissions).
1478         $this->setUser($user2);
1479         try {
1480             $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1481             $this->fail('Exception expected due invalid user.');
1482         } catch (moodle_exception $e) {
1483             $this->assertEquals('accessdenied', $e->errorcode);
1484         }
1486     }
1488     /**
1489      * Test get_messages where we want all messages from a user, sent to any user.
1490      */
1491     public function test_get_messages_useridto_all() {
1492         $this->resetAfterTest(true);
1494         $user1 = self::getDataGenerator()->create_user();
1495         $user2 = self::getDataGenerator()->create_user();
1496         $user3 = self::getDataGenerator()->create_user();
1498         $this->setUser($user1);
1500         // Send a message from user 1 to two other users.
1501         $this->send_message($user1, $user2, 'some random text 1', 0, 1);
1502         $this->send_message($user1, $user3, 'some random text 2', 0, 2);
1504         // Get messages sent from user 1.
1505         $messages = core_message_external::get_messages(0, $user1->id, 'conversations', false, false, 0, 0);
1506         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1508         // Confirm the data is correct.
1509         $messages = $messages['messages'];
1510         $this->assertCount(2, $messages);
1512         $message1 = array_shift($messages);
1513         $message2 = array_shift($messages);
1515         $this->assertEquals($user1->id, $message1['useridfrom']);
1516         $this->assertEquals($user2->id, $message1['useridto']);
1518         $this->assertEquals($user1->id, $message2['useridfrom']);
1519         $this->assertEquals($user3->id, $message2['useridto']);
1520     }
1522     /**
1523      * Test get_messages where we want all messages to a user, sent by any user.
1524      */
1525     public function test_get_messages_useridfrom_all() {
1526         $this->resetAfterTest();
1528         $user1 = self::getDataGenerator()->create_user();
1529         $user2 = self::getDataGenerator()->create_user();
1530         $user3 = self::getDataGenerator()->create_user();
1532         $this->setUser($user1);
1534         // Send a message to user 1 from two other users.
1535         $this->send_message($user2, $user1, 'some random text 1', 0, 1);
1536         $this->send_message($user3, $user1, 'some random text 2', 0, 2);
1538         // Get messages sent to user 1.
1539         $messages = core_message_external::get_messages($user1->id, 0, 'conversations', false, false, 0, 0);
1540         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1542         // Confirm the data is correct.
1543         $messages = $messages['messages'];
1544         $this->assertCount(2, $messages);
1546         $message1 = array_shift($messages);
1547         $message2 = array_shift($messages);
1549         $this->assertEquals($user2->id, $message1['useridfrom']);
1550         $this->assertEquals($user1->id, $message1['useridto']);
1552         $this->assertEquals($user3->id, $message2['useridfrom']);
1553         $this->assertEquals($user1->id, $message2['useridto']);
1554     }
1556     /**
1557      * Test get_blocked_users.
1558      */
1559     public function test_get_blocked_users() {
1560         $this->resetAfterTest(true);
1562         $user1 = self::getDataGenerator()->create_user();
1563         $userstranger = self::getDataGenerator()->create_user();
1564         $useroffline1 = self::getDataGenerator()->create_user();
1565         $useroffline2 = self::getDataGenerator()->create_user();
1566         $userblocked = self::getDataGenerator()->create_user();
1568         // Login as user1.
1569         $this->setUser($user1);
1571         \core_message\api::add_contact($user1->id, $useroffline1->id);
1572         \core_message\api::add_contact($user1->id, $useroffline2->id);
1574         // The userstranger sends a couple of messages to user1.
1575         $this->send_message($userstranger, $user1, 'Hello there!');
1576         $this->send_message($userstranger, $user1, 'How you goin?');
1578         // The userblocked sends a message to user1.
1579         // Note that this user is not blocked at this point.
1580         $this->send_message($userblocked, $user1, 'Here, have some spam.');
1582         // Retrieve the list of blocked users.
1583         $this->setUser($user1);
1584         $blockedusers = core_message_external::get_blocked_users($user1->id);
1585         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1586         $this->assertCount(0, $blockedusers['users']);
1588         // Block the $userblocked and retrieve again the list.
1589         core_message_external::block_contacts(array($userblocked->id));
1590         $this->assertDebuggingCalled();
1591         $blockedusers = core_message_external::get_blocked_users($user1->id);
1592         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1593         $this->assertCount(1, $blockedusers['users']);
1595         // Remove the $userblocked and check that the list now is empty.
1596         delete_user($userblocked);
1597         $blockedusers = core_message_external::get_blocked_users($user1->id);
1598         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1599         $this->assertCount(0, $blockedusers['users']);
1600     }
1602     /**
1603      * Test mark_message_read.
1604      */
1605     public function test_mark_message_read() {
1606         $this->resetAfterTest(true);
1608         $user1 = self::getDataGenerator()->create_user();
1609         $user2 = self::getDataGenerator()->create_user();
1610         $user3 = self::getDataGenerator()->create_user();
1612         // Login as user1.
1613         $this->setUser($user1);
1614         \core_message\api::add_contact($user1->id, $user2->id);
1615         \core_message\api::add_contact($user1->id, $user3->id);
1617         // The user2 sends a couple of messages to user1.
1618         $this->send_message($user2, $user1, 'Hello there!');
1619         $this->send_message($user2, $user1, 'How you goin?');
1620         $this->send_message($user3, $user1, 'How you goin?');
1621         $this->send_message($user3, $user2, 'How you goin?');
1623         // Retrieve all messages sent by user2 (they are currently unread).
1624         $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
1626         $messageids = array();
1627         foreach ($lastmessages as $m) {
1628             $messageid = core_message_external::mark_message_read($m->id, time());
1629             $messageids[] = external_api::clean_returnvalue(core_message_external::mark_message_read_returns(), $messageid);
1630         }
1632         // Retrieve all messages sent (they are currently read).
1633         $lastmessages = message_get_messages($user1->id, $user2->id, 0, true);
1634         $this->assertCount(2, $lastmessages);
1635         $this->assertArrayHasKey($messageids[0]['messageid'], $lastmessages);
1636         $this->assertArrayHasKey($messageids[1]['messageid'], $lastmessages);
1638         // Retrieve all messages sent by any user (that are currently unread).
1639         $lastmessages = message_get_messages($user1->id, 0, 0, false);
1640         $this->assertCount(1, $lastmessages);
1642         // Invalid message ids.
1643         try {
1644             $messageid = core_message_external::mark_message_read(1337, time());
1645             $this->fail('Exception expected due invalid messageid.');
1646         } catch (dml_missing_record_exception $e) {
1647             $this->assertEquals('invalidrecordunknown', $e->errorcode);
1648         }
1650         // A message to a different user.
1651         $lastmessages = message_get_messages($user2->id, $user3->id, 0, false);
1652         $messageid = array_pop($lastmessages)->id;
1653         try {
1654             $messageid = core_message_external::mark_message_read($messageid, time());
1655             $this->fail('Exception expected due invalid messageid.');
1656         } catch (invalid_parameter_exception $e) {
1657             $this->assertEquals('invalidparameter', $e->errorcode);
1658         }
1659     }
1661     /**
1662      * Test mark_notification_read.
1663      */
1664     public function test_mark_notification_read() {
1665         $this->resetAfterTest(true);
1667         $user1 = self::getDataGenerator()->create_user();
1668         $user2 = self::getDataGenerator()->create_user();
1669         $user3 = self::getDataGenerator()->create_user();
1671         // Login as user1.
1672         $this->setUser($user1);
1673         \core_message\api::add_contact($user1->id, $user2->id);
1674         \core_message\api::add_contact($user1->id, $user3->id);
1676         // The user2 sends a couple of notifications to user1.
1677         $this->send_message($user2, $user1, 'Hello there!', 1);
1678         $this->send_message($user2, $user1, 'How you goin?', 1);
1679         $this->send_message($user3, $user1, 'How you goin?', 1);
1680         $this->send_message($user3, $user2, 'How you goin?', 1);
1682         // Retrieve all notifications sent by user2 (they are currently unread).
1683         $lastnotifications = message_get_messages($user1->id, $user2->id, 1, false);
1685         $notificationids = array();
1686         foreach ($lastnotifications as $n) {
1687             $notificationid = core_message_external::mark_notification_read($n->id, time());
1688             $notificationids[] = external_api::clean_returnvalue(core_message_external::mark_notification_read_returns(),
1689                 $notificationid);
1690         }
1692         // Retrieve all notifications sent (they are currently read).
1693         $lastnotifications = message_get_messages($user1->id, $user2->id, 1, true);
1694         $this->assertCount(2, $lastnotifications);
1695         $this->assertArrayHasKey($notificationids[1]['notificationid'], $lastnotifications);
1696         $this->assertArrayHasKey($notificationids[0]['notificationid'], $lastnotifications);
1698         // Retrieve all notifications sent by any user (that are currently unread).
1699         $lastnotifications = message_get_messages($user1->id, 0, 1, false);
1700         $this->assertCount(1, $lastnotifications);
1702         // Invalid notification ids.
1703         try {
1704             $notificationid = core_message_external::mark_notification_read(1337, time());
1705             $this->fail('Exception expected due invalid notificationid.');
1706         } catch (dml_missing_record_exception $e) {
1707             $this->assertEquals('invalidrecord', $e->errorcode);
1708         }
1710         // A notification to a different user.
1711         $lastnotifications = message_get_messages($user2->id, $user3->id, 1, false);
1712         $notificationid = array_pop($lastnotifications)->id;
1713         try {
1714             $notificationid = core_message_external::mark_notification_read($notificationid, time());
1715             $this->fail('Exception expected due invalid notificationid.');
1716         } catch (invalid_parameter_exception $e) {
1717             $this->assertEquals('invalidparameter', $e->errorcode);
1718         }
1719     }
1721     /**
1722      * Test delete_message.
1723      */
1724     public function test_delete_message() {
1725         global $DB;
1726         $this->resetAfterTest(true);
1728         $user1 = self::getDataGenerator()->create_user();
1729         $user2 = self::getDataGenerator()->create_user();
1730         $user3 = self::getDataGenerator()->create_user();
1731         $user4 = self::getDataGenerator()->create_user();
1733         // Login as user1.
1734         $this->setUser($user1);
1735         \core_message\api::add_contact($user1->id, $user2->id);
1736         \core_message\api::add_contact($user1->id, $user3->id);
1738         // User user1 does not interchange messages with user3.
1739         $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
1740         $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
1741         $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
1742         $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE);
1744         // Retrieve all messages sent by user2 (they are currently unread).
1745         $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
1747         // Delete a message not read, as a user from.
1748         $result = core_message_external::delete_message($m1to2, $user1->id, false);
1749         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1750         $this->assertTrue($result['status']);
1751         $this->assertCount(0, $result['warnings']);
1752         $mua = $DB->get_record('message_user_actions', array('messageid' => $m1to2, 'userid' => $user1->id));
1753         $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua->action);
1755         // Try to delete the same message again.
1756         $result = core_message_external::delete_message($m1to2, $user1->id, false);
1757         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1758         $this->assertFalse($result['status']);
1760         // Try to delete a message that does not belong to me.
1761         try {
1762             $messageid = core_message_external::delete_message($m2to3, $user3->id, false);
1763             $this->fail('Exception expected due invalid messageid.');
1764         } catch (moodle_exception $e) {
1765             $this->assertEquals('You do not have permission to delete this message', $e->errorcode);
1766         }
1768         $this->setUser($user3);
1769         // Delete a message not read, as a user to.
1770         $result = core_message_external::delete_message($m2to3, $user3->id, false);
1771         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1772         $this->assertTrue($result['status']);
1773         $this->assertCount(0, $result['warnings']);
1774         $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m2to3, 'userid' => $user3->id,
1775             'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
1777         // Delete a message read.
1778         $message = $DB->get_record('messages', ['id' => $m3to2]);
1779         \core_message\api::mark_message_as_read($user3->id, $message, time());
1780         $result = core_message_external::delete_message($m3to2, $user3->id);
1781         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1782         $this->assertTrue($result['status']);
1783         $this->assertCount(0, $result['warnings']);
1784         $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to2, 'userid' => $user3->id,
1785             'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
1787         // Invalid message ids.
1788         try {
1789             $result = core_message_external::delete_message(-1, $user1->id);
1790             $this->fail('Exception expected due invalid messageid.');
1791         } catch (dml_missing_record_exception $e) {
1792             $this->assertEquals('invalidrecord', $e->errorcode);
1793         }
1795         // Invalid user.
1796         try {
1797             $result = core_message_external::delete_message($m1to2, -1, false);
1798             $this->fail('Exception expected due invalid user.');
1799         } catch (moodle_exception $e) {
1800             $this->assertEquals('invaliduser', $e->errorcode);
1801         }
1803         // Not active user.
1804         delete_user($user2);
1805         try {
1806             $result = core_message_external::delete_message($m1to2, $user2->id, false);
1807             $this->fail('Exception expected due invalid user.');
1808         } catch (moodle_exception $e) {
1809             $this->assertEquals('userdeleted', $e->errorcode);
1810         }
1812         // Now, as an admin, try to delete any message.
1813         $this->setAdminUser();
1814         $result = core_message_external::delete_message($m3to4, $user4->id, false);
1815         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1816         $this->assertTrue($result['status']);
1817         $this->assertCount(0, $result['warnings']);
1818         $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to4, 'userid' => $user4->id,
1819             'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
1821     }
1823     public function test_mark_all_notifications_as_read_invalid_user_exception() {
1824         $this->resetAfterTest(true);
1826         $this->expectException('moodle_exception');
1827         core_message_external::mark_all_notifications_as_read(-2132131, 0);
1828     }
1830     public function test_mark_all_notifications_as_read_access_denied_exception() {
1831         $this->resetAfterTest(true);
1833         $sender = $this->getDataGenerator()->create_user();
1834         $user = $this->getDataGenerator()->create_user();
1836         $this->setUser($user);
1837         $this->expectException('moodle_exception');
1838         core_message_external::mark_all_notifications_as_read($sender->id, 0);
1839     }
1841     public function test_mark_all_notifications_as_read_missing_from_user_exception() {
1842         $this->resetAfterTest(true);
1844         $sender = $this->getDataGenerator()->create_user();
1846         $this->setUser($sender);
1847         $this->expectException('moodle_exception');
1848         core_message_external::mark_all_notifications_as_read($sender->id, 99999);
1849     }
1851     public function test_mark_all_notifications_as_read() {
1852         global $DB;
1854         $this->resetAfterTest(true);
1856         $sender1 = $this->getDataGenerator()->create_user();
1857         $sender2 = $this->getDataGenerator()->create_user();
1858         $sender3 = $this->getDataGenerator()->create_user();
1859         $recipient = $this->getDataGenerator()->create_user();
1861         $this->setUser($recipient);
1863         $this->send_message($sender1, $recipient, 'Notification', 1);
1864         $this->send_message($sender1, $recipient, 'Notification', 1);
1865         $this->send_message($sender2, $recipient, 'Notification', 1);
1866         $this->send_message($sender2, $recipient, 'Notification', 1);
1867         $this->send_message($sender3, $recipient, 'Notification', 1);
1868         $this->send_message($sender3, $recipient, 'Notification', 1);
1870         core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id);
1871         $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]);
1872         $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]);
1874         $this->assertCount(2, $readnotifications);
1875         $this->assertCount(4, $unreadnotifications);
1877         core_message_external::mark_all_notifications_as_read($recipient->id, 0);
1878         $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]);
1879         $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]);
1881         $this->assertCount(6, $readnotifications);
1882         $this->assertCount(0, $unreadnotifications);
1883     }
1885     /**
1886      * Test get_user_notification_preferences
1887      */
1888     public function test_get_user_notification_preferences() {
1889         $this->resetAfterTest(true);
1891         $user = self::getDataGenerator()->create_user();
1892         $this->setUser($user);
1894         // Set a couple of preferences to test.
1895         set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
1896         set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
1898         $prefs = core_message_external::get_user_notification_preferences();
1899         $prefs = external_api::clean_returnvalue(core_message_external::get_user_notification_preferences_returns(), $prefs);
1900         // Check processors.
1901         $this->assertGreaterThanOrEqual(2, count($prefs['preferences']['processors']));
1902         $this->assertEquals($user->id, $prefs['preferences']['userid']);
1904         // Check components.
1905         $this->assertGreaterThanOrEqual(8, count($prefs['preferences']['components']));
1907         // Check some preferences that we previously set.
1908         $found = 0;
1909         foreach ($prefs['preferences']['components'] as $component) {
1910             foreach ($component['notifications'] as $prefdata) {
1911                 if ($prefdata['preferencekey'] != 'message_provider_mod_assign_assign_notification') {
1912                     continue;
1913                 }
1914                 foreach ($prefdata['processors'] as $processor) {
1915                     if ($processor['name'] == 'popup') {
1916                         $this->assertTrue($processor['loggedin']['checked']);
1917                         $found++;
1918                     } else if ($processor['name'] == 'email') {
1919                         $this->assertTrue($processor['loggedoff']['checked']);
1920                         $found++;
1921                     }
1922                 }
1923             }
1924         }
1925         $this->assertEquals(2, $found);
1926     }
1928     /**
1929      * Test get_user_notification_preferences permissions
1930      */
1931     public function test_get_user_notification_preferences_permissions() {
1932         $this->resetAfterTest(true);
1934         $user = self::getDataGenerator()->create_user();
1935         $otheruser = self::getDataGenerator()->create_user();
1936         $this->setUser($user);
1938         $this->expectException('moodle_exception');
1939         $prefs = core_message_external::get_user_notification_preferences($otheruser->id);
1940     }
1942     /**
1943      * Tests searching users in a course.
1944      */
1945     public function test_data_for_messagearea_search_users_in_course() {
1946         $this->resetAfterTest(true);
1948         // Create some users.
1949         $user1 = new stdClass();
1950         $user1->firstname = 'User';
1951         $user1->lastname = 'One';
1952         $user1 = self::getDataGenerator()->create_user($user1);
1954         // The person doing the search.
1955         $this->setUser($user1);
1957         // Set the second user's status to online by setting their last access to now.
1958         $user2 = new stdClass();
1959         $user2->firstname = 'User';
1960         $user2->lastname = 'Two';
1961         $user2->lastaccess = time();
1962         $user2 = self::getDataGenerator()->create_user($user2);
1964         // Block the second user.
1965         \core_message\api::block_user($user1->id, $user2->id);
1967         $user3 = new stdClass();
1968         $user3->firstname = 'User';
1969         $user3->lastname = 'Three';
1970         $user3 = self::getDataGenerator()->create_user($user3);
1972         // Create a course.
1973         $course1 = new stdClass();
1974         $course1->fullname = 'Course';
1975         $course1->shortname = 'One';
1976         $course1 = $this->getDataGenerator()->create_course();
1978         // Enrol the user we are doing the search for and one user in the course.
1979         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1980         $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1982         // Perform a search.
1983         $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User');
1985         // We need to execute the return values cleaning process to simulate the web service.
1986         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(),
1987             $result);
1989         // Check that we only retrieved a user that was enrolled, and that the user performing the search was not returned.
1990         $users = $result['contacts'];
1991         $this->assertCount(1, $users);
1993         $user = $users[0];
1994         $this->assertEquals($user2->id, $user['userid']);
1995         $this->assertEquals(fullname($user2), $user['fullname']);
1996         $this->assertFalse($user['ismessaging']);
1997         $this->assertFalse($user['sentfromcurrentuser']);
1998         $this->assertNull($user['lastmessage']);
1999         $this->assertNull($user['messageid']);
2000         $this->assertNull($user['isonline']);
2001         $this->assertFalse($user['isread']);
2002         $this->assertTrue($user['isblocked']);
2003         $this->assertNull($user['unreadcount']);
2004     }
2006     /**
2007      * Tests searching users in course as another user.
2008      */
2009     public function test_data_for_messagearea_search_users_in_course_as_other_user() {
2010         $this->resetAfterTest(true);
2012         // The person doing the search for another user.
2013         $this->setAdminUser();
2015         // Create some users.
2016         $user1 = new stdClass();
2017         $user1->firstname = 'User';
2018         $user1->lastname = 'One';
2019         $user1 = self::getDataGenerator()->create_user($user1);
2021         $user2 = new stdClass();
2022         $user2->firstname = 'User';
2023         $user2->lastname = 'Two';
2024         $user2 = self::getDataGenerator()->create_user($user2);
2026         $user3 = new stdClass();
2027         $user3->firstname = 'User';
2028         $user3->lastname = 'Three';
2029         $user3 = self::getDataGenerator()->create_user($user3);
2031         // Create a course.
2032         $course1 = new stdClass();
2033         $course1->fullname = 'Course';
2034         $course1->shortname = 'One';
2035         $course1 = $this->getDataGenerator()->create_course();
2037         // Enrol the user we are doing the search for and one user in the course.
2038         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2039         $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2041         // Perform a search.
2042         $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User');
2044         // We need to execute the return values cleaning process to simulate the web service server.
2045         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(),
2046             $result);
2048         // Check that we got the user enrolled, and that the user we are performing the search on behalf of was not returned.
2049         $users = $result['contacts'];
2050         $this->assertCount(1, $users);
2052         $user = $users[0];
2053         $this->assertEquals($user2->id, $user['userid']);
2054         $this->assertEquals(fullname($user2), $user['fullname']);
2055         $this->assertFalse($user['ismessaging']);
2056         $this->assertFalse($user['sentfromcurrentuser']);
2057         $this->assertNull($user['lastmessage']);
2058         $this->assertNull($user['messageid']);
2059         $this->assertFalse($user['isonline']);
2060         $this->assertFalse($user['isread']);
2061         $this->assertFalse($user['isblocked']);
2062         $this->assertNull($user['unreadcount']);
2063     }
2065     /**
2066      * Tests searching users in course as another user without the proper capabilities.
2067      */
2068     public function test_data_for_messagearea_search_users_in_course_as_other_user_without_cap() {
2069         $this->resetAfterTest(true);
2071         // Create some users.
2072         $user1 = self::getDataGenerator()->create_user();
2073         $user2 = self::getDataGenerator()->create_user();
2075         // The person doing the search for another user.
2076         $this->setUser($user1);
2078         // Create a course.
2079         $course = $this->getDataGenerator()->create_course();
2081         // Ensure an exception is thrown.
2082         $this->expectException('moodle_exception');
2083         core_message_external::data_for_messagearea_search_users_in_course($user2->id, $course->id, 'User');
2084         $this->assertDebuggingCalled();
2085     }
2087     /**
2088      * Tests searching users in course with messaging disabled.
2089      */
2090     public function test_data_for_messagearea_search_users_in_course_messaging_disabled() {
2091         global $CFG;
2093         $this->resetAfterTest(true);
2095         // Create some skeleton data just so we can call the WS..
2096         $user = self::getDataGenerator()->create_user();
2097         $course = $this->getDataGenerator()->create_course();
2099         // The person doing the search for another user.
2100         $this->setUser($user);
2102         // Disable messaging.
2103         $CFG->messaging = 0;
2105         // Ensure an exception is thrown.
2106         $this->expectException('moodle_exception');
2107         core_message_external::data_for_messagearea_search_users_in_course($user->id, $course->id, 'User');
2108         $this->assertDebuggingCalled();
2109     }
2111     /**
2112      * Tests searching users.
2113      */
2114     public function test_data_for_messagearea_search_users() {
2115         $this->resetAfterTest(true);
2117         // Create some users.
2118         $user1 = new stdClass();
2119         $user1->firstname = 'User';
2120         $user1->lastname = 'One';
2121         $user1 = self::getDataGenerator()->create_user($user1);
2123         // Set as the user performing the search.
2124         $this->setUser($user1);
2126         $user2 = new stdClass();
2127         $user2->firstname = 'User search';
2128         $user2->lastname = 'Two';
2129         $user2 = self::getDataGenerator()->create_user($user2);
2131         $user3 = new stdClass();
2132         $user3->firstname = 'User search';
2133         $user3->lastname = 'Three';
2134         $user3 = self::getDataGenerator()->create_user($user3);
2136         $user4 = new stdClass();
2137         $user4->firstname = 'User';
2138         $user4->lastname = 'Four';
2139         $user4 = self::getDataGenerator()->create_user($user4);
2141         $user5 = new stdClass();
2142         $user5->firstname = 'User search';
2143         $user5->lastname = 'Five';
2144         $user5 = self::getDataGenerator()->create_user($user5);
2146         $user6 = new stdClass();
2147         $user6->firstname = 'User';
2148         $user6->lastname = 'Six';
2149         $user6 = self::getDataGenerator()->create_user($user6);
2151         // Create some courses.
2152         $course1 = new stdClass();
2153         $course1->fullname = 'Course search';
2154         $course1->shortname = 'One';
2155         $course1 = $this->getDataGenerator()->create_course($course1);
2157         $course2 = new stdClass();
2158         $course2->fullname = 'Course';
2159         $course2->shortname = 'Two';
2160         $course2 = $this->getDataGenerator()->create_course($course2);
2162         $course3 = new stdClass();
2163         $course3->fullname = 'Course';
2164         $course3->shortname = 'Three search';
2165         $course3 = $this->getDataGenerator()->create_course($course3);
2167         $course4 = new stdClass();
2168         $course4->fullname = 'Course Four';
2169         $course4->shortname = 'CF100';
2170         $course4 = $this->getDataGenerator()->create_course($course4);
2172         $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
2173         $this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'student');
2174         $this->getDataGenerator()->enrol_user($user1->id, $course3->id, 'student');
2176         // Add some users as contacts.
2177         \core_message\api::add_contact($user1->id, $user2->id);
2178         \core_message\api::add_contact($user1->id, $user3->id);
2179         \core_message\api::add_contact($user1->id, $user4->id);
2181         // Perform a search $CFG->messagingallusers setting enabled.
2182         set_config('messagingallusers', 1);
2183         $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
2185         // We need to execute the return values cleaning process to simulate the web service server.
2186         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(),
2187             $result);
2189         // Confirm that we returns contacts, courses and non-contacts.
2190         $contacts = $result['contacts'];
2191         $courses = $result['courses'];
2192         $noncontacts = $result['noncontacts'];
2194         // Check that we retrieved the correct contacts.
2195         $this->assertCount(2, $contacts);
2196         $this->assertEquals($user3->id, $contacts[0]['userid']);
2197         $this->assertEquals($user2->id, $contacts[1]['userid']);
2199         // Check that we retrieved the correct courses.
2200         $this->assertCount(2, $courses);
2201         $this->assertEquals($course3->id, $courses[0]['id']);
2202         $this->assertEquals($course1->id, $courses[1]['id']);
2204         // Check that we retrieved the correct non-contacts.
2205         $this->assertCount(1, $noncontacts);
2206         $this->assertEquals($user5->id, $noncontacts[0]['userid']);
2207     }
2209     /**
2210      * Tests searching users as another user.
2211      */
2212     public function test_data_for_messagearea_search_users_as_other_user() {
2213         $this->resetAfterTest(true);
2215         // The person doing the search.
2216         $this->setAdminUser();
2218         // Create some users.
2219         $user1 = new stdClass();
2220         $user1->firstname = 'User';
2221         $user1->lastname = 'One';
2222         $user1 = self::getDataGenerator()->create_user($user1);
2224         $user2 = new stdClass();
2225         $user2->firstname = 'User search';
2226         $user2->lastname = 'Two';
2227         $user2 = self::getDataGenerator()->create_user($user2);
2229         $user3 = new stdClass();
2230         $user3->firstname = 'User search';
2231         $user3->lastname = 'Three';
2232         $user3 = self::getDataGenerator()->create_user($user3);
2234         $user4 = new stdClass();
2235         $user4->firstname = 'User';
2236         $user4->lastname = 'Four';
2237         $user4 = self::getDataGenerator()->create_user($user4);
2239         $user5 = new stdClass();
2240         $user5->firstname = 'User search';
2241         $user5->lastname = 'Five';
2242         $user5 = self::getDataGenerator()->create_user($user5);
2244         $user6 = new stdClass();
2245         $user6->firstname = 'User';
2246         $user6->lastname = 'Six';
2247         $user6 = self::getDataGenerator()->create_user($user6);
2249         // Create some courses.
2250         $course1 = new stdClass();
2251         $course1->fullname = 'Course search';
2252         $course1->shortname = 'One';
2253         $course1 = $this->getDataGenerator()->create_course($course1);
2255         $course2 = new stdClass();
2256         $course2->fullname = 'Course';
2257         $course2->shortname = 'Two';
2258         $course2 = $this->getDataGenerator()->create_course($course2);
2260         $course3 = new stdClass();
2261         $course3->fullname = 'Course';
2262         $course3->shortname = 'Three search';
2263         $course3 = $this->getDataGenerator()->create_course($course3);
2265         // Add some users as contacts.
2266         \core_message\api::add_contact($user1->id, $user2->id);
2267         \core_message\api::add_contact($user1->id, $user3->id);
2268         \core_message\api::add_contact($user1->id, $user4->id);
2270         // Perform a search $CFG->messagingallusers setting enabled.
2271         set_config('messagingallusers', 1);
2272         $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
2274         // We need to execute the return values cleaning process to simulate the web service server.
2275         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(),
2276             $result);
2278         // Confirm that we returns contacts, courses and non-contacts.
2279         $contacts = $result['contacts'];
2280         $courses = $result['courses'];
2281         $noncontacts = $result['noncontacts'];
2283         // Check that we retrieved the correct contacts.
2284         $this->assertCount(2, $contacts);
2285         $this->assertEquals($user3->id, $contacts[0]['userid']);
2286         $this->assertEquals($user2->id, $contacts[1]['userid']);
2288         // Check that we retrieved the correct courses.
2289         $this->assertCount(0, $courses);
2291         // Check that we retrieved the correct non-contacts.
2292         $this->assertCount(1, $noncontacts);
2293         $this->assertEquals($user5->id, $noncontacts[0]['userid']);
2294     }
2296     /**
2297      * Tests searching users as another user without the proper capabilities.
2298      */
2299     public function test_data_for_messagearea_search_users_as_other_user_without_cap() {
2300         $this->resetAfterTest(true);
2302         // Create some users.
2303         $user1 = self::getDataGenerator()->create_user();
2304         $user2 = self::getDataGenerator()->create_user();
2306         // The person doing the search for another user.
2307         $this->setUser($user1);
2309         // Ensure an exception is thrown.
2310         $this->expectException('moodle_exception');
2311         core_message_external::data_for_messagearea_search_users($user2->id, 'User');
2312         $this->assertDebuggingCalled();
2313     }
2315     /**
2316      * Tests searching users with messaging disabled.
2317      */
2318     public function test_data_for_messagearea_search_users_messaging_disabled() {
2319         global $CFG;
2321         $this->resetAfterTest(true);
2323         // Create some skeleton data just so we can call the WS.
2324         $user = self::getDataGenerator()->create_user();
2326         // The person doing the search.
2327         $this->setUser($user);
2329         // Disable messaging.
2330         $CFG->messaging = 0;
2332         // Ensure an exception is thrown.
2333         $this->expectException('moodle_exception');
2334         core_message_external::data_for_messagearea_search_users($user->id, 'User');
2335         $this->assertDebuggingCalled();
2336     }
2338     /**
2339      * Tests searching for users when site-wide messaging is disabled.
2340      *
2341      * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
2342      * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
2343      * profile.
2344      */
2345     public function test_message_search_users_messagingallusers_disabled() {
2346         $this->resetAfterTest();
2348         // Create some users.
2349         $users = [];
2350         foreach (range(1, 7) as $i) {
2351             $user = new stdClass();
2352             $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2353             $user->lastname = $i;
2354             $user = $this->getDataGenerator()->create_user($user);
2355             $users[$i] = $user;
2356         }
2358         // Enrol a few users in the same course, but leave them as non-contacts.
2359         $course1 = $this->getDataGenerator()->create_course();
2360         $this->setAdminUser();
2361         $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2362         $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2363         $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
2365         // Add some other users as contacts.
2366         \core_message\api::add_contact($users[1]->id, $users[2]->id);
2367         \core_message\api::add_contact($users[3]->id, $users[1]->id);
2368         \core_message\api::add_contact($users[1]->id, $users[4]->id);
2370         // Create individual conversations between some users, one contact and one non-contact.
2371         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2372             [$users[1]->id, $users[2]->id]);
2373         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2374             [$users[6]->id, $users[1]->id]);
2376         // Create a group conversation between 4 users, including a contact and a non-contact.
2377         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2378             [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
2380         // Set as the user performing the search.
2381         $this->setUser($users[1]);
2383         // Perform a search with $CFG->messagingallusers disabled.
2384         set_config('messagingallusers', 0);
2385         $result = core_message_external::message_search_users($users[1]->id, 'search');
2386         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2388         // Confirm that we returns contacts and non-contacts.
2389         $this->assertArrayHasKey('contacts', $result);
2390         $this->assertArrayHasKey('noncontacts', $result);
2391         $contacts = $result['contacts'];
2392         $noncontacts = $result['noncontacts'];
2394         // Check that we retrieved the correct contacts.
2395         $this->assertCount(2, $contacts);
2396         $this->assertEquals($users[2]->id, $contacts[0]['id']);
2397         $this->assertEquals($users[3]->id, $contacts[1]['id']);
2399         // Verify the correct conversations were returned for the contacts.
2400         $this->assertCount(2, $contacts[0]['conversations']);
2401         // We can't rely on the ordering of conversations within the results, so sort by id first.
2402         usort($contacts[0]['conversations'], function($a, $b) {
2403             return $a['id'] < $b['id'];
2404         });
2405         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']);
2406         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']);
2408         $this->assertCount(0, $contacts[1]['conversations']);
2410         // Check that we retrieved the correct non-contacts.
2411         // When site wide messaging is disabled, we expect to see only those users whose profiles we can view.
2412         $this->assertCount(2, $noncontacts);
2413         $this->assertEquals($users[6]->id, $noncontacts[0]['id']);
2414         $this->assertEquals($users[7]->id, $noncontacts[1]['id']);
2416         // Verify the correct conversations were returned for the non-contacts.
2417         $this->assertCount(1, $noncontacts[0]['conversations']);
2418         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[0]['conversations'][0]['type']);
2420         $this->assertCount(1, $noncontacts[1]['conversations']);
2421         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[1]['conversations'][0]['type']);
2422     }
2424     /**
2425      * Tests searching for users when site-wide messaging is enabled.
2426      *
2427      * This test verifies that any contacts are returned, as well as any non-contacts, regardless of whether the searching user
2428      * can view their respective profile.
2429      */
2430     public function test_message_search_users_messagingallusers_enabled() {
2431         $this->resetAfterTest();
2433         // Create some users.
2434         $users = [];
2435         foreach (range(1, 8) as $i) {
2436             $user = new stdClass();
2437             $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2438             $user->lastname = $i;
2439             $user = $this->getDataGenerator()->create_user($user);
2440             $users[$i] = $user;
2441         }
2443         // Enrol a few users in the same course, but leave them as non-contacts.
2444         $course1 = $this->getDataGenerator()->create_course();
2445         $this->setAdminUser();
2446         $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2447         $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2448         $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
2450         // Add some other users as contacts.
2451         \core_message\api::add_contact($users[1]->id, $users[2]->id);
2452         \core_message\api::add_contact($users[3]->id, $users[1]->id);
2453         \core_message\api::add_contact($users[1]->id, $users[4]->id);
2455         // Create individual conversations between some users, one contact and one non-contact.
2456         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2457             [$users[1]->id, $users[2]->id]);
2458         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2459             [$users[6]->id, $users[1]->id]);
2461         // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
2462         \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2463             [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
2465         // Set as the user performing the search.
2466         $this->setUser($users[1]);
2468         // Perform a search with $CFG->messagingallusers enabled.
2469         set_config('messagingallusers', 1);
2470         $result = core_message_external::message_search_users($users[1]->id, 'search');
2471         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2473         // Confirm that we returns contacts and non-contacts.
2474         $this->assertArrayHasKey('contacts', $result);
2475         $this->assertArrayHasKey('noncontacts', $result);
2476         $contacts = $result['contacts'];
2477         $noncontacts = $result['noncontacts'];
2479         // Check that we retrieved the correct contacts.
2480         $this->assertCount(2, $contacts);
2481         $this->assertEquals($users[2]->id, $contacts[0]['id']);
2482         $this->assertEquals($users[3]->id, $contacts[1]['id']);
2484         // Verify the correct conversations were returned for the contacts.
2485         $this->assertCount(2, $contacts[0]['conversations']);
2486         // We can't rely on the ordering of conversations within the results, so sort by id first.
2487         usort($contacts[0]['conversations'], function($a, $b) {
2488             return $a['id'] < $b['id'];
2489         });
2490         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']);
2491         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']);
2493         $this->assertCount(0, $contacts[1]['conversations']);
2495         // Check that we retrieved the correct non-contacts.
2496         // If site wide messaging is enabled, we expect to be able to search for any users.
2497         $this->assertCount(4, $noncontacts);
2498         $this->assertEquals($users[5]->id, $noncontacts[0]['id']);
2499         $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2500         $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
2501         $this->assertEquals($users[8]->id, $noncontacts[3]['id']);
2503         // Verify the correct conversations were returned for the non-contacts.
2504         $this->assertCount(0, $noncontacts[0]['conversations']);
2506         $this->assertCount(1, $noncontacts[1]['conversations']);
2507         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[1]['conversations'][0]['type']);
2509         $this->assertCount(1, $noncontacts[2]['conversations']);
2510         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]['conversations'][0]['type']);
2512         $this->assertCount(1, $noncontacts[3]['conversations']);
2513         $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[3]['conversations'][0]['type']);
2514     }
2516     /**
2517      * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
2518      */
2519     public function test_message_search_users_with_empty_result() {
2520         $this->resetAfterTest();
2522         // Create some users, but make sure neither will match the search term.
2523         $user1 = new stdClass();
2524         $user1->firstname = 'User';
2525         $user1->lastname = 'One';
2526         $user1 = $this->getDataGenerator()->create_user($user1);
2527         $user2 = new stdClass();
2528         $user2->firstname = 'User';
2529         $user2->lastname = 'Two';
2530         $user2 = $this->getDataGenerator()->create_user($user2);
2532         // Perform a search as user1.
2533         $this->setUser($user1);
2534         $result = core_message_external::message_search_users($user1->id, 'search');
2535         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2537         // Check results are empty.
2538         $this->assertCount(0, $result['contacts']);
2539         $this->assertCount(0, $result['noncontacts']);
2540     }
2542     /**
2543      * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
2544      */
2545     public function test_message_search_users_limit_offset() {
2546         $this->resetAfterTest();
2548         // Create 20 users.
2549         $users = [];
2550         foreach (range(1, 20) as $i) {
2551             $user = new stdClass();
2552             $user->firstname = "User search";
2553             $user->lastname = $i;
2554             $user = $this->getDataGenerator()->create_user($user);
2555             $users[$i] = $user;
2556         }
2558         // Enrol the first 9 users in the same course, but leave them as non-contacts.
2559         $this->setAdminUser();
2560         $course1 = $this->getDataGenerator()->create_course();
2561         foreach (range(1, 9) as $i) {
2562             $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
2563         }
2565         // Add 5 users, starting at the 11th user, as contacts for user1.
2566         foreach (range(11, 15) as $i) {
2567             \core_message\api::add_contact($users[1]->id, $users[$i]->id);
2568         }
2570         // Set as the user performing the search.
2571         $this->setUser($users[1]);
2573         // Search using a limit of 3.
2574         // This tests the case where we have more results than the limit for both contacts and non-contacts.
2575         $result = core_message_external::message_search_users($users[1]->id, 'search', 0, 3);
2576         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2577         $contacts = $result['contacts'];
2578         $noncontacts = $result['noncontacts'];
2580         // Check that we retrieved the correct contacts.
2581         $this->assertCount(3, $contacts);
2582         $this->assertEquals($users[11]->id, $contacts[0]['id']);
2583         $this->assertEquals($users[12]->id, $contacts[1]['id']);
2584         $this->assertEquals($users[13]->id, $contacts[2]['id']);
2586         // Check that we retrieved the correct non-contacts.
2587         $this->assertCount(3, $noncontacts);
2588         $this->assertEquals($users[2]->id, $noncontacts[0]['id']);
2589         $this->assertEquals($users[3]->id, $noncontacts[1]['id']);
2590         $this->assertEquals($users[4]->id, $noncontacts[2]['id']);
2592         // Now, offset to get the next batch of results.
2593         // We expect to see 2 contacts, and 3 non-contacts.
2594         $result = core_message_external::message_search_users($users[1]->id, 'search', 3, 3);
2595         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2596         $contacts = $result['contacts'];
2597         $noncontacts = $result['noncontacts'];
2598         $this->assertCount(2, $contacts);
2599         $this->assertEquals($users[14]->id, $contacts[0]['id']);
2600         $this->assertEquals($users[15]->id, $contacts[1]['id']);
2602         $this->assertCount(3, $noncontacts);
2603         $this->assertEquals($users[5]->id, $noncontacts[0]['id']);
2604         $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2605         $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
2607         // Now, offset to get the next batch of results.
2608         // We expect to see 0 contacts, and 2 non-contacts.
2609         $result = core_message_external::message_search_users($users[1]->id, 'search', 6, 3);
2610         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2611         $contacts = $result['contacts'];
2612         $noncontacts = $result['noncontacts'];
2613         $this->assertCount(0, $contacts);
2615         $this->assertCount(2, $noncontacts);
2616         $this->assertEquals($users[8]->id, $noncontacts[0]['id']);
2617         $this->assertEquals($users[9]->id, $noncontacts[1]['id']);
2618     }
2620     /**
2621      * Tests searching users as another user having the 'moodle/user:viewdetails' capability.
2622      */
2623     public function test_message_search_users_with_cap() {
2624         $this->resetAfterTest();
2625         global $DB;
2627         // Create some users.
2628         $users = [];
2629         foreach (range(1, 8) as $i) {
2630             $user = new stdClass();
2631             $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2632             $user->lastname = $i;
2633             $user = $this->getDataGenerator()->create_user($user);
2634             $users[$i] = $user;
2635         }
2637         // Enrol a few users in the same course, but leave them as non-contacts.
2638         $course1 = $this->getDataGenerator()->create_course();
2639         $this->setAdminUser();
2640         $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2641         $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2642         $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
2644         // Add some other users as contacts.
2645         \core_message\api::add_contact($users[1]->id, $users[2]->id);
2646         \core_message\api::add_contact($users[3]->id, $users[1]->id);
2647         \core_message\api::add_contact($users[1]->id, $users[4]->id);
2649         // Set as the user performing the search.
2650         $this->setUser($users[1]);
2652         // Grant the authenticated user role the capability 'user:viewdetails' at site context.
2653         $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
2654         assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance());
2656         // Perform a search with $CFG->messagingallusers disabled.
2657         set_config('messagingallusers', 0);
2658         $result = core_message_external::message_search_users($users[1]->id, 'search');
2659         $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2660         $contacts = $result['contacts'];
2661         $noncontacts = $result['noncontacts'];
2663         // Check that we retrieved the correct contacts.
2664         $this->assertCount(2, $contacts);
2665         $this->assertEquals($users[2]->id, $contacts[0]['id']);
2666         $this->assertEquals($users[3]->id, $contacts[1]['id']);
2668         // Check that we retrieved the correct non-contacts.
2669         // Site-wide messaging is disabled, but since we can see all users, we expect to be able to search for any users.
2670         $this->assertCount(4, $noncontacts);
2671         $this->assertEquals($users[5]->id, $noncontacts[0]['id']);
2672         $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2673         $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
2674         $this->assertEquals($users[8]->id, $noncontacts[3]['id']);
2675     }
2677     /**
2678      * Tests searching users as another user without the 'moodle/user:viewdetails' capability.
2679      */
2680     public function test_message_search_users_without_cap() {
2681         $this->resetAfterTest();
2683         // Create some users.
2684         $user1 = $this->getDataGenerator()->create_user();
2685         $user2 = $this->getDataGenerator()->create_user();
2687         // The person doing the search for another user.
2688         $this->setUser($user1);
2690         // Ensure an exception is thrown.
2691         $this->expectException('moodle_exception');
2692         core_message_external::message_search_users($user2->id, 'User');
2693         $this->assertDebuggingCalled();
2694     }
2696     /**
2697      * Tests searching users with messaging disabled.
2698      */
2699     public function test_message_search_users_messaging_disabled() {
2700         $this->resetAfterTest();
2702         // Create some skeleton data just so we can call the WS.
2703         $user = $this->getDataGenerator()->create_user();
2705         // The person doing the search.
2706         $this->setUser($user);
2708         // Disable messaging.
2709         set_config('messaging', 0);
2711         // Ensure an exception is thrown.
2712         $this->expectException('moodle_exception');
2713         core_message_external::message_search_users($user->id, 'User');
2714     }
2716     /**
2717      * Tests searching messages.
2718      */
2719     public function test_messagearea_search_messages() {
2720         $this->resetAfterTest(true);
2722         // Create some users.
2723         $user1 = self::getDataGenerator()->create_user();
2724         $user2 = self::getDataGenerator()->create_user();
2726         // The person doing the search.
2727         $this->setUser($user1);
2729         // Send some messages back and forth.
2730         $time = time();
2731         $this->send_message($user1, $user2, 'Yo!', 0, $time);
2732         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
2733         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
2734         $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
2735         $convid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2737         // Perform a search.
2738         $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o');
2740         // We need to execute the return values cleaning process to simulate the web service server.
2741         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(), $result);
2743         // Confirm the data is correct.
2744         $messages = $result['contacts'];
2745         $this->assertCount(2, $messages);
2747         $message1 = $messages[0];
2748         $message2 = $messages[1];
2750         $this->assertEquals($user2->id, $message1['userid']);
2751         $this->assertEquals(fullname($user2), $message1['fullname']);
2752         $this->assertTrue($message1['ismessaging']);
2753         $this->assertFalse($message1['sentfromcurrentuser']);
2754         $this->assertEquals('Word.', $message1['lastmessage']);
2755         $this->assertNotEmpty($message1['messageid']);
2756         $this->assertNull($message1['isonline']);
2757         $this->assertFalse($message1['isread']);
2758         $this->assertFalse($message1['isblocked']);
2759         $this->assertNull($message1['unreadcount']);
2760         $this->assertEquals($convid, $message1['conversationid']);
2762         $this->assertEquals($user2->id, $message2['userid']);
2763         $this->assertEquals(fullname($user2), $message2['fullname']);
2764         $this->assertTrue($message2['ismessaging']);
2765         $this->assertTrue($message2['sentfromcurrentuser']);
2766         $this->assertEquals('Yo!', $message2['lastmessage']);
2767         $this->assertNotEmpty($message2['messageid']);
2768         $this->assertNull($message2['isonline']);
2769         $this->assertTrue($message2['isread']);
2770         $this->assertFalse($message2['isblocked']);
2771         $this->assertNull($message2['unreadcount']);
2772         $this->assertEquals($convid, $message2['conversationid']);
2773     }
2775     /**
2776      * Tests searching messages as another user.
2777      */
2778     public function test_messagearea_search_messages_as_other_user() {
2779         $this->resetAfterTest(true);
2781         // The person doing the search.
2782         $this->setAdminUser();
2784         // Create some users.
2785         $user1 = self::getDataGenerator()->create_user();
2786         $user2 = self::getDataGenerator()->create_user();
2788         // Send some messages back and forth.
2789         $time = time();
2790         $this->send_message($user1, $user2, 'Yo!', 0, $time);
2791         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
2792         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
2793         $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
2795         // Perform a search.
2796         $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o');
2798         // We need to execute the return values cleaning process to simulate the web service server.
2799         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(),
2800             $result);
2802         // Confirm the data is correct.
2803         $messages = $result['contacts'];
2804         $this->assertCount(2, $messages);
2806         $message1 = $messages[0];
2807         $message2 = $messages[1];
2809         $this->assertEquals($user2->id, $message1['userid']);
2810         $this->assertEquals(fullname($user2), $message1['fullname']);
2811         $this->assertTrue($message1['ismessaging']);
2812         $this->assertFalse($message1['sentfromcurrentuser']);
2813         $this->assertEquals('Word.', $message1['lastmessage']);
2814         $this->assertNotEmpty($message1['messageid']);
2815         $this->assertFalse($message1['isonline']);
2816         $this->assertFalse($message1['isread']);
2817         $this->assertFalse($message1['isblocked']);
2818         $this->assertNull($message1['unreadcount']);
2820         $this->assertEquals($user2->id, $message2['userid']);
2821         $this->assertEquals(fullname($user2), $message2['fullname']);
2822         $this->assertTrue($message2['ismessaging']);
2823         $this->assertTrue($message2['sentfromcurrentuser']);
2824         $this->assertEquals('Yo!', $message2['lastmessage']);
2825         $this->assertNotEmpty($message2['messageid']);
2826         $this->assertFalse($message2['isonline']);
2827         $this->assertTrue($message2['isread']);
2828         $this->assertFalse($message2['isblocked']);
2829         $this->assertNull($message2['unreadcount']);
2830     }
2832     /**
2833      * Tests searching messages as another user without the proper capabilities.
2834      */
2835     public function test_messagearea_search_messages_as_other_user_without_cap() {
2836         $this->resetAfterTest(true);
2838         // Create some users.
2839         $user1 = self::getDataGenerator()->create_user();
2840         $user2 = self::getDataGenerator()->create_user();
2842         // The person doing the search for another user.
2843         $this->setUser($user1);
2845         // Ensure an exception is thrown.
2846         $this->expectException('moodle_exception');
2847         core_message_external::data_for_messagearea_search_messages($user2->id, 'Search');
2848     }
2850     /**
2851      * Tests searching messages with messaging disabled
2852      */
2853     public function test_messagearea_search_messages_messaging_disabled() {
2854         global $CFG;
2856         $this->resetAfterTest(true);
2858         // Create some skeleton data just so we can call the WS.
2859         $user = self::getDataGenerator()->create_user();
2861         // The person doing the search .
2862         $this->setUser($user);
2864         // Disable messaging.
2865         $CFG->messaging = 0;
2867         // Ensure an exception is thrown.
2868         $this->expectException('moodle_exception');
2869         core_message_external::data_for_messagearea_search_messages($user->id, 'Search');
2870     }
2872     /**
2873      * Tests retrieving conversations.
2874      */
2875     public function test_messagearea_conversations() {
2876         $this->resetAfterTest(true);
2878         // Create some users.
2879         $user1 = self::getDataGenerator()->create_user();
2880         $user2 = self::getDataGenerator()->create_user();
2881         $user3 = self::getDataGenerator()->create_user();
2882         $user4 = self::getDataGenerator()->create_user();
2884         // The person retrieving the conversations.
2885         $this->setUser($user1);
2887         // Send some messages back and forth, have some different conversations with different users.
2888         $time = time();
2889         $this->send_message($user1, $user2, 'Yo!', 0, $time);
2890         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
2891         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
2892         $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
2894         $this->send_message($user1, $user3, 'Booyah', 0, $time + 4);
2895         $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5);
2896         $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6);
2897         $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7);
2899         $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8);
2900         $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9);
2901         $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10);
2903         // Retrieve the conversations.
2904         $result = core_message_external::data_for_messagearea_conversations($user1->id);
2906         // We need to execute the return values cleaning process to simulate the web service server.
2907         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(),
2908             $result);
2910         // Confirm the data is correct.
2911         $messages = $result['contacts'];
2912         $this->assertCount(3, $messages);
2914         $message1 = $messages[0];
2915         $message2 = $messages[1];
2916         $message3 = $messages[2];
2918         $this->assertEquals($user4->id, $message1['userid']);
2919         $this->assertTrue($message1['ismessaging']);
2920         $this->assertTrue($message1['sentfromcurrentuser']);
2921         $this->assertEquals('Dope.', $message1['lastmessage']);
2922         $this->assertEquals($messageid3, $message1['messageid']);
2923         $this->assertNull($message1['isonline']);
2924         $this->assertFalse($message1['isread']);
2925         $this->assertFalse($message1['isblocked']);
2926         $this->assertEquals(1, $message1['unreadcount']);
2928         $this->assertEquals($user3->id, $message2['userid']);
2929         $this->assertTrue($message2['ismessaging']);
2930         $this->assertFalse($message2['sentfromcurrentuser']);
2931         $this->assertEquals('Cool.', $message2['lastmessage']);
2932         $this->assertEquals($messageid2, $message2['messageid']);
2933         $this->assertNull($message2['isonline']);
2934         $this->assertFalse($message2['isread']);
2935         $this->assertFalse($message2['isblocked']);
2936         $this->assertEquals(2, $message2['unreadcount']);
2938         $this->assertEquals($user2->id, $message3['userid']);
2939         $this->assertTrue($message3['ismessaging']);
2940         $this->assertFalse($message3['sentfromcurrentuser']);
2941         $this->assertEquals('Word.', $message3['lastmessage']);
2942         $this->assertEquals($messageid1, $message3['messageid']);
2943         $this->assertNull($message3['isonline']);
2944         $this->assertFalse($message3['isread']);
2945         $this->assertFalse($message3['isblocked']);
2946         $this->assertEquals(2, $message3['unreadcount']);
2947     }
2949     /**
2950      * Tests retrieving conversations as another user.
2951      */
2952     public function test_messagearea_conversations_as_other_user() {
2953         $this->resetAfterTest(true);
2955         // Set as admin.
2956         $this->setAdminUser();
2958         // Create some users.
2959         $user1 = self::getDataGenerator()->create_user();
2960         $user2 = self::getDataGenerator()->create_user();
2961         $user3 = self::getDataGenerator()->create_user();
2962         $user4 = self::getDataGenerator()->create_user();
2964         // Send some messages back and forth, have some different conversations with different users.
2965         $time = time();
2966         $this->send_message($user1, $user2, 'Yo!', 0, $time);
2967         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
2968         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
2969         $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
2971         $this->send_message($user1, $user3, 'Booyah', 0, $time + 4);
2972         $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5);
2973         $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6);
2974         $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7);
2976         $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8);
2977         $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9);
2978         $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10);
2980         // Retrieve the conversations.
2981         $result = core_message_external::data_for_messagearea_conversations($user1->id);
2983         // We need to execute the return values cleaning process to simulate the web service server.
2984         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(),
2985             $result);
2987         // Confirm the data is correct.
2988         $messages = $result['contacts'];
2989         $this->assertCount(3, $messages);
2991         $message1 = $messages[0];
2992         $message2 = $messages[1];
2993         $message3 = $messages[2];
2995         $this->assertEquals($user4->id, $message1['userid']);
2996         $this->assertTrue($message1['ismessaging']);
2997         $this->assertTrue($message1['sentfromcurrentuser']);
2998         $this->assertEquals('Dope.', $message1['lastmessage']);
2999         $this->assertEquals($messageid3, $message1['messageid']);
3000         $this->assertFalse($message1['isonline']);
3001         $this->assertFalse($message1['isread']);
3002         $this->assertFalse($message1['isblocked']);
3003         $this->assertEquals(1, $message1['unreadcount']);
3005         $this->assertEquals($user3->id, $message2['userid']);
3006         $this->assertTrue($message2['ismessaging']);
3007         $this->assertFalse($message2['sentfromcurrentuser']);
3008         $this->assertEquals('Cool.', $message2['lastmessage']);
3009         $this->assertEquals($messageid2, $message2['messageid']);
3010         $this->assertFalse($message2['isonline']);
3011         $this->assertFalse($message2['isread']);
3012         $this->assertFalse($message2['isblocked']);
3013         $this->assertEquals(2, $message2['unreadcount']);
3015         $this->assertEquals($user2->id, $message3['userid']);
3016         $this->assertTrue($message3['ismessaging']);
3017         $this->assertFalse($message3['sentfromcurrentuser']);
3018         $this->assertEquals('Word.', $message3['lastmessage']);
3019         $this->assertEquals($messageid1, $message3['messageid']);
3020         $this->assertFalse($message3['isonline']);
3021         $this->assertFalse($message3['isread']);
3022         $this->assertFalse($message3['isblocked']);
3023         $this->assertEquals(2, $message3['unreadcount']);
3024     }
3026     /**
3027      * Tests retrieving conversations as another user without the proper capabilities.
3028      */
3029     public function test_messagearea_conversations_as_other_user_without_cap() {
3030         $this->resetAfterTest(true);
3032         // Create some users.
3033         $user1 = self::getDataGenerator()->create_user();
3034         $user2 = self::getDataGenerator()->create_user();
3036         // The person retrieving the conversations for another user.
3037         $this->setUser($user1);
3039         // Ensure an exception is thrown.
3040         $this->expectException('moodle_exception');
3041         core_message_external::data_for_messagearea_conversations($user2->id);
3042     }
3044     /**
3045      * Tests retrieving conversations with messaging disabled.
3046      */
3047     public function test_messagearea_conversations_messaging_disabled() {
3048         global $CFG;
3050         $this->resetAfterTest(true);
3052         // Create some skeleton data just so we can call the WS.
3053         $user = self::getDataGenerator()->create_user();
3055         // The person retrieving the conversations.
3056         $this->setUser($user);
3058         // Disable messaging.
3059         $CFG->messaging = 0;
3061         // Ensure an exception is thrown.
3062         $this->expectException('moodle_exception');
3063         core_message_external::data_for_messagearea_conversations($user->id);
3064     }
3066     /**
3067      * Tests retrieving contacts.
3068      */
3069     public function test_messagearea_contacts() {
3070         $this->resetAfterTest(true);
3072         // Create some users.
3073         $user1 = self::getDataGenerator()->create_user();
3075         // Set as the user.
3076         $this->setUser($user1);
3078         $user2 = new stdClass();
3079         $user2->firstname = 'User';
3080         $user2->lastname = 'A';
3081         $user2 = self::getDataGenerator()->create_user($user2);
3083         $user3 = new stdClass();
3084         $user3->firstname = 'User';
3085         $user3->lastname = 'B';
3086         $user3 = self::getDataGenerator()->create_user($user3);
3088         $user4 = new stdClass();
3089         $user4->firstname = 'User';
3090         $user4->lastname = 'C';
3091         $user4 = self::getDataGenerator()->create_user($user4);
3093         $user5 = new stdClass();
3094         $user5->firstname = 'User';
3095         $user5->lastname = 'D';
3096         $user5 = self::getDataGenerator()->create_user($user5);
3098         // Add some users as contacts.
3099         \core_message\api::add_contact($user1->id, $user2->id);
3100         \core_message\api::add_contact($user1->id, $user3->id);
3101         \core_message\api::add_contact($user1->id, $user4->id);
3103         // Retrieve the contacts.
3104         $result = core_message_external::data_for_messagearea_contacts($user1->id);
3106         // We need to execute the return values cleaning process to simulate the web service server.
3107         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(),
3108             $result);
3110         // Confirm the data is correct.
3111         $contacts = $result['contacts'];
3112         usort($contacts, ['static', 'sort_contacts']);
3113         $this->assertCount(3, $contacts);
3115         $contact1 = $contacts[0];
3116         $contact2 = $contacts[1];
3117         $contact3 = $contacts[2];
3119         $this->assertEquals($user2->id, $contact1['userid']);
3120         $this->assertFalse($contact1['ismessaging']);
3121         $this->assertFalse($contact1['sentfromcurrentuser']);
3122         $this->assertNull($contact1['lastmessage']);
3123         $this->assertNull($contact1['messageid']);
3124         $this->assertNull($contact1['isonline']);
3125         $this->assertFalse($contact1['isread']);
3126         $this->assertFalse($contact1['isblocked']);
3127         $this->assertNull($contact1['unreadcount']);
3129         $this->assertEquals($user3->id, $contact2['userid']);
3130         $this->assertFalse($contact2['ismessaging']);
3131         $this->assertFalse($contact2['sentfromcurrentuser']);
3132         $this->assertNull($contact2['lastmessage']);
3133         $this->assertNull($contact2['messageid']);
3134         $this->assertNull($contact2['isonline']);
3135         $this->assertFalse($contact2['isread']);
3136         $this->assertFalse($contact2['isblocked']);
3137         $this->assertNull($contact2['unreadcount']);
3139         $this->assertEquals($user4->id, $contact3['userid']);
3140         $this->assertFalse($contact3['ismessaging']);
3141         $this->assertFalse($contact3['sentfromcurrentuser']);
3142         $this->assertNull($contact3['lastmessage']);
3143         $this->assertNull($contact3['messageid']);
3144         $this->assertNull($contact3['isonline']);
3145         $this->assertFalse($contact3['isread']);
3146         $this->assertFalse($contact3['isblocked']);
3147         $this->assertNull($contact3['unreadcount']);
3148     }
3150     /**
3151      * Tests retrieving contacts as another user.
3152      */
3153     public function test_messagearea_contacts_as_other_user() {
3154         $this->resetAfterTest(true);
3156         $this->setAdminUser();
3158         // Create some users.
3159         $user1 = self::getDataGenerator()->create_user();
3161         $user2 = new stdClass();
3162         $user2->firstname = 'User';
3163         $user2->lastname = 'A';
3164         $user2 = self::getDataGenerator()->create_user($user2);
3166         $user3 = new stdClass();
3167         $user3->firstname = 'User';
3168         $user3->lastname = 'B';
3169         $user3 = self::getDataGenerator()->create_user($user3);
3171         $user4 = new stdClass();
3172         $user4->firstname = 'User';
3173         $user4->lastname = 'C';
3174         $user4 = self::getDataGenerator()->create_user($user4);
3176         $user5 = new stdClass();
3177         $user5->firstname = 'User';
3178         $user5->lastname = 'D';
3179         $user5 = self::getDataGenerator()->create_user($user5);
3181         // Add some users as contacts.
3182         \core_message\api::add_contact($user1->id, $user2->id);
3183         \core_message\api::add_contact($user1->id, $user3->id);
3184         \core_message\api::add_contact($user1->id, $user4->id);
3186         // Retrieve the contacts.
3187         $result = core_message_external::data_for_messagearea_contacts($user1->id);
3189         // We need to execute the return values cleaning process to simulate the web service server.
3190         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(),
3191             $result);
3193         // Confirm the data is correct.
3194         $contacts = $result['contacts'];
3195         usort($contacts, ['static', 'sort_contacts']);
3196         $this->assertCount(3, $contacts);
3198         $contact1 = $contacts[0];
3199         $contact2 = $contacts[1];
3200         $contact3 = $contacts[2];
3202         $this->assertEquals($user2->id, $contact1['userid']);
3203         $this->assertFalse($contact1['ismessaging']);
3204         $this->assertFalse($contact1['sentfromcurrentuser']);
3205         $this->assertNull($contact1['lastmessage']);
3206         $this->assertNull($contact1['messageid']);
3207         $this->assertFalse($contact1['isonline']);
3208         $this->assertFalse($contact1['isread']);
3209         $this->assertFalse($contact1['isblocked']);
3210         $this->assertNull($contact1['unreadcount']);
3212         $this->assertEquals($user3->id, $contact2['userid']);
3213         $this->assertFalse($contact2['ismessaging']);
3214         $this->assertFalse($contact2['sentfromcurrentuser']);
3215         $this->assertNull($contact2['lastmessage']);
3216         $this->assertNull($contact2['messageid']);
3217         $this->assertFalse($contact2['isonline']);
3218         $this->assertFalse($contact2['isread']);
3219         $this->assertFalse($contact2['isblocked']);
3220         $this->assertNull($contact2['unreadcount']);
3222         $this->assertEquals($user4->id, $contact3['userid']);
3223         $this->assertFalse($contact3['ismessaging']);
3224         $this->assertFalse($contact3['sentfromcurrentuser']);
3225         $this->assertNull($contact3['lastmessage']);
3226         $this->assertNull($contact3['messageid']);
3227         $this->assertFalse($contact3['isonline']);
3228         $this->assertFalse($contact3['isread']);
3229         $this->assertFalse($contact3['isblocked']);
3230         $this->assertNull($contact3['unreadcount']);
3231     }
3233     /**
3234      * Tests retrieving contacts as another user without the proper capabilities.
3235      */
3236     public function test_messagearea_contacts_as_other_user_without_cap() {
3237         $this->resetAfterTest(true);
3239         // Create some users.
3240         $user1 = self::getDataGenerator()->create_user();
3241         $user2 = self::getDataGenerator()->create_user();
3243         // The person retrieving the contacts for another user.
3244         $this->setUser($user1);
3246         // Perform the WS call and ensure an exception is thrown.
3247         $this->expectException('moodle_exception');
3248         core_message_external::data_for_messagearea_contacts($user2->id);
3249     }
3251     /**
3252      * Tests retrieving contacts with messaging disabled.
3253      */
3254     public function test_messagearea_contacts_messaging_disabled() {
3255         global $CFG;
3257         $this->resetAfterTest(true);
3259         // Create some skeleton data just so we can call the WS.
3260         $user = self::getDataGenerator()->create_user();
3262         // The person retrieving the contacts.
3263         $this->setUser($user);
3265         // Disable messaging.
3266         $CFG->messaging = 0;
3268         // Perform the WS call and ensure we are shown that it is disabled.
3269         $this->expectException('moodle_exception');
3270         core_message_external::data_for_messagearea_contacts($user->id);
3271     }
3273     /**
3274      * Tests retrieving contacts.
3275      */
3276     public function test_get_user_contacts() {
3277         $this->resetAfterTest(true);
3279         // Create some users.
3280         $user1 = self::getDataGenerator()->create_user();
3282         // Set as the user.
3283         $this->setUser($user1);
3285         $user2 = new stdClass();
3286         $user2->firstname = 'User';
3287         $user2->lastname = 'A';
3288         $user2 = self::getDataGenerator()->create_user($user2);
3290         $user3 = new stdClass();
3291         $user3->firstname = 'User';
3292         $user3->lastname = 'B';
3293         $user3 = self::getDataGenerator()->create_user($user3);
3295         $user4 = new stdClass();
3296         $user4->firstname = 'User';
3297         $user4->lastname = 'C';
3298         $user4 = self::getDataGenerator()->create_user($user4);
3300         $user5 = new stdClass();
3301         $user5->firstname = 'User';
3302         $user5->lastname = 'D';
3303         $user5 = self::getDataGenerator()->create_user($user5);
3305         // Add some users as contacts.
3306         \core_message\api::add_contact($user1->id, $user2->id);
3307         \core_message\api::add_contact($user1->id, $user3->id);
3308         \core_message\api::add_contact($user1->id, $user4->id);
3310         // Retrieve the contacts.
3311         $result = core_message_external::get_user_contacts($user1->id);
3313         // We need to execute the return values cleaning process to simulate the web service server.
3314         $result = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(),
3315             $result);
3317         // Confirm the data is correct.
3318         $contacts = $result;
3319         usort($contacts, ['static', 'sort_contacts_id']);
3320         $this->assertCount(3, $contacts);
3322         $contact1 = array_shift($contacts);
3323         $contact2 = array_shift($contacts);
3324         $contact3 = array_shift($contacts);
3326         $this->assertEquals($user2->id, $contact1['id']);
3327         $this->assertEquals(fullname($user2), $contact1['fullname']);
3328         $this->assertTrue($contact1['iscontact']);
3330         $this->assertEquals($user3->id, $contact2['id']);
3331         $this->assertEquals(fullname($user3), $contact2['fullname']);
3332         $this->assertTrue($contact2['iscontact']);
3334         $this->assertEquals($user4->id, $contact3['id']);
3335         $this->assertEquals(fullname($user4), $contact3['fullname']);
3336         $this->assertTrue($contact3['iscontact']);
3337     }
3339     /**
3340      * Tests retrieving contacts as another user.
3341      */
3342     public function test_get_user_contacts_as_other_user() {
3343         $this->resetAfterTest(true);
3345         $this->setAdminUser();
3347         // Create some users.
3348         $user1 = self::getDataGenerator()->create_user();
3350         $user2 = new stdClass();
3351         $user2->firstname = 'User';
3352         $user2->lastname = 'A';
3353         $user2 = self::getDataGenerator()->create_user($user2);
3355         $user3 = new stdClass();
3356         $user3->firstname = 'User';
3357         $user3->lastname = 'B';
3358         $user3 = self::getDataGenerator()->create_user($user3);
3360         $user4 = new stdClass();
3361         $user4->firstname = 'User';
3362         $user4->lastname = 'C';
3363         $user4 = self::getDataGenerator()->create_user($user4);
3365         $user5 = new stdClass();
3366         $user5->firstname = 'User';
3367         $user5->lastname = 'D';
3368         $user5 = self::getDataGenerator()->create_user($user5);
3370         // Add some users as contacts.
3371         \core_message\api::add_contact($user1->id, $user2->id);
3372         \core_message\api::add_contact($user1->id, $user3->id);
3373         \core_message\api::add_contact($user1->id, $user4->id);
3375         // Retrieve the contacts.
3376         $result = core_message_external::get_user_contacts($user1->id);
3378         // We need to execute the return values cleaning process to simulate the web service server.
3379         $result = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(),
3380             $result);
3382         // Confirm the data is correct.
3383         $contacts = $result;
3384         usort($contacts, ['static', 'sort_contacts_id']);
3385         $this->assertCount(3, $contacts);
3387         $contact1 = array_shift($contacts);
3388         $contact2 = array_shift($contacts);
3389         $contact3 = array_shift($contacts);
3391         $this->assertEquals($user2->id, $contact1['id']);
3392         $this->assertEquals(fullname($user2), $contact1['fullname']);
3393         $this->assertTrue($contact1['iscontact']);
3395         $this->assertEquals($user3->id, $contact2['id']);
3396         $this->assertEquals(fullname($user3), $contact2['fullname']);
3397         $this->assertTrue($contact2['iscontact']);
3399         $this->assertEquals($user4->id, $contact3['id']);
3400         $this->assertEquals(fullname($user4), $contact3['fullname']);
3401         $this->assertTrue($contact3['iscontact']);
3402     }
3404     /**
3405      * Tests retrieving contacts as another user without the proper capabilities.
3406      */
3407     public function test_get_user_contacts_as_other_user_without_cap() {
3408         $this->resetAfterTest(true);
3410         // Create some users.
3411         $user1 = self::getDataGenerator()->create_user();
3412         $user2 = self::getDataGenerator()->create_user();
3414         // The person retrieving the contacts for another user.
3415         $this->setUser($user1);
3417         // Perform the WS call and ensure an exception is thrown.
3418         $this->expectException('moodle_exception');
3419         core_message_external::get_user_contacts($user2->id);
3420     }
3422     /**
3423      * Tests retrieving contacts with messaging disabled.
3424      */
3425     public function test_get_user_contacts_messaging_disabled() {
3426         global $CFG;
3428         $this->resetAfterTest(true);
3430         // Create some skeleton data just so we can call the WS.
3431         $user = self::getDataGenerator()->create_user();
3433         // The person retrieving the contacts.
3434         $this->setUser($user);
3436         // Disable messaging.
3437         $CFG->messaging = 0;
3439         // Perform the WS call and ensure we are shown that it is disabled.
3440         $this->expectException('moodle_exception');
3441         core_message_external::get_user_contacts($user->id);
3442     }
3444     /**
3445      * Test getting contacts when there are no results.
3446      */
3447     public function test_get_user_contacts_no_results() {
3448         $this->resetAfterTest();
3450         $user1 = self::getDataGenerator()->create_user();
3452         $this->setUser($user1);
3454         $requests = core_message_external::get_user_contacts($user1->id);
3455         $requests = external_api::clean_returnvalue(core_message_external::get_user_contacts_returns(), $requests);
3457         $this->assertEmpty($requests);
3458     }
3460     /**
3461      * Tests retrieving messages.
3462      */
3463     public function test_messagearea_messages() {
3464         $this->resetAfterTest(true);
3466         // Create some users.
3467         $user1 = self::getDataGenerator()->create_user();
3468         $user2 = self::getDataGenerator()->create_user();
3470         // The person asking for the messages.
3471         $this->setUser($user1);
3473         // Send some messages back and forth.
3474         $time = time();
3475         $this->send_message($user1, $user2, 'Yo!', 0, $time);
3476         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3477         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
3478         $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
3480         // Retrieve the messages.
3481         $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id);
3483         // We need to execute the return values cleaning process to simulate the web service server.
3484         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(),
3485             $result);
3487         // Check the results are correct.
3488         $this->assertTrue($result['iscurrentuser']);
3489         $this->assertEquals($user1->id, $result['currentuserid']);
3490         $this->assertEquals($user2->id, $result['otheruserid']);
3491         $this->assertEquals(fullname($user2), $result['otheruserfullname']);
3492         $this->assertNull($result['isonline']);
3494         // Confirm the message data is correct.
3495         $messages = $result['messages'];
3496         $this->assertCount(4, $messages);
3498         $message1 = $messages[0];
3499         $message2 = $messages[1];
3500         $message3 = $messages[2];
3501         $message4 = $messages[3];
3503         $this->assertEquals($user1->id, $message1['useridfrom']);
3504         $this->assertEquals($user2->id, $message1['useridto']);
3505         $this->assertTrue($message1['displayblocktime']);
3506         $this->assertContains('Yo!', $message1['text']);
3508         $this->assertEquals($user2->id, $message2['useridfrom']);
3509         $this->assertEquals($user1->id, $message2['useridto']);
3510         $this->assertFalse($message2['displayblocktime']);
3511         $this->assertContains('Sup mang?', $message2['text']);
3513         $this->assertEquals($user1->id, $message3['useridfrom']);
3514         $this->assertEquals($user2->id, $message3['useridto']);
3515         $this->assertFalse($message3['displayblocktime']);
3516         $this->assertContains('Writing PHPUnit tests!', $message3['text']);
3518         $this->assertEquals($user2->id, $message4['useridfrom']);
3519         $this->assertEquals($user1->id, $message4['useridto']);
3520         $this->assertFalse($message4['displayblocktime']);
3521         $this->assertContains('Word.', $message4['text']);
3522     }
3524     /**
3525      * Tests retrieving messages.
3526      */
3527     public function test_messagearea_messages_timefrom() {
3528         $this->resetAfterTest(true);
3530         // Create some users.
3531         $user1 = self::getDataGenerator()->create_user();
3532         $user2 = self::getDataGenerator()->create_user();
3534         // The person asking for the messages.
3535         $this->setUser($user1);
3537         // Send some messages back and forth.
3538         $time = time();
3539         $this->send_message($user1, $user2, 'Message 1', 0, $time - 4);
3540         $this->send_message($user2, $user1, 'Message 2', 0, $time - 3);
3541         $this->send_message($user1, $user2, 'Message 3', 0, $time - 2);
3542         $this->send_message($user2, $user1, 'Message 4', 0, $time - 1);
3544         // Retrieve the messages from $time - 3, which should be the 3 most recent messages.
3545         $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id, 0, 0, false, $time - 3);
3547         // We need to execute the return values cleaning process to simulate the web service server.
3548         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(),
3549             $result);
3551         // Confirm the message data is correct. We shouldn't get 'Message 1' back.
3552         $messages = $result['messages'];
3553         $this->assertCount(3, $messages);
3555         $message1 = $messages[0];
3556         $message2 = $messages[1];
3557         $message3 = $messages[2];
3559         $this->assertContains('Message 2', $message1['text']);
3560         $this->assertContains('Message 3', $message2['text']);
3561         $this->assertContains('Message 4', $message3['text']);
3562     }
3564     /**
3565      * Tests retrieving messages as another user.
3566      */
3567     public function test_messagearea_messages_as_other_user() {
3568         $this->resetAfterTest(true);
3570         // Set as admin.
3571         $this->setAdminUser();
3573         // Create some users.
3574         $user1 = self::getDataGenerator()->create_user();
3575         $user2 = self::getDataGenerator()->create_user();
3577         // Send some messages back and forth.
3578         $time = time();
3579         $this->send_message($user1, $user2, 'Yo!', 0, $time);
3580         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3581         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
3582         $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
3584         // Retrieve the messages.
3585         $result = core_message_external::data_for_messagearea_messages($user1->id, $user2->id);
3587         // We need to execute the return values cleaning process to simulate the web service server.
3588         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_messages_returns(),
3589             $result);
3591         // Check the results are correct.
3592         $this->assertFalse($result['iscurrentuser']);
3593         $this->assertEquals($user1->id, $result['currentuserid']);
3594         $this->assertEquals($user2->id, $result['otheruserid']);
3595         $this->assertEquals(fullname($user2), $result['otheruserfullname']);
3596         $this->assertFalse($result['isonline']);
3598         // Confirm the message data is correct.
3599         $messages = $result['messages'];
3600         $this->assertCount(4, $messages);
3602         $message1 = $messages[0];
3603         $message2 = $messages[1];
3604         $message3 = $messages[2];
3605         $message4 = $messages[3];
3607         $this->assertEquals($user1->id, $message1['useridfrom']);
3608         $this->assertEquals($user2->id, $message1['useridto']);
3609         $this->assertTrue($message1['displayblocktime']);
3610         $this->assertContains('Yo!', $message1['text']);
3612         $this->assertEquals($user2->id, $message2['useridfrom']);
3613         $this->assertEquals($user1->id, $message2['useridto']);
3614         $this->assertFalse($message2['displayblocktime']);
3615         $this->assertContains('Sup mang?', $message2['text']);
3617         $this->assertEquals($user1->id, $message3['useridfrom']);
3618         $this->assertEquals($user2->id, $message3['useridto']);
3619         $this->assertFalse($message3['displayblocktime']);
3620         $this->assertContains('Writing PHPUnit tests!', $message3['text']);
3622         $this->assertEquals($user2->id, $message4['useridfrom']);
3623         $this->assertEquals($user1->id, $message4['useridto']);
3624         $this->assertFalse($message4['displayblocktime']);
3625         $this->assertContains('Word.', $message4['text']);
3626     }
3628     /**
3629      * Tests retrieving messages as another user without the proper capabilities.
3630      */
3631     public function test_messagearea_messages_as_other_user_without_cap() {
3632         $this->resetAfterTest(true);
3634         // Create some users.
3635         $user1 = self::getDataGenerator()->create_user();
3636         $user2 = self::getDataGenerator()->create_user();
3637         $user3 = self::getDataGenerator()->create_user();
3639         // The person asking for the messages for another user.
3640         $this->setUser($user1);
3642         // Ensure an exception is thrown.
3643         $this->expectException('moodle_exception');
3644         core_message_external::data_for_messagearea_messages($user2->id, $user3->id);
3645     }
3647     /**
3648      * Tests retrieving messages with messaging disabled.
3649      */
3650     public function test_messagearea_messages_messaging_disabled() {
3651         global $CFG;
3653         $this->resetAfterTest(true);
3655         // Create some skeleton data just so we can call the WS.
3656         $user1 = self::getDataGenerator()->create_user();
3657         $user2 = self::getDataGenerator()->create_user();
3659         // The person asking for the messages for another user.
3660         $this->setUser($user1);
3662         // Disable messaging.
3663         $CFG->messaging = 0;
3665         // Ensure an exception is thrown.
3666         $this->expectException('moodle_exception');
3667         core_message_external::data_for_messagearea_messages($user1->id, $user2->id);
3668     }
3670     /**
3671      * Tests get_conversation_messages for retrieving messages.
3672      */
3673     public function test_get_conversation_messages() {
3674         $this->resetAfterTest(true);
3676         // Create some users.
3677         $user1 = self::getDataGenerator()->create_user();
3678         $user2 = self::getDataGenerator()->create_user();
3679         $user3 = self::getDataGenerator()->create_user();
3680         $user4 = self::getDataGenerator()->create_user();
3681         $user5 = self::getDataGenerator()->create_user();
3683         // Create group conversation.
3684         $conversation = \core_message\api::create_conversation(
3685             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3686             [$user1->id, $user2->id, $user3->id, $user4->id]
3687         );
3689         // The person asking for the messages.
3690         $this->setUser($user1);
3692         // Send some messages back and forth.
3693         $time = time();
3694         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time);
3695         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Sup mang?', $time + 1);
3696         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Writing PHPUnit tests!', $time + 2);
3697         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 3);
3699         // Retrieve the messages.
3700         $result = core_message_external::get_conversation_messages($user1->id, $conversation->id);
3702         // We need to execute the return values cleaning process to simulate the web service server.
3703         $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(),
3704             $result);
3706         // Check the results are correct.
3707         $this->assertEquals($conversation->id, $result['id']);
3709         // Confirm the members data is correct.
3710         $members = $result['members'];
3711         $this->assertCount(3, $members);
3712         $membersid = [$members[0]['id'], $members[1]['id'], $members[2]['id']];
3713         $this->assertContains($user1->id, $membersid);
3714         $this->assertContains($user2->id, $membersid);
3715         $this->assertContains($user3->id, $membersid);
3717         $membersfullnames = [$members[0]['fullname'], $members[1]['fullname'], $members[2]['fullname']];
3718         $this->assertContains(fullname($user1), $membersfullnames);
3719         $this->assertContains(fullname($user2), $membersfullnames);
3720         $this->assertContains(fullname($user3), $membersfullnames);
3722         // Confirm the messages data is correct.
3723         $messages = $result['messages'];
3724         $this->assertCount(4, $messages);
3726         $message1 = $messages[0];
3727         $message2 = $messages[1];
3728         $message3 = $messages[2];
3729         $message4 = $messages[3];
3731         $this->assertEquals($user1->id, $message1['useridfrom']);
3732         $this->assertContains('Yo!', $message1['text']);
3734         $this->assertEquals($user3->id, $message2['useridfrom']);
3735         $this->assertContains('Sup mang?', $message2['text']);
3737         $this->assertEquals($user2->id, $message3['useridfrom']);
3738         $this->assertContains('Writing PHPUnit tests!', $message3['text']);
3740         $this->assertEquals($user1->id, $message4['useridfrom']);
3741         $this->assertContains('Word.', $message4['text']);
3742     }
3744     /**
3745      * Tests get_conversation_messages for retrieving messages using timefrom parameter.
3746      */
3747     public function test_get_conversation_messages_timefrom() {
3748         $this->resetAfterTest(true);
3750         // Create some users.
3751         $user1 = self::getDataGenerator()->create_user();
3752         $user2 = self::getDataGenerator()->create_user();
3753         $user3 = self::getDataGenerator()->create_user();
3754         $user4 = self::getDataGenerator()->create_user();
3756         // Create group conversation.
3757         $conversation = \core_message\api::create_conversation(
3758             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3759             [$user1->id, $user2->id, $user3->id]
3760         );
3762         // The person asking for the messages.
3763         $this->setUser($user1);
3765         // Send some messages back and forth.
3766         $time = time();
3767         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time - 4);
3768         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time - 3);
3769         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 3', $time - 2);
3770         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 4', $time - 1);
3772         // Retrieve the messages from $time - 3, which should be the 3 most recent messages.
3773         $result = core_message_external::get_conversation_messages($user1->id, $conversation->id, 0, 0, false, $time - 3);
3775         // We need to execute the return values cleaning process to simulate the web service server.
3776         $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(),
3777             $result);
3779         // Check the results are correct.
3780         $this->assertEquals($conversation->id, $result['id']);
3782         // Confirm the messages data is correct.
3783         $messages = $result['messages'];
3784         $this->assertCount(3, $messages);
3786         $message1 = $messages[0];
3787         $message2 = $messages[1];
3788         $message3 = $messages[2];
3790         $this->assertContains('Message 2', $message1['text']);
3791         $this->assertContains('Message 3', $message2['text']);
3792         $this->assertContains('Message 4', $message3['text']);
3794         // Confirm the members data is correct.
3795         $members = $result['members'];
3796         $this->assertCount(1, $members);
3797         $this->assertEquals($user2->id, $members[0]['id']);
3798     }
3800     /**
3801      * Tests get_conversation_messages for retrieving messages as another user.
3802      */
3803     public function test_get_conversation_messages_as_other_user() {
3804         $this->resetAfterTest(true);
3806         // Set as admin.
3807         $this->setAdminUser();
3809         // Create some users.
3810         $user1 = self::getDataGenerator()->create_user();
3811         $user2 = self::getDataGenerator()->create_user();
3812         $user3 = self::getDataGenerator()->create_user();
3813         $user4 = self::getDataGenerator()->create_user();
3815         // Create group conversation.
3816         $conversation = \core_message\api::create_conversation(
3817             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3818             [$user1->id, $user2->id, $user3->id, $user4->id]
3819         );
3821         // Send some messages back and forth.
3822         $time = time();
3823         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time);
3824         testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Sup mang?', $time + 1);
3825         testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Writing PHPUnit tests!', $time + 2);
3826         testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 3);
3828         // Retrieve the messages.
3829         $result = core_message_external::get_conversation_messages($user1->id, $conversation->id);
3831         // We need to execute the return values cleaning process to simulate the web service server.
3832         $result = external_api::clean_returnvalue(core_message_external::get_conversation_messages_returns(),
3833             $result);
3835         // Check the results are correct.
3836         $this->assertEquals($conversation->id, $result['id']);
3838         // Confirm the members data is correct.
3839         $members = $result['members'];
3840         $this->assertCount(3, $members);
3841         $membersid = [$members[0]['id'], $members[1]['id'], $members[2]['id']];
3842         $this->assertContains($user1->id, $membersid);
3843         $this->assertContains($user2->id, $membersid);
3844         $this->assertContains($user3->id, $membersid);
3846         // Confirm the message data is correct.
3847         $messages = $result['messages'];
3848         $this->assertCount(4, $messages);
3850         $message1 = $messages[0];
3851         $message2 = $messages[1];
3852         $message3 = $messages[2];
3853         $message4 = $messages[3];
3855         $this->assertEquals($user1->id, $message1['useridfrom']);
3856         $this->assertContains('Yo!', $message1['text']);
3858         $this->assertEquals($user3->id, $message2['useridfrom']);
3859         $this->assertContains('Sup mang?', $message2['text']);
3861         $this->assertEquals($user2->id, $message3['useridfrom']);
3862         $this->assertContains('Writing PHPUnit tests!', $message3['text']);
3864         $this->assertEquals($user1->id, $message4['useridfrom']);
3865         $this->assertContains('Word.', $message4['text']);
3866     }
3868     /**
3869      * Tests get_conversation_messages for retrieving messages as another user without the proper capabilities.
3870      */
3871     public function test_get_conversation_messages_as_other_user_without_cap() {
3872         $this->resetAfterTest(true);
3874         // Create some users.
3875         $user1 = self::getDataGenerator()->create_user();
3876         $user2 = self::getDataGenerator()->create_user();
3877         $user3 = self::getDataGenerator()->create_user();
3878         $user4 = self::getDataGenerator()->create_user();
3880         // Create group conversation.
3881         $conversation = \core_message\api::create_conversation(
3882             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3883             [$user1->id, $user2->id, $user3->id, $user4->id]
3884         );
3886         // The person asking for the messages for another user.
3887         $this->setUser($user1);
3889         // Ensure an exception is thrown.
3890         $this->expectException('moodle_exception');
3891         core_message_external::get_conversation_messages($user2->id, $conversation->id);
3892     }
3894     /**
3895      * Tests get_conversation_messages for retrieving messages with messaging disabled.
3896      */
3897     public function test_get_conversation_messages_messaging_disabled() {
3898         $this->resetAfterTest(true);
3900         // Create some skeleton data just so we can call the WS.
3901         $user1 = self::getDataGenerator()->create_user();
3902         $user2 = self::getDataGenerator()->create_user();
3903         $user3 = self::getDataGenerator()->create_user();
3904         $user4 = self::getDataGenerator()->create_user();
3906         // Create group conversation.
3907         $conversation = \core_message\api::create_conversation(
3908             \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3909             [$user1->id, $user2->id, $user3->id, $user4->id]
3910         );
3912         // The person asking for the messages for another user.
3913         $this->setUser($user1);
3915         // Disable messaging.
3916         set_config('messaging', 0);
3918         // Ensure an exception is thrown.
3919         $this->expectException('moodle_exception');
3920         core_message_external::get_conversation_messages($user1->id, $conversation->id);
3921     }
3923     /**
3924      * Tests retrieving most recent message.
3925      */
3926     public function test_messagearea_get_most_recent_message() {
3927         $this->resetAfterTest(true);
3929         // Create some users.
3930         $user1 = self::getDataGenerator()->create_user();
3931         $user2 = self::getDataGenerator()->create_user();
3933         // The person doing the search.
3934         $this->setUser($user1);
3936         // Send some messages back and forth.
3937         $time = time();
3938         $this->send_message($user1, $user2, 'Yo!', 0, $time);
3939         $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3940         $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
3941         $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
3943         // Get the most recent message.
3944         $result = core_message_external::data_for_messagearea_get_most_recent_message($user1->id, $user2->id);
3946         // We need to execute the return values cleaning process to simulate the web service server.
3947         $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_get_most_recent_message_returns(),
3948             $result);
3950         // Check the results are correct.
3951         $this->assertEquals($user2->id, $result['useridfrom']);
3952         $this->assertEquals($user1->id, $result['useridto']);
3953         $this->assertContains('Word.', $result['text']);
3954     }
3956     /**
3957      * Tests retrieving most recent message as another user.
3958      */