8827f0176fe63b0d69e9e0f1f8c059ef8b5d8aca
[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 class core_message_externallib_testcase extends externallib_advanced_testcase {
35     /**
36      * Tests set up
37      */
38     protected function setUp() {
39         global $CFG;
41         require_once($CFG->dirroot . '/message/lib.php');
42     }
44     /**
45      * Send a fake message.
46      *
47      * {@link message_send()} does not support transaction, this function will simulate a message
48      * sent from a user to another. We should stop using it once {@link message_send()} will support
49      * transactions. This is not clean at all, this is just used to add rows to the table.
50      *
51      * @param stdClass $userfrom user object of the one sending the message.
52      * @param stdClass $userto user object of the one receiving the message.
53      * @param string $message message to send.
54      */
55     protected function send_message($userfrom, $userto, $message = 'Hello world!') {
56         global $DB;
57         $record = new stdClass();
58         $record->useridfrom = $userfrom->id;
59         $record->useridto = $userto->id;
60         $record->subject = 'No subject';
61         $record->fullmessage = $message;
62         $record->timecreated = time();
63         $insert = $DB->insert_record('message', $record);
64     }
66     /**
67      * Send a fake unread popup notification.
68      *
69      * {@link message_send()} does not support transaction, this function will simulate a message
70      * sent from a user to another. We should stop using it once {@link message_send()} will support
71      * transactions. This is not clean at all, this is just used to add rows to the table.
72      *
73      * @param stdClass $userfrom user object of the one sending the message.
74      * @param stdClass $userto user object of the one receiving the message.
75      * @param string $message message to send.
76      * @param int $timecreated time the message was created.
77      * @return int the id of the message
78      */
79     protected function send_fake_unread_popup_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0) {
80         global $DB;
82         $record = new stdClass();
83         $record->useridfrom = $userfrom->id;
84         $record->useridto = $userto->id;
85         $record->notification = 1;
86         $record->subject = 'No subject';
87         $record->fullmessage = $message;
88         $record->smallmessage = $message;
89         $record->timecreated = $timecreated ? $timecreated : time();
91         $id = $DB->insert_record('message', $record);
93         $popup = new stdClass();
94         $popup->messageid = $id;
95         $popup->isread = 0;
97         $DB->insert_record('message_popup', $popup);
99         return $id;
100     }
102     /**
103      * Send a fake read popup notification.
104      *
105      * {@link message_send()} does not support transaction, this function will simulate a message
106      * sent from a user to another. We should stop using it once {@link message_send()} will support
107      * transactions. This is not clean at all, this is just used to add rows to the table.
108      *
109      * @param stdClass $userfrom user object of the one sending the message.
110      * @param stdClass $userto user object of the one receiving the message.
111      * @param string $message message to send.
112      * @param int $timecreated time the message was created.
113      * @return int the id of the message
114      */
115     protected function send_fake_read_popup_notification($userfrom, $userto, $message = 'Hello world!', $timecreated = 0, $timeread = 0) {
116         global $DB;
118         $record = new stdClass();
119         $record->useridfrom = $userfrom->id;
120         $record->useridto = $userto->id;
121         $record->notification = 1;
122         $record->subject = 'No subject';
123         $record->fullmessage = $message;
124         $record->smallmessage = $message;
125         $record->timecreated = $timecreated ? $timecreated : time();
126         $record->timeread = $timeread ? $timeread : time();
128         $id = $DB->insert_record('message_read', $record);
130         $popup = new stdClass();
131         $popup->messageid = $id;
132         $popup->isread = 1;
134         $DB->insert_record('message_popup', $popup);
136         return $id;
137     }
139     /**
140      * Test send_instant_messages
141      */
142     public function test_send_instant_messages() {
144         global $DB, $USER, $CFG;
146         $this->resetAfterTest(true);
147         // Transactions used in tests, tell phpunit use alternative reset method.
148         $this->preventResetByRollback();
150         // Turn off all message processors (so nothing is really sent)
151         require_once($CFG->dirroot . '/message/lib.php');
152         $messageprocessors = get_message_processors();
153         foreach($messageprocessors as $messageprocessor) {
154             $messageprocessor->enabled = 0;
155             $DB->update_record('message_processors', $messageprocessor);
156         }
158         // Set the required capabilities by the external function
159         $contextid = context_system::instance()->id;
160         $roleid = $this->assignUserCapability('moodle/site:sendmessage', $contextid);
162         $user1 = self::getDataGenerator()->create_user();
164         // Create test message data.
165         $message1 = array();
166         $message1['touserid'] = $user1->id;
167         $message1['text'] = 'the message.';
168         $message1['clientmsgid'] = 4;
169         $messages = array($message1);
171         $sentmessages = core_message_external::send_instant_messages($messages);
173         // We need to execute the return values cleaning process to simulate the web service server.
174         $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
176         $themessage = $DB->get_record('message', array('id' => $sentmessages[0]['msgid']));
178         // Confirm that the message was inserted correctly.
179         $this->assertEquals($themessage->useridfrom, $USER->id);
180         $this->assertEquals($themessage->useridto, $message1['touserid']);
181         $this->assertEquals($themessage->smallmessage, $message1['text']);
182         $this->assertEquals($sentmessages[0]['clientmsgid'], $message1['clientmsgid']);
183     }
185     /**
186      * Test create_contacts.
187      */
188     public function test_create_contacts() {
189         $this->resetAfterTest(true);
191         $user1 = self::getDataGenerator()->create_user();
192         $user2 = self::getDataGenerator()->create_user();
193         $user3 = self::getDataGenerator()->create_user();
194         $user4 = self::getDataGenerator()->create_user();
195         $user5 = self::getDataGenerator()->create_user();
196         $this->setUser($user1);
198         // Adding a contact.
199         $return = core_message_external::create_contacts(array($user2->id));
200         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
201         $this->assertEquals(array(), $return);
203         // Adding a contact who is already a contact.
204         $return = core_message_external::create_contacts(array($user2->id));
205         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
206         $this->assertEquals(array(), $return);
208         // Adding multiple contacts.
209         $return = core_message_external::create_contacts(array($user3->id, $user4->id));
210         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
211         $this->assertEquals(array(), $return);
213         // Adding a non-existing user.
214         $return = core_message_external::create_contacts(array(99999));
215         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
216         $this->assertCount(1, $return);
217         $return = array_pop($return);
218         $this->assertEquals($return['warningcode'], 'contactnotcreated');
219         $this->assertEquals($return['itemid'], 99999);
221         // Adding contacts with valid and invalid parameters.
222         $return = core_message_external::create_contacts(array($user5->id, 99999));
223         $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
224         $this->assertCount(1, $return);
225         $return = array_pop($return);
226         $this->assertEquals($return['warningcode'], 'contactnotcreated');
227         $this->assertEquals($return['itemid'], 99999);
228     }
230     /**
231      * Test delete_contacts.
232      */
233     public function test_delete_contacts() {
234         $this->resetAfterTest(true);
236         $user1 = self::getDataGenerator()->create_user();
237         $user2 = self::getDataGenerator()->create_user();
238         $user3 = self::getDataGenerator()->create_user();
239         $user4 = self::getDataGenerator()->create_user();
240         $user5 = self::getDataGenerator()->create_user();
241         $user6 = self::getDataGenerator()->create_user();
242         $this->setUser($user1);
243         $this->assertEquals(array(), core_message_external::create_contacts(
244             array($user3->id, $user4->id, $user5->id, $user6->id)));
246         // Removing a non-contact.
247         $return = core_message_external::delete_contacts(array($user2->id));
248         $this->assertNull($return);
250         // Removing one contact.
251         $return = core_message_external::delete_contacts(array($user3->id));
252         $this->assertNull($return);
254         // Removing multiple contacts.
255         $return = core_message_external::delete_contacts(array($user4->id, $user5->id));
256         $this->assertNull($return);
258         // Removing contact from unexisting user.
259         $return = core_message_external::delete_contacts(array(99999));
260         $this->assertNull($return);
262         // Removing mixed valid and invalid data.
263         $return = core_message_external::delete_contacts(array($user6->id, 99999));
264         $this->assertNull($return);
265     }
267     /**
268      * Test block_contacts.
269      */
270     public function test_block_contacts() {
271         $this->resetAfterTest(true);
273         $user1 = self::getDataGenerator()->create_user();
274         $user2 = self::getDataGenerator()->create_user();
275         $user3 = self::getDataGenerator()->create_user();
276         $user4 = self::getDataGenerator()->create_user();
277         $user5 = self::getDataGenerator()->create_user();
278         $this->setUser($user1);
279         $this->assertEquals(array(), core_message_external::create_contacts(array($user3->id, $user4->id, $user5->id)));
281         // Blocking a contact.
282         $return = core_message_external::block_contacts(array($user2->id));
283         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
284         $this->assertEquals(array(), $return);
286         // Blocking a contact who is already a contact.
287         $return = core_message_external::block_contacts(array($user2->id));
288         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
289         $this->assertEquals(array(), $return);
291         // Blocking multiple contacts.
292         $return = core_message_external::block_contacts(array($user3->id, $user4->id));
293         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
294         $this->assertEquals(array(), $return);
296         // Blocking a non-existing user.
297         $return = core_message_external::block_contacts(array(99999));
298         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
299         $this->assertCount(1, $return);
300         $return = array_pop($return);
301         $this->assertEquals($return['warningcode'], 'contactnotblocked');
302         $this->assertEquals($return['itemid'], 99999);
304         // Blocking contacts with valid and invalid parameters.
305         $return = core_message_external::block_contacts(array($user5->id, 99999));
306         $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
307         $this->assertCount(1, $return);
308         $return = array_pop($return);
309         $this->assertEquals($return['warningcode'], 'contactnotblocked');
310         $this->assertEquals($return['itemid'], 99999);
311     }
313     /**
314      * Test unblock_contacts.
315      */
316     public function test_unblock_contacts() {
317         $this->resetAfterTest(true);
319         $user1 = self::getDataGenerator()->create_user();
320         $user2 = self::getDataGenerator()->create_user();
321         $user3 = self::getDataGenerator()->create_user();
322         $user4 = self::getDataGenerator()->create_user();
323         $user5 = self::getDataGenerator()->create_user();
324         $user6 = self::getDataGenerator()->create_user();
325         $this->setUser($user1);
326         $this->assertEquals(array(), core_message_external::create_contacts(
327             array($user3->id, $user4->id, $user5->id, $user6->id)));
329         // Removing a non-contact.
330         $return = core_message_external::unblock_contacts(array($user2->id));
331         $this->assertNull($return);
333         // Removing one contact.
334         $return = core_message_external::unblock_contacts(array($user3->id));
335         $this->assertNull($return);
337         // Removing multiple contacts.
338         $return = core_message_external::unblock_contacts(array($user4->id, $user5->id));
339         $this->assertNull($return);
341         // Removing contact from unexisting user.
342         $return = core_message_external::unblock_contacts(array(99999));
343         $this->assertNull($return);
345         // Removing mixed valid and invalid data.
346         $return = core_message_external::unblock_contacts(array($user6->id, 99999));
347         $this->assertNull($return);
349     }
351     /**
352      * Test get_contacts.
353      */
354     public function test_get_contacts() {
355         $this->resetAfterTest(true);
357         $user1 = self::getDataGenerator()->create_user();
358         $user_stranger = self::getDataGenerator()->create_user();
359         $user_offline1 = self::getDataGenerator()->create_user();
360         $user_offline2 = self::getDataGenerator()->create_user();
361         $user_offline3 = self::getDataGenerator()->create_user();
362         $user_online = new stdClass();
363         $user_online->lastaccess = time();
364         $user_online = self::getDataGenerator()->create_user($user_online);
365         $user_blocked = self::getDataGenerator()->create_user();
366         $noreplyuser = core_user::get_user(core_user::NOREPLY_USER);
368         // Login as user1.
369         $this->setUser($user1);
370         $this->assertEquals(array(), core_message_external::create_contacts(
371             array($user_offline1->id, $user_offline2->id, $user_offline3->id, $user_online->id)));
373         // User_stranger sends a couple of messages to user1.
374         $this->send_message($user_stranger, $user1, 'Hello there!');
375         $this->send_message($user_stranger, $user1, 'How you goin?');
376         $this->send_message($user_stranger, $user1, 'Cya!');
377         $this->send_message($noreplyuser, $user1, 'I am not a real user');
379         // User_blocked sends a message to user1.
380         $this->send_message($user_blocked, $user1, 'Here, have some spam.');
382         // Retrieve the contacts of the user.
383         $this->setUser($user1);
384         $contacts = core_message_external::get_contacts();
385         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
386         $this->assertCount(3, $contacts['offline']);
387         $this->assertCount(1, $contacts['online']);
388         $this->assertCount(3, $contacts['strangers']);
389         core_message_external::block_contacts(array($user_blocked->id));
390         $contacts = core_message_external::get_contacts();
391         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
392         $this->assertCount(3, $contacts['offline']);
393         $this->assertCount(1, $contacts['online']);
394         $this->assertCount(2, $contacts['strangers']);
396         // Checking some of the fields returned.
397         $stranger = array_pop($contacts['strangers']);
399         $this->assertEquals(core_user::NOREPLY_USER, $stranger['id']);
400         $this->assertEquals(1, $stranger['unread']);
402         // Check that deleted users are not returned.
403         delete_user($user_offline1);
404         delete_user($user_stranger);
405         delete_user($user_online);
406         $contacts = core_message_external::get_contacts();
407         $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
408         $this->assertCount(2, $contacts['offline']);
409         $this->assertCount(0, $contacts['online']);
410         $this->assertCount(1, $contacts['strangers']);
411     }
413     /**
414      * Test search_contacts.
415      * @expectedException moodle_exception
416      */
417     public function test_search_contacts() {
418         global $DB;
419         $this->resetAfterTest(true);
421         $course1 = $this->getDataGenerator()->create_course();
422         $course2 = $this->getDataGenerator()->create_course();
424         $user1 = new stdClass();
425         $user1->firstname = 'X';
426         $user1->lastname = 'X';
427         $user1 = $this->getDataGenerator()->create_user($user1);
428         $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
429         $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
431         $user2 = new stdClass();
432         $user2->firstname = 'Eric';
433         $user2->lastname = 'Cartman';
434         $user2 = self::getDataGenerator()->create_user($user2);
435         $user3 = new stdClass();
436         $user3->firstname = 'Stan';
437         $user3->lastname = 'Marsh';
438         $user3 = self::getDataGenerator()->create_user($user3);
439         self::getDataGenerator()->enrol_user($user3->id, $course1->id);
440         $user4 = new stdClass();
441         $user4->firstname = 'Kyle';
442         $user4->lastname = 'Broflovski';
443         $user4 = self::getDataGenerator()->create_user($user4);
444         $user5 = new stdClass();
445         $user5->firstname = 'Kenny';
446         $user5->lastname = 'McCormick';
447         $user5 = self::getDataGenerator()->create_user($user5);
448         self::getDataGenerator()->enrol_user($user5->id, $course2->id);
450         $this->setUser($user1);
452         $results = core_message_external::search_contacts('r');
453         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
454         $this->assertCount(5, $results); // Users 2 through 5 + admin
456         $results = core_message_external::search_contacts('r', true);
457         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
458         $this->assertCount(2, $results);
460         $results = core_message_external::search_contacts('Kyle', false);
461         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
462         $this->assertCount(1, $results);
463         $result = reset($results);
464         $this->assertEquals($user4->id, $result['id']);
466         $results = core_message_external::search_contacts('y', false);
467         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
468         $this->assertCount(2, $results);
470         $results = core_message_external::search_contacts('y', true);
471         $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
472         $this->assertCount(1, $results);
473         $result = reset($results);
474         $this->assertEquals($user5->id, $result['id']);
476         // Empty query, will throw an exception.
477         $results = core_message_external::search_contacts('');
478     }
480     /**
481      * Test get_messages.
482      */
483     public function test_get_messages() {
484         global $CFG, $DB;
485         $this->resetAfterTest(true);
487         $this->preventResetByRollback();
488         // This mark the messages as read!.
489         $sink = $this->redirectMessages();
491         $user1 = self::getDataGenerator()->create_user();
492         $user2 = self::getDataGenerator()->create_user();
493         $user3 = self::getDataGenerator()->create_user();
495         $course = self::getDataGenerator()->create_course();
497         // Send a message from one user to another.
498         message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
499         message_post_message($user1, $user3, 'some random text 2', FORMAT_MOODLE);
500         message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
501         message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
502         message_post_message($user3, $user1, 'some random text 5', FORMAT_MOODLE);
504         $this->setUser($user1);
505         // Get read conversations from user1 to user2.
506         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
507         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
508         $this->assertCount(1, $messages['messages']);
510         // Delete the message.
511         $message = array_shift($messages['messages']);
512         $messagetobedeleted = $DB->get_record('message_read', array('id' => $message['id']));
513         message_delete_message($messagetobedeleted, $user1->id);
515         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
516         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
517         $this->assertCount(0, $messages['messages']);
519         // Get unread conversations from user1 to user2.
520         $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', false, true, 0, 0);
521         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
522         $this->assertCount(0, $messages['messages']);
524         // Get read messages send from user1.
525         $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
526         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
527         $this->assertCount(1, $messages['messages']);
529         $this->setUser($user2);
530         // Get read conversations from any user to user2.
531         $messages = core_message_external::get_messages($user2->id, 0, 'conversations', true, true, 0, 0);
532         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
533         $this->assertCount(2, $messages['messages']);
535         // Conversations from user3 to user2.
536         $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
537         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
538         $this->assertCount(1, $messages['messages']);
540         // Delete the message.
541         $message = array_shift($messages['messages']);
542         $messagetobedeleted = $DB->get_record('message_read', array('id' => $message['id']));
543         message_delete_message($messagetobedeleted, $user2->id);
545         $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
546         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
547         $this->assertCount(0, $messages['messages']);
549         $this->setUser($user3);
550         // Get read notifications received by user3.
551         $messages = core_message_external::get_messages($user3->id, 0, 'notifications', true, true, 0, 0);
552         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
553         $this->assertCount(0, $messages['messages']);
555         // Now, create some notifications...
556         // We are creating fake notifications but based on real ones.
558         // This one omits notification = 1.
559         $eventdata = new stdClass();
560         $eventdata->modulename        = 'moodle';
561         $eventdata->component         = 'enrol_paypal';
562         $eventdata->name              = 'paypal_enrolment';
563         $eventdata->userfrom          = get_admin();
564         $eventdata->userto            = $user1;
565         $eventdata->subject           = "Moodle: PayPal payment";
566         $eventdata->fullmessage       = "Your PayPal payment is pending.";
567         $eventdata->fullmessageformat = FORMAT_PLAIN;
568         $eventdata->fullmessagehtml   = '';
569         $eventdata->smallmessage      = '';
570         message_send($eventdata);
572         $message = new stdClass();
573         $message->notification      = 1;
574         $message->component         = 'enrol_manual';
575         $message->name              = 'expiry_notification';
576         $message->userfrom          = $user2;
577         $message->userto            = $user1;
578         $message->subject           = 'Enrolment expired';
579         $message->fullmessage       = 'Enrolment expired blah blah blah';
580         $message->fullmessageformat = FORMAT_MARKDOWN;
581         $message->fullmessagehtml   = markdown_to_html($message->fullmessage);
582         $message->smallmessage      = $message->subject;
583         $message->contexturlname    = $course->fullname;
584         $message->contexturl        = (string)new moodle_url('/course/view.php', array('id' => $course->id));
585         message_send($message);
587         $userfrom = core_user::get_noreply_user();
588         $userfrom->maildisplay = true;
589         $eventdata = new stdClass();
590         $eventdata->component         = 'moodle';
591         $eventdata->name              = 'badgecreatornotice';
592         $eventdata->userfrom          = $userfrom;
593         $eventdata->userto            = $user1;
594         $eventdata->notification      = 1;
595         $eventdata->subject           = 'New badge';
596         $eventdata->fullmessage       = format_text_email($eventdata->subject, FORMAT_HTML);
597         $eventdata->fullmessageformat = FORMAT_PLAIN;
598         $eventdata->fullmessagehtml   = $eventdata->subject;
599         $eventdata->smallmessage      = $eventdata->subject;
600         message_send($eventdata);
602         $eventdata = new stdClass();
603         $eventdata->name             = 'submission';
604         $eventdata->component        = 'mod_feedback';
605         $eventdata->userfrom         = $user1;
606         $eventdata->userto           = $user2;
607         $eventdata->subject          = 'Feedback submitted';
608         $eventdata->fullmessage      = 'Feedback submitted from an user';
609         $eventdata->fullmessageformat = FORMAT_PLAIN;
610         $eventdata->fullmessagehtml  = '<strong>Feedback submitted</strong>';
611         $eventdata->smallmessage     = '';
612         message_send($eventdata);
614         $this->setUser($user1);
615         // Get read notifications from any user to user1.
616         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 0);
617         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
618         $this->assertCount(3, $messages['messages']);
620         // Get one read notifications from any user to user1.
621         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 1);
622         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
623         $this->assertCount(1, $messages['messages']);
625         // Get unread notifications from any user to user1.
626         $messages = core_message_external::get_messages($user1->id, 0, 'notifications', false, true, 0, 0);
627         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
628         $this->assertCount(0, $messages['messages']);
630         // Get read both type of messages from any user to user1.
631         $messages = core_message_external::get_messages($user1->id, 0, 'both', true, true, 0, 0);
632         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
633         $this->assertCount(4, $messages['messages']);
635         // Get read notifications from no-reply-user to user1.
636         $messages = core_message_external::get_messages($user1->id, $userfrom->id, 'notifications', true, true, 0, 0);
637         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
638         $this->assertCount(1, $messages['messages']);
640         // Get notifications send by user1 to any user.
641         $messages = core_message_external::get_messages(0, $user1->id, 'notifications', true, true, 0, 0);
642         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
643         $this->assertCount(1, $messages['messages']);
645         // Test warnings.
646         $CFG->messaging = 0;
648         $messages = core_message_external::get_messages(0, $user1->id, 'both', true, true, 0, 0);
649         $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
650         $this->assertCount(1, $messages['warnings']);
652         // Test exceptions.
654         // Messaging disabled.
655         try {
656             $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
657             $this->fail('Exception expected due messaging disabled.');
658         } catch (moodle_exception $e) {
659             $this->assertEquals('disabled', $e->errorcode);
660         }
662         $CFG->messaging = 1;
664         // Invalid users.
665         try {
666             $messages = core_message_external::get_messages(0, 0, 'conversations', true, true, 0, 0);
667             $this->fail('Exception expected due invalid users.');
668         } catch (moodle_exception $e) {
669             $this->assertEquals('accessdenied', $e->errorcode);
670         }
672         // Invalid user ids.
673         try {
674             $messages = core_message_external::get_messages(2500, 0, 'conversations', true, true, 0, 0);
675             $this->fail('Exception expected due invalid users.');
676         } catch (moodle_exception $e) {
677             $this->assertEquals('invaliduser', $e->errorcode);
678         }
680         // Invalid users (permissions).
681         $this->setUser($user2);
682         try {
683             $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
684             $this->fail('Exception expected due invalid user.');
685         } catch (moodle_exception $e) {
686             $this->assertEquals('accessdenied', $e->errorcode);
687         }
689     }
691     /**
692      * Test get_blocked_users.
693      */
694     public function test_get_blocked_users() {
695         $this->resetAfterTest(true);
697         $user1 = self::getDataGenerator()->create_user();
698         $userstranger = self::getDataGenerator()->create_user();
699         $useroffline1 = self::getDataGenerator()->create_user();
700         $useroffline2 = self::getDataGenerator()->create_user();
701         $userblocked = self::getDataGenerator()->create_user();
703         // Login as user1.
704         $this->setUser($user1);
705         $this->assertEquals(array(), core_message_external::create_contacts(
706             array($useroffline1->id, $useroffline2->id)));
708         // The userstranger sends a couple of messages to user1.
709         $this->send_message($userstranger, $user1, 'Hello there!');
710         $this->send_message($userstranger, $user1, 'How you goin?');
712         // The userblocked sends a message to user1.
713         // Note that this user is not blocked at this point.
714         $this->send_message($userblocked, $user1, 'Here, have some spam.');
716         // Retrieve the list of blocked users.
717         $this->setUser($user1);
718         $blockedusers = core_message_external::get_blocked_users($user1->id);
719         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
720         $this->assertCount(0, $blockedusers['users']);
722         // Block the $userblocked and retrieve again the list.
723         core_message_external::block_contacts(array($userblocked->id));
724         $blockedusers = core_message_external::get_blocked_users($user1->id);
725         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
726         $this->assertCount(1, $blockedusers['users']);
728         // Remove the $userblocked and check that the list now is empty.
729         delete_user($userblocked);
730         $blockedusers = core_message_external::get_blocked_users($user1->id);
731         $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
732         $this->assertCount(0, $blockedusers['users']);
734     }
736     /**
737      * Test mark_message_read.
738      */
739     public function test_mark_message_read() {
740         $this->resetAfterTest(true);
742         $user1 = self::getDataGenerator()->create_user();
743         $user2 = self::getDataGenerator()->create_user();
744         $user3 = self::getDataGenerator()->create_user();
746         // Login as user1.
747         $this->setUser($user1);
748         $this->assertEquals(array(), core_message_external::create_contacts(
749             array($user2->id, $user3->id)));
751         // The user2 sends a couple of messages to user1.
752         $this->send_message($user2, $user1, 'Hello there!');
753         $this->send_message($user2, $user1, 'How you goin?');
754         $this->send_message($user3, $user1, 'How you goin?');
755         $this->send_message($user3, $user2, 'How you goin?');
757         // Retrieve all messages sent by user2 (they are currently unread).
758         $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
760         $messageids = array();
761         foreach ($lastmessages as $m) {
762             $messageid = core_message_external::mark_message_read($m->id, time());
763             $messageids[] = external_api::clean_returnvalue(core_message_external::mark_message_read_returns(), $messageid);
764         }
766         // Retrieve all messages sent (they are currently read).
767         $lastmessages = message_get_messages($user1->id, $user2->id, 0, true);
768         $this->assertCount(2, $lastmessages);
769         $this->assertArrayHasKey($messageids[0]['messageid'], $lastmessages);
770         $this->assertArrayHasKey($messageids[1]['messageid'], $lastmessages);
772         // Retrieve all messages sent by any user (that are currently unread).
773         $lastmessages = message_get_messages($user1->id, 0, 0, false);
774         $this->assertCount(1, $lastmessages);
776         // Invalid message ids.
777         try {
778             $messageid = core_message_external::mark_message_read($messageids[0]['messageid'] * 2, time());
779             $this->fail('Exception expected due invalid messageid.');
780         } catch (dml_missing_record_exception $e) {
781             $this->assertEquals('invalidrecord', $e->errorcode);
782         }
784         // A message to a different user.
785         $lastmessages = message_get_messages($user2->id, $user3->id, 0, false);
786         $messageid = array_pop($lastmessages)->id;
787         try {
788             $messageid = core_message_external::mark_message_read($messageid, time());
789             $this->fail('Exception expected due invalid messageid.');
790         } catch (invalid_parameter_exception $e) {
791             $this->assertEquals('invalidparameter', $e->errorcode);
792         }
794     }
796     /**
797      * Test delete_message.
798      */
799     public function test_delete_message() {
800         global $DB;
801         $this->resetAfterTest(true);
803         $user1 = self::getDataGenerator()->create_user();
804         $user2 = self::getDataGenerator()->create_user();
805         $user3 = self::getDataGenerator()->create_user();
806         $user4 = self::getDataGenerator()->create_user();
808         // Login as user1.
809         $this->setUser($user1);
810         $this->assertEquals(array(), core_message_external::create_contacts(array($user2->id, $user3->id)));
812         // User user1 does not interchange messages with user3.
813         $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
814         $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
815         $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
816         $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE);
818         // Retrieve all messages sent by user2 (they are currently unread).
819         $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
821         // Delete a message not read, as a user from.
822         $result = core_message_external::delete_message($m1to2, $user1->id, false);
823         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
824         $this->assertTrue($result['status']);
825         $this->assertCount(0, $result['warnings']);
826         $deletedmessage = $DB->get_record('message', array('id' => $m1to2));
827         $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted);
829         // Try to delete the same message again.
830         $result = core_message_external::delete_message($m1to2, $user1->id, false);
831         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
832         $this->assertFalse($result['status']);
834         // Try to delete a message that does not belong to me.
835         try {
836             $messageid = core_message_external::delete_message($m2to3, $user3->id, false);
837             $this->fail('Exception expected due invalid messageid.');
838         } catch (moodle_exception $e) {
839             $this->assertEquals('You do not have permission to delete this message', $e->errorcode);
840         }
842         $this->setUser($user3);
843         // Delete a message not read, as a user to.
844         $result = core_message_external::delete_message($m2to3, $user3->id, false);
845         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
846         $this->assertTrue($result['status']);
847         $this->assertCount(0, $result['warnings']);
848         $deletedmessage = $DB->get_record('message', array('id' => $m2to3));
849         $this->assertNotEquals(0, $deletedmessage->timeusertodeleted);
851         // Delete a message read.
852         $message = $DB->get_record('message', array('id' => $m3to2));
853         $messageid = message_mark_message_read($message, time());
854         $result = core_message_external::delete_message($messageid, $user3->id);
855         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
856         $this->assertTrue($result['status']);
857         $this->assertCount(0, $result['warnings']);
858         $deletedmessage = $DB->get_record('message_read', array('id' => $messageid));
859         $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted);
861         // Invalid message ids.
862         try {
863             $result = core_message_external::delete_message(-1, $user1->id);
864             $this->fail('Exception expected due invalid messageid.');
865         } catch (dml_missing_record_exception $e) {
866             $this->assertEquals('invalidrecord', $e->errorcode);
867         }
869         // Invalid user.
870         try {
871             $result = core_message_external::delete_message($m1to2, -1, false);
872             $this->fail('Exception expected due invalid user.');
873         } catch (moodle_exception $e) {
874             $this->assertEquals('invaliduser', $e->errorcode);
875         }
877         // Not active user.
878         delete_user($user2);
879         try {
880             $result = core_message_external::delete_message($m1to2, $user2->id, false);
881             $this->fail('Exception expected due invalid user.');
882         } catch (moodle_exception $e) {
883             $this->assertEquals('userdeleted', $e->errorcode);
884         }
886         // Now, as an admin, try to delete any message.
887         $this->setAdminUser();
888         $result = core_message_external::delete_message($m3to4, $user4->id, false);
889         $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
890         $this->assertTrue($result['status']);
891         $this->assertCount(0, $result['warnings']);
892         $deletedmessage = $DB->get_record('message', array('id' => $m3to4));
893         $this->assertNotEquals(0, $deletedmessage->timeusertodeleted);
895     }
897     public function test_get_popup_notifications_no_user_exception() {
898         $this->resetAfterTest(true);
900         $this->setExpectedException('moodle_exception');
901         $result = core_message_external::get_popup_notifications(-2132131, '', false, false, false, true, false, 0, 0);
902     }
904     public function test_get_popup_notifications_access_denied_exception() {
905         $this->resetAfterTest(true);
907         $sender = $this->getDataGenerator()->create_user();
908         $user = $this->getDataGenerator()->create_user();
910         $this->setUser($user);
911         $this->setExpectedException('moodle_exception');
912         $result = core_message_external::get_popup_notifications($sender->id, '', false, false, false, true, false, 0, 0);
913     }
915     public function test_get_popup_notifications_as_recipient() {
916         $this->resetAfterTest(true);
918         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Sendy', 'lastname' => 'Sender'));
919         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Recipy', 'lastname' => 'Recipient'));
921         $notificationids = array(
922             $this->send_fake_unread_popup_notification($sender, $recipient),
923             $this->send_fake_unread_popup_notification($sender, $recipient),
924             $this->send_fake_read_popup_notification($sender, $recipient),
925             $this->send_fake_read_popup_notification($sender, $recipient),
926         );
928         // Confirm that admin has super powers to retrieve any notifications.
929         $this->setAdminUser();
930         $result = core_message_external::get_popup_notifications($recipient->id, '', false, false, false, true, false, 0, 0);
931         $this->assertCount(4, $result['notifications']);
933         $this->setUser($recipient);
934         $result = core_message_external::get_popup_notifications($recipient->id, '', false, false, false, true, false, 0, 0);
935         $this->assertCount(4, $result['notifications']);
937         $result = core_message_external::get_popup_notifications($recipient->id, MESSAGE_UNREAD, false, false, true, true, false, 0, 0);
938         $this->assertCount(2, $result['notifications']);
939         $this->assertObjectHasAttribute('userfromfullname', $result['notifications'][0]);
940         $this->assertObjectNotHasAttribute('usertofullname', $result['notifications'][0]);
941         $this->assertObjectHasAttribute('userfromfullname', $result['notifications'][1]);
942         $this->assertObjectNotHasAttribute('usertofullname', $result['notifications'][1]);
944         $result = core_message_external::get_popup_notifications($recipient->id, MESSAGE_UNREAD, false, true, true, true, false, 0, 0);
945         $this->assertCount(2, $result['notifications']);
946         $this->assertObjectHasAttribute('userfromfullname', $result['notifications'][0]);
947         $this->assertObjectHasAttribute('usertofullname', $result['notifications'][0]);
948         $this->assertObjectHasAttribute('userfromfullname', $result['notifications'][1]);
949         $this->assertObjectHasAttribute('usertofullname', $result['notifications'][1]);
951         $result = core_message_external::get_popup_notifications($recipient->id, MESSAGE_UNREAD, false, true, true, true, true, 0, 0);
952         $this->assertCount(2, $result['notifications']);
953         $this->assertEquals(0, $result['unreadcount']);
955         $result = core_message_external::get_popup_notifications($recipient->id, MESSAGE_UNREAD, false, true, true, true, true, 0, 0);
956         $this->assertCount(0, $result['notifications']);
958         $result = core_message_external::get_popup_notifications($recipient->id, MESSAGE_READ, false, true, true, true, true, 0, 0);
959         $this->assertCount(4, $result['notifications']);
960     }
962     public function test_get_popup_notification_limit_offset() {
963         $this->resetAfterTest(true);
965         $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Sendy', 'lastname' => 'Sender'));
966         $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Recipy', 'lastname' => 'Recipient'));
968         $this->setUser($recipient);
970         $notificationids = array(
971             $this->send_fake_unread_popup_notification($sender, $recipient, 'Notification 1', 1),
972             $this->send_fake_unread_popup_notification($sender, $recipient, 'Notification 2', 2),
973             $this->send_fake_unread_popup_notification($sender, $recipient, 'Notification 3', 3),
974             $this->send_fake_unread_popup_notification($sender, $recipient, 'Notification 4', 4),
975             $this->send_fake_read_popup_notification($sender, $recipient, 'Notification 5', 5),
976             $this->send_fake_read_popup_notification($sender, $recipient, 'Notification 6', 6),
977             $this->send_fake_read_popup_notification($sender, $recipient, 'Notification 7', 7),
978             $this->send_fake_read_popup_notification($sender, $recipient, 'Notification 8', 8),
979         );
981         $result = core_message_external::get_popup_notifications($recipient->id, '', false, false, false, true, false, 2, 0);
983         $this->assertEquals($result['notifications'][0]->id, $notificationids[7]);
984         $this->assertEquals($result['notifications'][1]->id, $notificationids[6]);
986         $result = core_message_external::get_popup_notifications($recipient->id, '', false, false, false, true, false, 2, 2);
988         $this->assertEquals($result['notifications'][0]->id, $notificationids[5]);
989         $this->assertEquals($result['notifications'][1]->id, $notificationids[4]);
990     }
992     public function test_mark_all_notifications_as_read_invalid_user_exception() {
993         $this->resetAfterTest(true);
995         $this->setExpectedException('moodle_exception');
996         $result = core_message_external::mark_all_notifications_as_read(-2132131, 0);
997     }
999     public function test_mark_all_notifications_as_read_access_denied_exception() {
1000         $this->resetAfterTest(true);
1002         $sender = $this->getDataGenerator()->create_user();
1003         $user = $this->getDataGenerator()->create_user();
1005         $this->setUser($user);
1006         $this->setExpectedException('moodle_exception');
1007         $result = core_message_external::mark_all_notifications_as_read($sender->id, 0);
1008     }
1010     public function test_mark_all_notifications_as_read_missing_from_user_exception() {
1011         $this->resetAfterTest(true);
1013         $sender = $this->getDataGenerator()->create_user();
1015         $this->setUser($sender);
1016         $this->setExpectedException('moodle_exception');
1017         $result = core_message_external::mark_all_notifications_as_read($sender->id, 99999);
1018     }
1020     public function test_mark_all_notifications_as_read() {
1021         $this->resetAfterTest(true);
1023         $sender1 = $this->getDataGenerator()->create_user();
1024         $sender2 = $this->getDataGenerator()->create_user();
1025         $sender3 = $this->getDataGenerator()->create_user();
1026         $recipient = $this->getDataGenerator()->create_user();
1028         $this->setUser($recipient);
1030         $notificationids = array(
1031             $this->send_fake_unread_popup_notification($sender1, $recipient, 'Notification', 1),
1032             $this->send_fake_unread_popup_notification($sender1, $recipient, 'Notification', 2),
1033             $this->send_fake_unread_popup_notification($sender2, $recipient, 'Notification', 3),
1034             $this->send_fake_unread_popup_notification($sender2, $recipient, 'Notification', 4),
1035             $this->send_fake_unread_popup_notification($sender3, $recipient, 'Notification', 5),
1036             $this->send_fake_unread_popup_notification($sender3, $recipient, 'Notification', 6),
1037         );
1039         core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id);
1040         $readresult = core_message_external::get_popup_notifications($recipient->id, 'read', false, false, false, true, false, 0, 0);
1041         $unreadresult = core_message_external::get_popup_notifications($recipient->id, 'unread', false, false, false, true, false, 0, 0);
1043         $this->assertCount(2, $readresult['notifications']);
1044         $this->assertCount(4, $unreadresult['notifications']);
1046         core_message_external::mark_all_notifications_as_read($recipient->id, 0);
1047         $readresult = core_message_external::get_popup_notifications($recipient->id, 'read', false, false, false, true, false, 0, 0);
1048         $unreadresult = core_message_external::get_popup_notifications($recipient->id, 'unread', false, false, false, true, false, 0, 0);
1050         $this->assertCount(6, $readresult['notifications']);
1051         $this->assertCount(0, $unreadresult['notifications']);
1052     }
1054     public function test_get_unread_popup_notification_count_invalid_user_exception() {
1055         $this->resetAfterTest(true);
1057         $this->setExpectedException('moodle_exception');
1058         $result = core_message_external::get_unread_popup_notification_count(-2132131, 0);
1059     }
1061     public function test_get_unread_popup_notification_count_access_denied_exception() {
1062         $this->resetAfterTest(true);
1064         $sender = $this->getDataGenerator()->create_user();
1065         $user = $this->getDataGenerator()->create_user();
1067         $this->setUser($user);
1068         $this->setExpectedException('moodle_exception');
1069         $result = core_message_external::get_unread_popup_notification_count($sender->id, 0);
1070     }
1072     public function test_get_unread_popup_notification_count() {
1073         $this->resetAfterTest(true);
1075         $sender1 = $this->getDataGenerator()->create_user();
1076         $sender2 = $this->getDataGenerator()->create_user();
1077         $sender3 = $this->getDataGenerator()->create_user();
1078         $recipient = $this->getDataGenerator()->create_user();
1080         $this->setUser($recipient);
1082         $notificationids = array(
1083             $this->send_fake_unread_popup_notification($sender1, $recipient, 'Notification', 1),
1084             $this->send_fake_unread_popup_notification($sender1, $recipient, 'Notification', 2),
1085             $this->send_fake_unread_popup_notification($sender2, $recipient, 'Notification', 3),
1086             $this->send_fake_unread_popup_notification($sender2, $recipient, 'Notification', 4),
1087             $this->send_fake_unread_popup_notification($sender3, $recipient, 'Notification', 5),
1088             $this->send_fake_unread_popup_notification($sender3, $recipient, 'Notification', 6),
1089         );
1091         $count = core_message_external::get_unread_popup_notification_count($recipient->id);
1092         $this->assertEquals($count, 6);
1093     }