MDL-65566 core_message: fix bug allowing duplicate unique conversations
[moodle.git] / message / tests / externallib_test.php
CommitLineData
e6432668
JM
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/>.
16
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 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29
30require_once($CFG->dirroot . '/webservice/tests/helpers.php');
31require_once($CFG->dirroot . '/message/externallib.php');
32
fb04293b
SA
33use \core_message\tests\helper as testhelper;
34
8252b7c2 35class core_message_externallib_testcase extends externallib_advanced_testcase {
e6432668 36
6ff4464b
JL
37 /**
38 * Tests set up
39 */
40 protected function setUp() {
41 global $CFG;
42
43 require_once($CFG->dirroot . '/message/lib.php');
44 }
45
d6731600
FM
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.
7d69958e 56 * @param int $notification is the message a notification.
6aa01968 57 * @param int $time the time the message was sent
d6731600 58 */
6aa01968 59 protected function send_message($userfrom, $userto, $message = 'Hello world!', $notification = 0, $time = 0) {
d6731600 60 global $DB;
6aa01968
MN
61
62 if (empty($time)) {
63 $time = time();
64 }
65
883ce421
MN
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;
74
75 return $DB->insert_record('notifications', $record);
76 }
77
b2cd17e6 78 if (!$conversationid = \core_message\api::get_conversation_between_users([$userfrom->id, $userto->id])) {
f2ac0a3e
MN
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;
883ce421
MN
87 }
88
89 // Ok, send the message.
d6731600
FM
90 $record = new stdClass();
91 $record->useridfrom = $userfrom->id;
883ce421 92 $record->conversationid = $conversationid;
d6731600
FM
93 $record->subject = 'No subject';
94 $record->fullmessage = $message;
883ce421 95 $record->smallmessage = $message;
6aa01968 96 $record->timecreated = $time;
4d146f1a 97
883ce421 98 return $DB->insert_record('messages', $record);
d6731600
FM
99 }
100
e6432668 101 /**
f219eac7 102 * Test send_instant_messages.
e6432668
JM
103 */
104 public function test_send_instant_messages() {
f219eac7 105 global $DB, $USER;
e6432668 106
f219eac7 107 $this->resetAfterTest();
e6432668 108
7356e732
EL
109 // Transactions used in tests, tell phpunit use alternative reset method.
110 $this->preventResetByRollback();
e6432668 111
f219eac7
MN
112 $user1 = self::getDataGenerator()->create_user();
113 $user2 = self::getDataGenerator()->create_user();
e6432668 114
f219eac7
MN
115 $this->setUser($user1);
116
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);
123
124 $sentmessages = core_message_external::send_instant_messages($messages);
125 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
f7dfa9ba
SA
126 $this->assertEquals(
127 get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message1['touserid']))),
128 array_pop($sentmessages)['errormessage']
129 );
130
131 // Add the user1 as a contact.
132 \core_message\api::add_contact($user1->id, $user2->id);
133
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);
f219eac7
MN
138
139 $sentmessage = reset($sentmessages);
140
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']]);
150
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 }
157
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;
163
164 $this->resetAfterTest();
165
166 // Transactions used in tests, tell phpunit use alternative reset method.
167 $this->preventResetByRollback();
e6432668
JM
168
169 $user1 = self::getDataGenerator()->create_user();
f219eac7
MN
170 $user2 = self::getDataGenerator()->create_user();
171
172 $this->setUser($user1);
173
174 \core_message\api::block_user($user2->id, $user1->id);
e6432668
JM
175
176 // Create test message data.
177 $message1 = array();
f219eac7 178 $message1['touserid'] = $user2->id;
e6432668
JM
179 $message1['text'] = 'the message.';
180 $message1['clientmsgid'] = 4;
181 $messages = array($message1);
182
183 $sentmessages = core_message_external::send_instant_messages($messages);
f219eac7 184 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
e6432668 185
f219eac7
MN
186 $sentmessage = reset($sentmessages);
187
f7dfa9ba 188 $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']);
f219eac7
MN
189
190 $this->assertEquals(0, $DB->count_records('messages'));
191 }
192
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;
198
199 $this->resetAfterTest(true);
200
201 // Transactions used in tests, tell phpunit use alternative reset method.
202 $this->preventResetByRollback();
203
204 $user1 = self::getDataGenerator()->create_user();
205 $user2 = self::getDataGenerator()->create_user();
206
207 $this->setUser($user1);
208
209 // Set the user preference so user 2 does not accept messages from non-contacts.
f7dfa9ba 210 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2);
f219eac7
MN
211
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);
218
219 $sentmessages = core_message_external::send_instant_messages($messages);
220 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
221
222 $sentmessage = reset($sentmessages);
223
f7dfa9ba 224 $this->assertEquals(get_string('usercantbemessaged', 'message', fullname($user2)), $sentmessage['errormessage']);
f219eac7
MN
225
226 $this->assertEquals(0, $DB->count_records('messages'));
227 }
228
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;
234
235 $this->resetAfterTest(true);
236
237 // Transactions used in tests, tell phpunit use alternative reset method.
238 $this->preventResetByRollback();
239
240 $user1 = self::getDataGenerator()->create_user();
241 $user2 = self::getDataGenerator()->create_user();
242
243 $this->setUser($user1);
244
245 // Set the user preference so user 2 does not accept messages from non-contacts.
f7dfa9ba 246 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2);
f219eac7
MN
247
248 \core_message\api::add_contact($user1->id, $user2->id);
249
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);
256
257 $sentmessages = core_message_external::send_instant_messages($messages);
fb695f6e
JM
258 $sentmessages = external_api::clean_returnvalue(core_message_external::send_instant_messages_returns(), $sentmessages);
259
f219eac7
MN
260 $sentmessage = reset($sentmessages);
261
883ce421
MN
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 = ?";
f219eac7 270 $themessage = $DB->get_record_sql($sql, [$USER->id, $sentmessage['msgid']]);
e6432668
JM
271
272 // Confirm that the message was inserted correctly.
f219eac7 273 $this->assertEquals($themessage->useridfrom, $user1->id);
e6432668
JM
274 $this->assertEquals($themessage->useridto, $message1['touserid']);
275 $this->assertEquals($themessage->smallmessage, $message1['text']);
f219eac7
MN
276 $this->assertEquals($sentmessage['clientmsgid'], $message1['clientmsgid']);
277 }
278
279 /**
280 * Test send_instant_messages with no capabilities
281 */
282 public function test_send_instant_messages_no_capability() {
283 global $DB;
284
285 $this->resetAfterTest(true);
286
287 // Transactions used in tests, tell phpunit use alternative reset method.
288 $this->preventResetByRollback();
289
290 $user1 = self::getDataGenerator()->create_user();
291 $user2 = self::getDataGenerator()->create_user();
292
293 $this->setUser($user1);
294
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);
299
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);
306
307 $this->expectException('required_capability_exception');
308 core_message_external::send_instant_messages($messages);
309 }
310
311 /**
312 * Test send_instant_messages when messaging is disabled.
313 */
314 public function test_send_instant_messages_messaging_disabled() {
315 global $CFG;
316
317 $this->resetAfterTest(true);
318
319 // Transactions used in tests, tell phpunit use alternative reset method.
320 $this->preventResetByRollback();
321
322 $user1 = self::getDataGenerator()->create_user();
323 $user2 = self::getDataGenerator()->create_user();
324
325 $this->setUser($user1);
326
327 // Disable messaging.
328 $CFG->messaging = 0;
329
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);
336
337 $this->expectException('moodle_exception');
338 core_message_external::send_instant_messages($messages);
e6432668 339 }
d6731600
FM
340
341 /**
342 * Test create_contacts.
343 */
344 public function test_create_contacts() {
345 $this->resetAfterTest(true);
346
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);
353
354 // Adding a contact.
355 $return = core_message_external::create_contacts(array($user2->id));
f219eac7 356 $this->assertDebuggingCalled();
d6731600
FM
357 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
358 $this->assertEquals(array(), $return);
359
360 // Adding a contact who is already a contact.
361 $return = core_message_external::create_contacts(array($user2->id));
f219eac7 362 $this->assertDebuggingCalled();
d6731600
FM
363 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
364 $this->assertEquals(array(), $return);
365
366 // Adding multiple contacts.
367 $return = core_message_external::create_contacts(array($user3->id, $user4->id));
f219eac7 368 $this->assertDebuggingCalledCount(2);
d6731600
FM
369 $return = external_api::clean_returnvalue(core_message_external::create_contacts_returns(), $return);
370 $this->assertEquals(array(), $return);
371
372 // Adding a non-existing user.
373 $return = core_message_external::create_contacts(array(99999));
f219eac7 374 $this->assertDebuggingCalled();
d6731600
FM
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);
380
381 // Adding contacts with valid and invalid parameters.
382 $return = core_message_external::create_contacts(array($user5->id, 99999));
f219eac7 383 $this->assertDebuggingCalledCount(2);
d6731600
FM
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);
343ba16c
SL
389
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);
d6731600
FM
394 }
395
396 /**
397 * Test delete_contacts.
398 */
399 public function test_delete_contacts() {
400 $this->resetAfterTest(true);
401
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);
f219eac7
MN
409
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);
d6731600
FM
414
415 // Removing a non-contact.
416 $return = core_message_external::delete_contacts(array($user2->id));
417 $this->assertNull($return);
418
419 // Removing one contact.
420 $return = core_message_external::delete_contacts(array($user3->id));
421 $this->assertNull($return);
422
423 // Removing multiple contacts.
424 $return = core_message_external::delete_contacts(array($user4->id, $user5->id));
425 $this->assertNull($return);
426
427 // Removing contact from unexisting user.
428 $return = core_message_external::delete_contacts(array(99999));
429 $this->assertNull($return);
430
431 // Removing mixed valid and invalid data.
432 $return = core_message_external::delete_contacts(array($user6->id, 99999));
433 $this->assertNull($return);
343ba16c
SL
434
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);
d6731600
FM
439 }
440
441 /**
442 * Test block_contacts.
443 */
444 public function test_block_contacts() {
445 $this->resetAfterTest(true);
446
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);
f219eac7
MN
453
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);
d6731600
FM
457
458 // Blocking a contact.
459 $return = core_message_external::block_contacts(array($user2->id));
f219eac7 460 $this->assertDebuggingCalled();
d6731600
FM
461 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
462 $this->assertEquals(array(), $return);
463
464 // Blocking a contact who is already a contact.
465 $return = core_message_external::block_contacts(array($user2->id));
f219eac7 466 $this->assertDebuggingCalled();
d6731600
FM
467 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
468 $this->assertEquals(array(), $return);
469
470 // Blocking multiple contacts.
471 $return = core_message_external::block_contacts(array($user3->id, $user4->id));
f219eac7 472 $this->assertDebuggingCalledCount(2);
d6731600
FM
473 $return = external_api::clean_returnvalue(core_message_external::block_contacts_returns(), $return);
474 $this->assertEquals(array(), $return);
475
476 // Blocking a non-existing user.
477 $return = core_message_external::block_contacts(array(99999));
f219eac7 478 $this->assertDebuggingCalled();
d6731600
FM
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);
484
485 // Blocking contacts with valid and invalid parameters.
486 $return = core_message_external::block_contacts(array($user5->id, 99999));
f219eac7 487 $this->assertDebuggingCalledCount(2);
d6731600
FM
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);
343ba16c
SL
493
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);
d6731600
FM
498 }
499
500 /**
501 * Test unblock_contacts.
502 */
503 public function test_unblock_contacts() {
504 $this->resetAfterTest(true);
505
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);
f219eac7
MN
513
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);
d6731600
FM
518
519 // Removing a non-contact.
520 $return = core_message_external::unblock_contacts(array($user2->id));
f219eac7 521 $this->assertDebuggingCalled();
d6731600
FM
522 $this->assertNull($return);
523
524 // Removing one contact.
525 $return = core_message_external::unblock_contacts(array($user3->id));
f219eac7 526 $this->assertDebuggingCalled();
d6731600
FM
527 $this->assertNull($return);
528
529 // Removing multiple contacts.
530 $return = core_message_external::unblock_contacts(array($user4->id, $user5->id));
f219eac7 531 $this->assertDebuggingCalledCount(2);
d6731600
FM
532 $this->assertNull($return);
533
534 // Removing contact from unexisting user.
535 $return = core_message_external::unblock_contacts(array(99999));
f219eac7 536 $this->assertDebuggingCalled();
d6731600
FM
537 $this->assertNull($return);
538
539 // Removing mixed valid and invalid data.
540 $return = core_message_external::unblock_contacts(array($user6->id, 99999));
f219eac7 541 $this->assertDebuggingCalledCount(2);
d6731600
FM
542 $this->assertNull($return);
543
343ba16c
SL
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);
f219eac7 548 $this->assertDebuggingCalled();
d6731600
FM
549 }
550
52284186
MN
551 /**
552 * Test getting contact requests.
553 */
554 public function test_get_contact_requests() {
0866b336
RW
555 global $PAGE;
556
52284186
MN
557 $this->resetAfterTest();
558
559 $user1 = self::getDataGenerator()->create_user();
560 $user2 = self::getDataGenerator()->create_user();
561 $user3 = self::getDataGenerator()->create_user();
562
563 $this->setUser($user1);
564
565 // Block one user, their request should not show up.
566 \core_message\api::block_user($user1->id, $user3->id);
567
568 \core_message\api::create_contact_request($user2->id, $user1->id);
569 \core_message\api::create_contact_request($user3->id, $user1->id);
570
571 $requests = core_message_external::get_contact_requests($user1->id);
572 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
573
574 $this->assertCount(1, $requests);
575
576 $request = reset($requests);
0866b336
RW
577 $userpicture = new \user_picture($user2);
578 $profileimageurl = $userpicture->get_url($PAGE)->out(false);
52284186
MN
579
580 $this->assertEquals($user2->id, $request['id']);
daa33803
MN
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);
52284186
MN
588 }
589
e4088b75
JD
590 /**
591 * Test the get_contact_requests() function when the user has blocked the sender of the request.
592 */
593 public function test_get_contact_requests_blocked_sender() {
594 $this->resetAfterTest();
595 $user1 = self::getDataGenerator()->create_user();
596 $user2 = self::getDataGenerator()->create_user();
597
598 // User1 blocks User2.
599 \core_message\api::block_user($user1->id, $user2->id);
600
601 // User2 tries to add User1 as a contact.
602 \core_message\api::create_contact_request($user2->id, $user1->id);
603
604 // Verify we don't see the contact request from the blocked user User2 in the requests for User1.
605 $this->setUser($user1);
606 $requests = core_message_external::get_contact_requests($user1->id);
607 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
608
609 $this->assertCount(0, $requests);
610 }
611
b3ce575e
MN
612 /**
613 * Test getting contact requests when there are none.
614 */
615 public function test_get_contact_requests_no_requests() {
616 $this->resetAfterTest();
617
618 $user1 = self::getDataGenerator()->create_user();
619
620 $this->setUser($user1);
621
622 $requests = core_message_external::get_contact_requests($user1->id);
623 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
624
625 $this->assertEmpty($requests);
626 }
627
628 /**
629 * Test getting contact requests with limits.
630 */
631 public function test_get_contact_requests_with_limits() {
632 $this->resetAfterTest();
633
634 $user1 = self::getDataGenerator()->create_user();
635 $user2 = self::getDataGenerator()->create_user();
636 $user3 = self::getDataGenerator()->create_user();
637
638 $this->setUser($user1);
639
640 \core_message\api::create_contact_request($user2->id, $user1->id);
641 \core_message\api::create_contact_request($user3->id, $user1->id);
642
643 $requests = core_message_external::get_contact_requests($user1->id, 0, 1);
644 $requests = external_api::clean_returnvalue(core_message_external::get_contact_requests_returns(), $requests);
645
646 $this->assertCount(1, $requests);
52284186
MN
647 }
648
649 /**
650 * Test getting contact requests with messaging disabled.
651 */
652 public function test_get_contact_requests_messaging_disabled() {
653 global $CFG;
654
655 $this->resetAfterTest();
656
657 // Create some skeleton data just so we can call the WS.
658 $user1 = self::getDataGenerator()->create_user();
659
660 $this->setUser($user1);
661
662 // Disable messaging.
663 $CFG->messaging = 0;
664
665 // Ensure an exception is thrown.
666 $this->expectException('moodle_exception');
667 core_message_external::get_contact_requests($user1->id);
668 }
669
670 /**
671 * Test getting contact requests with no permission.
672 */
673 public function test_get_contact_requests_no_permission() {
674 $this->resetAfterTest();
675
676 // Create some skeleton data just so we can call the WS.
677 $user1 = self::getDataGenerator()->create_user();
678 $user2 = self::getDataGenerator()->create_user();
679 $user3 = self::getDataGenerator()->create_user();
680
681 $this->setUser($user3);
682
683 // Ensure an exception is thrown.
684 $this->expectException('required_capability_exception');
685 core_message_external::create_contact_request($user1->id, $user2->id);
686 }
687
7d678923
MN
688 /**
689 * Test getting the number of received contact requests.
690 */
691 public function test_get_received_contact_requests_count() {
692 $this->resetAfterTest();
693
694 $user1 = self::getDataGenerator()->create_user();
695 $user2 = self::getDataGenerator()->create_user();
696 $user3 = self::getDataGenerator()->create_user();
697 $user4 = self::getDataGenerator()->create_user();
698
699 $this->setUser($user1);
700
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(0, $contactrequestnumber);
705
706 \core_message\api::create_contact_request($user2->id, $user1->id);
707
708 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
709 $contactrequestnumber = external_api::clean_returnvalue(
710 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
711 $this->assertEquals(1, $contactrequestnumber);
712
713 \core_message\api::create_contact_request($user3->id, $user1->id);
714
715 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
716 $contactrequestnumber = external_api::clean_returnvalue(
717 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
718 $this->assertEquals(2, $contactrequestnumber);
719
720 \core_message\api::create_contact_request($user1->id, $user4->id);
721
722 // Web service should ignore sent requests.
723 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
724 $contactrequestnumber = external_api::clean_returnvalue(
725 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
726 $this->assertEquals(2, $contactrequestnumber);
727 }
728
e492a554
JD
729 /**
730 * Test the get_received_contact_requests_count() function when the user has blocked the sender of the request.
731 */
732 public function test_get_received_contact_requests_count_blocked_sender() {
733 $this->resetAfterTest();
734 $user1 = self::getDataGenerator()->create_user();
735 $user2 = self::getDataGenerator()->create_user();
736
737 // User1 blocks User2.
738 \core_message\api::block_user($user1->id, $user2->id);
739
740 // User2 tries to add User1 as a contact.
741 \core_message\api::create_contact_request($user2->id, $user1->id);
742
743 // Verify we don't see the contact request from the blocked user User2 in the count for User1.
744 $this->setUser($user1);
745 $contactrequestnumber = core_message_external::get_received_contact_requests_count($user1->id);
746 $contactrequestnumber = external_api::clean_returnvalue(
747 core_message_external::get_received_contact_requests_count_returns(), $contactrequestnumber);
748 $this->assertEquals(0, $contactrequestnumber);
749 }
750
7d678923
MN
751 /**
752 * Test getting the number of received contact requests with no permissions.
753 */
754 public function test_get_received_contact_requests_count_no_permission() {
755 $this->resetAfterTest();
756
757 // Create some skeleton data just so we can call the WS.
758 $user1 = self::getDataGenerator()->create_user();
759 $user2 = self::getDataGenerator()->create_user();
760
761 $this->setUser($user2);
762
763 // Ensure an exception is thrown.
764 $this->expectException('required_capability_exception');
765 core_message_external::get_received_contact_requests_count($user1->id);
766 }
767
768 /**
769 * Test getting the number of received contact requests with messaging disabled.
770 */
771 public function test_get_received_contact_requests_count_messaging_disabled() {
772 global $CFG;
773
774 $this->resetAfterTest();
775
776 // Create some skeleton data just so we can call the WS.
777 $user1 = self::getDataGenerator()->create_user();
778
779 $this->setUser($user1);
780
781 // Disable messaging.
782 $CFG->messaging = 0;
783
784 // Ensure an exception is thrown.
785 $this->expectException('moodle_exception');
786 core_message_external::get_received_contact_requests_count($user1->id);
787 }
788
52284186
MN
789 /**
790 * Test creating a contact request.
791 */
792 public function test_create_contact_request() {
0d203bbf 793 global $CFG, $DB;
52284186
MN
794
795 $this->resetAfterTest();
796
797 $user1 = self::getDataGenerator()->create_user();
798 $user2 = self::getDataGenerator()->create_user();
799
800 $this->setUser($user1);
801
0d203bbf
MN
802 // Allow users to message anyone site-wide.
803 $CFG->messagingallusers = 1;
804
52284186
MN
805 $return = core_message_external::create_contact_request($user1->id, $user2->id);
806 $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
0866b336 807 $this->assertEquals([], $return['warnings']);
52284186
MN
808
809 $request = $DB->get_records('message_contact_requests');
810
811 $this->assertCount(1, $request);
812
813 $request = reset($request);
814
0866b336
RW
815 $this->assertEquals($request->id, $return['request']['id']);
816 $this->assertEquals($request->userid, $return['request']['userid']);
817 $this->assertEquals($request->requesteduserid, $return['request']['requesteduserid']);
818 $this->assertEquals($request->timecreated, $return['request']['timecreated']);
52284186
MN
819 }
820
0d203bbf
MN
821 /**
822 * Test creating a contact request when not allowed.
823 */
824 public function test_create_contact_request_not_allowed() {
825 global $CFG;
826
827 $this->resetAfterTest();
828
829 $user1 = self::getDataGenerator()->create_user();
830 $user2 = self::getDataGenerator()->create_user();
831
832 $this->setUser($user1);
833
834 $CFG->messagingallusers = 0;
835
836 $return = core_message_external::create_contact_request($user1->id, $user2->id);
837 $return = external_api::clean_returnvalue(core_message_external::create_contact_request_returns(), $return);
838
0866b336 839 $warning = reset($return['warnings']);
0d203bbf
MN
840
841 $this->assertEquals('user', $warning['item']);
842 $this->assertEquals($user2->id, $warning['itemid']);
843 $this->assertEquals('cannotcreatecontactrequest', $warning['warningcode']);
844 $this->assertEquals('You are unable to create a contact request for this user', $warning['message']);
845 }
846
52284186
MN
847 /**
848 * Test creating a contact request with messaging disabled.
849 */
850 public function test_create_contact_request_messaging_disabled() {
851 global $CFG;
852
853 $this->resetAfterTest();
854
855 // Create some skeleton data just so we can call the WS.
856 $user1 = self::getDataGenerator()->create_user();
857 $user2 = self::getDataGenerator()->create_user();
858
859 $this->setUser($user1);
860
861 // Disable messaging.
862 $CFG->messaging = 0;
863
864 // Ensure an exception is thrown.
865 $this->expectException('moodle_exception');
866 core_message_external::create_contact_request($user1->id, $user2->id);
867 }
868
869 /**
870 * Test creating a contact request with no permission.
871 */
872 public function test_create_contact_request_no_permission() {
873 $this->resetAfterTest();
874
875 // Create some skeleton data just so we can call the WS.
876 $user1 = self::getDataGenerator()->create_user();
877 $user2 = self::getDataGenerator()->create_user();
878 $user3 = self::getDataGenerator()->create_user();
879
880 $this->setUser($user3);
881
882 // Ensure an exception is thrown.
883 $this->expectException('required_capability_exception');
884 core_message_external::create_contact_request($user1->id, $user2->id);
885 }
886
887 /**
888 * Test confirming a contact request.
889 */
890 public function test_confirm_contact_request() {
891 global $DB;
892
893 $this->resetAfterTest();
894
895 $user1 = self::getDataGenerator()->create_user();
896 $user2 = self::getDataGenerator()->create_user();
897
898 $this->setUser($user1);
899
900 \core_message\api::create_contact_request($user1->id, $user2->id);
901
902 $this->setUser($user2);
903
904 $return = core_message_external::confirm_contact_request($user1->id, $user2->id);
905 $return = external_api::clean_returnvalue(core_message_external::confirm_contact_request_returns(), $return);
906 $this->assertEquals(array(), $return);
907
908 $this->assertEquals(0, $DB->count_records('message_contact_requests'));
909
910 $contact = $DB->get_records('message_contacts');
911
912 $this->assertCount(1, $contact);
913
914 $contact = reset($contact);
915
916 $this->assertEquals($user1->id, $contact->userid);
917 $this->assertEquals($user2->id, $contact->contactid);
918 }
919
920 /**
921 * Test confirming a contact request with messaging disabled.
922 */
923 public function test_confirm_contact_request_messaging_disabled() {
924 global $CFG;
925
926 $this->resetAfterTest();
927
928 // Create some skeleton data just so we can call the WS.
929 $user1 = self::getDataGenerator()->create_user();
930 $user2 = self::getDataGenerator()->create_user();
931
932 $this->setUser($user1);
933
934 // Disable messaging.
935 $CFG->messaging = 0;
936
937 // Ensure an exception is thrown.
938 $this->expectException('moodle_exception');
939 core_message_external::confirm_contact_request($user1->id, $user2->id);
940 }
941
942 /**
943 * Test confirming a contact request with no permission.
944 */
945 public function test_confirm_contact_request_no_permission() {
946 $this->resetAfterTest();
947
948 // Create some skeleton data just so we can call the WS.
949 $user1 = self::getDataGenerator()->create_user();
950 $user2 = self::getDataGenerator()->create_user();
951 $user3 = self::getDataGenerator()->create_user();
952
953 $this->setUser($user3);
954
955 // Ensure an exception is thrown.
956 $this->expectException('required_capability_exception');
957 core_message_external::confirm_contact_request($user1->id, $user2->id);
958 }
959
960 /**
961 * Test declining a contact request.
962 */
963 public function test_decline_contact_request() {
964 global $DB;
965
966 $this->resetAfterTest();
967
968 $user1 = self::getDataGenerator()->create_user();
969 $user2 = self::getDataGenerator()->create_user();
970
971 $this->setUser($user1);
972
973 \core_message\api::create_contact_request($user1->id, $user2->id);
974
975 $this->setUser($user2);
976
977 $return = core_message_external::decline_contact_request($user1->id, $user2->id);
978 $return = external_api::clean_returnvalue(core_message_external::decline_contact_request_returns(), $return);
979 $this->assertEquals(array(), $return);
980
981 $this->assertEquals(0, $DB->count_records('message_contact_requests'));
982 $this->assertEquals(0, $DB->count_records('message_contacts'));
983 }
984
985 /**
986 * Test declining a contact request with messaging disabled.
987 */
988 public function test_decline_contact_request_messaging_disabled() {
989 global $CFG;
990
991 $this->resetAfterTest();
992
993 // Create some skeleton data just so we can call the WS.
994 $user1 = self::getDataGenerator()->create_user();
995 $user2 = self::getDataGenerator()->create_user();
996
997 $this->setUser($user1);
998
999 // Disable messaging.
1000 $CFG->messaging = 0;
1001
1002 // Ensure an exception is thrown.
1003 $this->expectException('moodle_exception');
1004 core_message_external::decline_contact_request($user1->id, $user2->id);
1005 }
1006
1007 /**
1008 * Test declining a contact request with no permission.
1009 */
1010 public function test_decline_contact_request_no_permission() {
1011 $this->resetAfterTest();
1012
1013 // Create some skeleton data just so we can call the WS.
1014 $user1 = self::getDataGenerator()->create_user();
1015 $user2 = self::getDataGenerator()->create_user();
1016 $user3 = self::getDataGenerator()->create_user();
1017
1018 $this->setUser($user3);
1019
1020 // Ensure an exception is thrown.
1021 $this->expectException('required_capability_exception');
1022 core_message_external::decline_contact_request($user1->id, $user2->id);
1023 }
1024
086409f6
MN
1025 /**
1026 * Test muting conversations.
1027 */
1028 public function test_mute_conversations() {
1029 global $DB;
1030
1031 $this->resetAfterTest(true);
1032
1033 $user1 = self::getDataGenerator()->create_user();
1034 $user2 = self::getDataGenerator()->create_user();
1035
1036 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1037 [$user1->id, $user2->id]);
1038
1039 $this->setUser($user1);
1040
1041 // Muting a conversation.
1042 $return = core_message_external::mute_conversations($user1->id, [$conversation->id]);
1043 $return = external_api::clean_returnvalue(core_message_external::mute_conversations_returns(), $return);
1044 $this->assertEquals(array(), $return);
1045
1046 // Get list of muted conversations.
1047 $mca = $DB->get_record('message_conversation_actions', []);
1048
1049 $this->assertEquals($user1->id, $mca->userid);
1050 $this->assertEquals($conversation->id, $mca->conversationid);
1051 $this->assertEquals(\core_message\api::CONVERSATION_ACTION_MUTED, $mca->action);
1052
1053 // Muting a conversation that is already muted.
1054 $return = core_message_external::mute_conversations($user1->id, [$conversation->id]);
1055 $return = external_api::clean_returnvalue(core_message_external::mute_conversations_returns(), $return);
1056 $this->assertEquals(array(), $return);
1057
1058 $this->assertEquals(1, $DB->count_records('message_conversation_actions'));
1059 }
1060
1061 /**
1062 * Test muting a conversation with messaging disabled.
1063 */
1064 public function test_mute_conversations_messaging_disabled() {
1065 global $CFG;
1066
1067 $this->resetAfterTest();
1068
1069 // Create some skeleton data just so we can call the WS.
1070 $user1 = self::getDataGenerator()->create_user();
1071 $user2 = self::getDataGenerator()->create_user();
1072
1073 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1074 [$user1->id, $user2->id]);
1075
1076 $this->setUser($user1);
1077
1078 // Disable messaging.
1079 $CFG->messaging = 0;
1080
1081 // Ensure an exception is thrown.
1082 $this->expectException('moodle_exception');
1083 core_message_external::mute_conversations($user1->id, [$conversation->id]);
1084 }
1085
1086 /**
1087 * Test muting a conversation with no permission.
1088 */
1089 public function test_mute_conversations_no_permission() {
1090 $this->resetAfterTest();
1091
1092 // Create some skeleton data just so we can call the WS.
1093 $user1 = self::getDataGenerator()->create_user();
1094 $user2 = self::getDataGenerator()->create_user();
1095 $user3 = self::getDataGenerator()->create_user();
1096
1097 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1098 [$user1->id, $user2->id]);
1099
1100 $this->setUser($user3);
1101
1102 // Ensure an exception is thrown.
1103 $this->expectException('required_capability_exception');
1104 core_message_external::mute_conversations($user1->id, [$conversation->id]);
1105 }
1106
1107 /**
1108 * Test unmuting conversations.
1109 */
1110 public function test_unmute_conversations() {
1111 global $DB;
1112
1113 $this->resetAfterTest(true);
1114
1115 $user1 = self::getDataGenerator()->create_user();
1116 $user2 = self::getDataGenerator()->create_user();
1117
1118 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1119 [$user1->id, $user2->id]);
1120
1121 $this->setUser($user1);
1122
1123 // Mute the conversation.
1124 \core_message\api::mute_conversation($user1->id, $conversation->id);
1125
1126 // Unmuting a conversation.
1127 $return = core_message_external::unmute_conversations($user1->id, [$conversation->id]);
1128 $return = external_api::clean_returnvalue(core_message_external::unmute_conversations_returns(), $return);
1129 $this->assertEquals(array(), $return);
1130
1131 $this->assertEquals(0, $DB->count_records('message_conversation_actions'));
1132
1133 // Unmuting a conversation which is already unmuted.
1134 $return = core_message_external::unmute_conversations($user1->id, [$conversation->id]);
1135 $return = external_api::clean_returnvalue(core_message_external::unmute_conversations_returns(), $return);
1136 $this->assertEquals(array(), $return);
1137
1138 $this->assertEquals(0, $DB->count_records('message_conversation_actions'));
1139 }
1140
1141 /**
1142 * Test unmuting a conversation with messaging disabled.
1143 */
1144 public function test_unmute_conversation_messaging_disabled() {
1145 global $CFG;
1146
1147 $this->resetAfterTest();
1148
1149 // Create some skeleton data just so we can call the WS.
1150 $user1 = self::getDataGenerator()->create_user();
1151 $user2 = self::getDataGenerator()->create_user();
1152
1153 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1154 [$user1->id, $user2->id]);
1155
1156 $this->setUser($user1);
1157
1158 // Disable messaging.
1159 $CFG->messaging = 0;
1160
1161 // Ensure an exception is thrown.
1162 $this->expectException('moodle_exception');
1163 core_message_external::unmute_conversations($user1->id, [$user2->id]);
1164 }
1165
1166 /**
1167 * Test unmuting a conversation with no permission.
1168 */
1169 public function test_unmute_conversation_no_permission() {
1170 $this->resetAfterTest();
1171
1172 // Create some skeleton data just so we can call the WS.
1173 $user1 = self::getDataGenerator()->create_user();
1174 $user2 = self::getDataGenerator()->create_user();
1175 $user3 = self::getDataGenerator()->create_user();
1176
1177 $conversation = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1178 [$user1->id, $user2->id]);
1179
1180 $this->setUser($user3);
1181
1182 // Ensure an exception is thrown.
1183 $this->expectException('required_capability_exception');
1184 core_message_external::unmute_conversations($user1->id, [$conversation->id]);
1185 }
1186
52284186
MN
1187 /**
1188 * Test blocking a user.
1189 */
1190 public function test_block_user() {
1191 global $DB;
1192
1193 $this->resetAfterTest(true);
1194
1195 $user1 = self::getDataGenerator()->create_user();
1196 $user2 = self::getDataGenerator()->create_user();
1197
1198 $this->setUser($user1);
1199
1200 // Blocking a user.
1201 $return = core_message_external::block_user($user1->id, $user2->id);
1202 $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
1203 $this->assertEquals(array(), $return);
1204
1205 // Get list of blocked users.
1206 $record = $DB->get_record('message_users_blocked', []);
1207
1208 $this->assertEquals($user1->id, $record->userid);
1209 $this->assertEquals($user2->id, $record->blockeduserid);
1210
1211 // Blocking a user who is already blocked.
1212 $return = core_message_external::block_user($user1->id, $user2->id);
1213 $return = external_api::clean_returnvalue(core_message_external::block_user_returns(), $return);
1214 $this->assertEquals(array(), $return);
1215
1216 $this->assertEquals(1, $DB->count_records('message_users_blocked'));
1217 }
1218
1219 /**
1220 * Test blocking a user with messaging disabled.
1221 */
1222 public function test_block_user_messaging_disabled() {
1223 global $CFG;
1224
1225 $this->resetAfterTest();
1226
1227 // Create some skeleton data just so we can call the WS.
1228 $user1 = self::getDataGenerator()->create_user();
1229 $user2 = self::getDataGenerator()->create_user();
1230
1231 $this->setUser($user1);
1232
1233 // Disable messaging.
1234 $CFG->messaging = 0;
1235
1236 // Ensure an exception is thrown.
1237 $this->expectException('moodle_exception');
1238 core_message_external::block_user($user1->id, $user2->id);
1239 }
1240
1241 /**
1242 * Test blocking a user with no permission.
1243 */
1244 public function test_block_user_no_permission() {
1245 $this->resetAfterTest();
1246
1247 // Create some skeleton data just so we can call the WS.
1248 $user1 = self::getDataGenerator()->create_user();
1249 $user2 = self::getDataGenerator()->create_user();
1250 $user3 = self::getDataGenerator()->create_user();
1251
1252 $this->setUser($user3);
1253
1254 // Ensure an exception is thrown.
1255 $this->expectException('required_capability_exception');
1256 core_message_external::block_user($user1->id, $user2->id);
1257 }
1258
1259 /**
1260 * Test unblocking a user.
1261 */
1262 public function test_unblock_user() {
1263 global $DB;
1264
1265 $this->resetAfterTest(true);
1266
1267 $user1 = self::getDataGenerator()->create_user();
1268 $user2 = self::getDataGenerator()->create_user();
1269
1270 $this->setUser($user1);
1271
1272 // Block the user.
1273 \core_message\api::block_user($user1->id, $user2->id);
1274
1275 // Unblocking a user.
1276 $return = core_message_external::unblock_user($user1->id, $user2->id);
1277 $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
1278 $this->assertEquals(array(), $return);
1279
1280 $this->assertEquals(0, $DB->count_records('message_users_blocked'));
1281
1282 // Unblocking a user who is already unblocked.
1283 $return = core_message_external::unblock_user($user1->id, $user2->id);
1284 $return = external_api::clean_returnvalue(core_message_external::unblock_user_returns(), $return);
1285 $this->assertEquals(array(), $return);
1286
1287 $this->assertEquals(0, $DB->count_records('message_users_blocked'));
1288 }
1289
1290 /**
1291 * Test unblocking a user with messaging disabled.
1292 */
1293 public function test_unblock_user_messaging_disabled() {
1294 global $CFG;
1295
1296 $this->resetAfterTest();
1297
1298 // Create some skeleton data just so we can call the WS.
1299 $user1 = self::getDataGenerator()->create_user();
1300 $user2 = self::getDataGenerator()->create_user();
1301
1302 $this->setUser($user1);
1303
1304 // Disable messaging.
1305 $CFG->messaging = 0;
1306
1307 // Ensure an exception is thrown.
1308 $this->expectException('moodle_exception');
1309 core_message_external::unblock_user($user1->id, $user2->id);
1310 }
1311
1312 /**
1313 * Test unblocking a user with no permission.
1314 */
1315 public function test_unblock_user_no_permission() {
1316 $this->resetAfterTest();
1317
1318 // Create some skeleton data just so we can call the WS.
1319 $user1 = self::getDataGenerator()->create_user();
1320 $user2 = self::getDataGenerator()->create_user();
1321 $user3 = self::getDataGenerator()->create_user();
1322
1323 $this->setUser($user3);
1324
1325 // Ensure an exception is thrown.
1326 $this->expectException('required_capability_exception');
1327 core_message_external::unblock_user($user1->id, $user2->id);
1328 }
1329
d6731600
FM
1330 /**
1331 * Test get_contacts.
1332 */
1333 public function test_get_contacts() {
1334 $this->resetAfterTest(true);
1335
1336 $user1 = self::getDataGenerator()->create_user();
1337 $user_stranger = self::getDataGenerator()->create_user();
1338 $user_offline1 = self::getDataGenerator()->create_user();
1339 $user_offline2 = self::getDataGenerator()->create_user();
1340 $user_offline3 = self::getDataGenerator()->create_user();
1341 $user_online = new stdClass();
1342 $user_online->lastaccess = time();
1343 $user_online = self::getDataGenerator()->create_user($user_online);
1344 $user_blocked = self::getDataGenerator()->create_user();
0b074e88 1345 $noreplyuser = core_user::get_user(core_user::NOREPLY_USER);
d6731600
FM
1346
1347 // Login as user1.
1348 $this->setUser($user1);
f219eac7
MN
1349 \core_message\api::add_contact($user1->id, $user_offline1->id);
1350 \core_message\api::add_contact($user1->id, $user_offline2->id);
1351 \core_message\api::add_contact($user1->id, $user_offline3->id);
1352 \core_message\api::add_contact($user1->id, $user_online->id);
d6731600
FM
1353
1354 // User_stranger sends a couple of messages to user1.
1355 $this->send_message($user_stranger, $user1, 'Hello there!');
1356 $this->send_message($user_stranger, $user1, 'How you goin?');
1357 $this->send_message($user_stranger, $user1, 'Cya!');
0b074e88 1358 $this->send_message($noreplyuser, $user1, 'I am not a real user');
d6731600
FM
1359
1360 // User_blocked sends a message to user1.
1361 $this->send_message($user_blocked, $user1, 'Here, have some spam.');
1362
1363 // Retrieve the contacts of the user.
1364 $this->setUser($user1);
1365 $contacts = core_message_external::get_contacts();
1366 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1367 $this->assertCount(3, $contacts['offline']);
1368 $this->assertCount(1, $contacts['online']);
0b074e88 1369 $this->assertCount(3, $contacts['strangers']);
d6731600 1370 core_message_external::block_contacts(array($user_blocked->id));
f219eac7 1371 $this->assertDebuggingCalled();
d6731600
FM
1372 $contacts = core_message_external::get_contacts();
1373 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1374 $this->assertCount(3, $contacts['offline']);
1375 $this->assertCount(1, $contacts['online']);
0b074e88 1376 $this->assertCount(2, $contacts['strangers']);
d6731600
FM
1377
1378 // Checking some of the fields returned.
1379 $stranger = array_pop($contacts['strangers']);
01393790 1380
0b074e88
JL
1381 $this->assertEquals(core_user::NOREPLY_USER, $stranger['id']);
1382 $this->assertEquals(1, $stranger['unread']);
01393790
JL
1383
1384 // Check that deleted users are not returned.
1385 delete_user($user_offline1);
1386 delete_user($user_stranger);
1387 delete_user($user_online);
1388 $contacts = core_message_external::get_contacts();
1389 $contacts = external_api::clean_returnvalue(core_message_external::get_contacts_returns(), $contacts);
1390 $this->assertCount(2, $contacts['offline']);
1391 $this->assertCount(0, $contacts['online']);
1392 $this->assertCount(1, $contacts['strangers']);
d6731600
FM
1393 }
1394
1395 /**
1396 * Test search_contacts.
52f3e060 1397 * @expectedException moodle_exception
d6731600
FM
1398 */
1399 public function test_search_contacts() {
1400 global $DB;
1401 $this->resetAfterTest(true);
1402
1403 $course1 = $this->getDataGenerator()->create_course();
1404 $course2 = $this->getDataGenerator()->create_course();
1405
1406 $user1 = new stdClass();
1407 $user1->firstname = 'X';
1408 $user1->lastname = 'X';
1409 $user1 = $this->getDataGenerator()->create_user($user1);
1410 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1411 $this->getDataGenerator()->enrol_user($user1->id, $course2->id);
1412
1413 $user2 = new stdClass();
1414 $user2->firstname = 'Eric';
1415 $user2->lastname = 'Cartman';
1416 $user2 = self::getDataGenerator()->create_user($user2);
1417 $user3 = new stdClass();
1418 $user3->firstname = 'Stan';
1419 $user3->lastname = 'Marsh';
1420 $user3 = self::getDataGenerator()->create_user($user3);
1421 self::getDataGenerator()->enrol_user($user3->id, $course1->id);
1422 $user4 = new stdClass();
1423 $user4->firstname = 'Kyle';
1424 $user4->lastname = 'Broflovski';
1425 $user4 = self::getDataGenerator()->create_user($user4);
1426 $user5 = new stdClass();
1427 $user5->firstname = 'Kenny';
1428 $user5->lastname = 'McCormick';
1429 $user5 = self::getDataGenerator()->create_user($user5);
1430 self::getDataGenerator()->enrol_user($user5->id, $course2->id);
1431
d6731600 1432 $this->setUser($user1);
2e2d1977 1433
d6731600
FM
1434 $results = core_message_external::search_contacts('r');
1435 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
2e2d1977
AD
1436 $this->assertCount(5, $results); // Users 2 through 5 + admin
1437
d6731600
FM
1438 $results = core_message_external::search_contacts('r', true);
1439 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1440 $this->assertCount(2, $results);
2e2d1977 1441
d6731600
FM
1442 $results = core_message_external::search_contacts('Kyle', false);
1443 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1444 $this->assertCount(1, $results);
1445 $result = reset($results);
1446 $this->assertEquals($user4->id, $result['id']);
2e2d1977 1447
d6731600
FM
1448 $results = core_message_external::search_contacts('y', false);
1449 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1450 $this->assertCount(2, $results);
2e2d1977 1451
d6731600
FM
1452 $results = core_message_external::search_contacts('y', true);
1453 $results = external_api::clean_returnvalue(core_message_external::search_contacts_returns(), $results);
1454 $this->assertCount(1, $results);
1455 $result = reset($results);
1456 $this->assertEquals($user5->id, $result['id']);
1457
1458 // Empty query, will throw an exception.
d6731600
FM
1459 $results = core_message_external::search_contacts('');
1460 }
6ff4464b
JL
1461
1462 /**
1463 * Test get_messages.
1464 */
1465 public function test_get_messages() {
ea21d637 1466 global $CFG, $DB;
6ff4464b
JL
1467 $this->resetAfterTest(true);
1468
1469 $this->preventResetByRollback();
1470 // This mark the messages as read!.
1471 $sink = $this->redirectMessages();
1472
1473 $user1 = self::getDataGenerator()->create_user();
1474 $user2 = self::getDataGenerator()->create_user();
1475 $user3 = self::getDataGenerator()->create_user();
1476
1477 $course = self::getDataGenerator()->create_course();
1478
1479 // Send a message from one user to another.
1480 message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
1481 message_post_message($user1, $user3, 'some random text 2', FORMAT_MOODLE);
1482 message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
1483 message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
1484 message_post_message($user3, $user1, 'some random text 5', FORMAT_MOODLE);
1485
1486 $this->setUser($user1);
1487 // Get read conversations from user1 to user2.
1488 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
1489 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1490 $this->assertCount(1, $messages['messages']);
1491
ea21d637
JL
1492 // Delete the message.
1493 $message = array_shift($messages['messages']);
883ce421 1494 \core_message\api::delete_message($user1->id, $message['id']);
ea21d637
JL
1495
1496 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', true, true, 0, 0);
1497 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1498 $this->assertCount(0, $messages['messages']);
1499
6ff4464b
JL
1500 // Get unread conversations from user1 to user2.
1501 $messages = core_message_external::get_messages($user2->id, $user1->id, 'conversations', false, true, 0, 0);
1502 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1503 $this->assertCount(0, $messages['messages']);
1504
1505 // Get read messages send from user1.
1506 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1507 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
ea21d637 1508 $this->assertCount(1, $messages['messages']);
6ff4464b
JL
1509
1510 $this->setUser($user2);
1511 // Get read conversations from any user to user2.
1512 $messages = core_message_external::get_messages($user2->id, 0, 'conversations', true, true, 0, 0);
1513 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1514 $this->assertCount(2, $messages['messages']);
1515
ea21d637
JL
1516 // Conversations from user3 to user2.
1517 $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
1518 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1519 $this->assertCount(1, $messages['messages']);
1520
1521 // Delete the message.
1522 $message = array_shift($messages['messages']);
883ce421 1523 \core_message\api::delete_message($user2->id, $message['id']);
ea21d637
JL
1524
1525 $messages = core_message_external::get_messages($user2->id, $user3->id, 'conversations', true, true, 0, 0);
1526 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1527 $this->assertCount(0, $messages['messages']);
1528
6ff4464b
JL
1529 $this->setUser($user3);
1530 // Get read notifications received by user3.
1531 $messages = core_message_external::get_messages($user3->id, 0, 'notifications', true, true, 0, 0);
1532 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1533 $this->assertCount(0, $messages['messages']);
1534
1535 // Now, create some notifications...
1536 // We are creating fake notifications but based on real ones.
1537
39d2c688 1538 // This one comes from a disabled plugin's provider and therefore is not sent.
cc350fd9
AD
1539 $eventdata = new \core\message\message();
1540 $eventdata->courseid = $course->id;
39d2c688 1541 $eventdata->notification = 1;
6ff4464b
JL
1542 $eventdata->modulename = 'moodle';
1543 $eventdata->component = 'enrol_paypal';
1544 $eventdata->name = 'paypal_enrolment';
1545 $eventdata->userfrom = get_admin();
1546 $eventdata->userto = $user1;
1547 $eventdata->subject = "Moodle: PayPal payment";
1548 $eventdata->fullmessage = "Your PayPal payment is pending.";
1549 $eventdata->fullmessageformat = FORMAT_PLAIN;
1550 $eventdata->fullmessagehtml = '';
1551 $eventdata->smallmessage = '';
1552 message_send($eventdata);
39d2c688
DM
1553 $this->assertDebuggingCalled('Attempt to send msg from a provider enrol_paypal/paypal_enrolment '.
1554 'that is inactive or not allowed for the user id='.$user1->id);
1555
1556 // This one omits notification = 1.
1557 $message = new \core\message\message();
1558 $message->courseid = $course->id;
1559 $message->component = 'enrol_manual';
1560 $message->name = 'expiry_notification';
1561 $message->userfrom = $user2;
1562 $message->userto = $user1;
1563 $message->subject = 'Test: This is not a notification but otherwise is valid';
1564 $message->fullmessage = 'Test: Full message';
1565 $message->fullmessageformat = FORMAT_MARKDOWN;
1566 $message->fullmessagehtml = markdown_to_html($message->fullmessage);
1567 $message->smallmessage = $message->subject;
1568 $message->contexturlname = $course->fullname;
1569 $message->contexturl = (string)new moodle_url('/course/view.php', array('id' => $course->id));
1570 message_send($message);
6ff4464b 1571
cc350fd9 1572 $message = new \core\message\message();
880fc15b 1573 $message->courseid = $course->id;
6ff4464b
JL
1574 $message->notification = 1;
1575 $message->component = 'enrol_manual';
1576 $message->name = 'expiry_notification';
1577 $message->userfrom = $user2;
1578 $message->userto = $user1;
1579 $message->subject = 'Enrolment expired';
1580 $message->fullmessage = 'Enrolment expired blah blah blah';
1581 $message->fullmessageformat = FORMAT_MARKDOWN;
1582 $message->fullmessagehtml = markdown_to_html($message->fullmessage);
1583 $message->smallmessage = $message->subject;
1584 $message->contexturlname = $course->fullname;
1585 $message->contexturl = (string)new moodle_url('/course/view.php', array('id' => $course->id));
1586 message_send($message);
1587
1588 $userfrom = core_user::get_noreply_user();
1589 $userfrom->maildisplay = true;
0e8b5160
EM
1590 $eventdata = new \core\message\message();
1591 $eventdata->courseid = $course->id;
6ff4464b
JL
1592 $eventdata->component = 'moodle';
1593 $eventdata->name = 'badgecreatornotice';
1594 $eventdata->userfrom = $userfrom;
1595 $eventdata->userto = $user1;
1596 $eventdata->notification = 1;
1597 $eventdata->subject = 'New badge';
1598 $eventdata->fullmessage = format_text_email($eventdata->subject, FORMAT_HTML);
1599 $eventdata->fullmessageformat = FORMAT_PLAIN;
1600 $eventdata->fullmessagehtml = $eventdata->subject;
1601 $eventdata->smallmessage = $eventdata->subject;
1602 message_send($eventdata);
1603
cc350fd9
AD
1604 $eventdata = new \core\message\message();
1605 $eventdata->courseid = $course->id;
6ff4464b
JL
1606 $eventdata->name = 'submission';
1607 $eventdata->component = 'mod_feedback';
1608 $eventdata->userfrom = $user1;
1609 $eventdata->userto = $user2;
1610 $eventdata->subject = 'Feedback submitted';
1611 $eventdata->fullmessage = 'Feedback submitted from an user';
1612 $eventdata->fullmessageformat = FORMAT_PLAIN;
1613 $eventdata->fullmessagehtml = '<strong>Feedback submitted</strong>';
1614 $eventdata->smallmessage = '';
333d11c9 1615 $eventdata->customdata = ['datakey' => 'data'];
6ff4464b
JL
1616 message_send($eventdata);
1617
1618 $this->setUser($user1);
1619 // Get read notifications from any user to user1.
1620 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 0);
1621 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1622 $this->assertCount(3, $messages['messages']);
1623
1624 // Get one read notifications from any user to user1.
1625 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', true, true, 0, 1);
1626 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1627 $this->assertCount(1, $messages['messages']);
1628
1629 // Get unread notifications from any user to user1.
1630 $messages = core_message_external::get_messages($user1->id, 0, 'notifications', false, true, 0, 0);
1631 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1632 $this->assertCount(0, $messages['messages']);
1633
1634 // Get read both type of messages from any user to user1.
1635 $messages = core_message_external::get_messages($user1->id, 0, 'both', true, true, 0, 0);
1636 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1637 $this->assertCount(4, $messages['messages']);
1638
1639 // Get read notifications from no-reply-user to user1.
1640 $messages = core_message_external::get_messages($user1->id, $userfrom->id, 'notifications', true, true, 0, 0);
1641 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1642 $this->assertCount(1, $messages['messages']);
1643
1644 // Get notifications send by user1 to any user.
1645 $messages = core_message_external::get_messages(0, $user1->id, 'notifications', true, true, 0, 0);
1646 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1647 $this->assertCount(1, $messages['messages']);
333d11c9
JL
1648 // Check we receive custom data as a unserialisable json.
1649 $this->assertObjectHasAttribute('datakey', json_decode($messages['messages'][0]['customdata']));
1650 $this->assertEquals('mod_feedback', $messages['messages'][0]['component']);
1651 $this->assertEquals('submission', $messages['messages'][0]['eventtype']);
6ff4464b
JL
1652
1653 // Test warnings.
1654 $CFG->messaging = 0;
1655
1656 $messages = core_message_external::get_messages(0, $user1->id, 'both', true, true, 0, 0);
1657 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1658 $this->assertCount(1, $messages['warnings']);
1659
1660 // Test exceptions.
1661
1662 // Messaging disabled.
1663 try {
1664 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1665 $this->fail('Exception expected due messaging disabled.');
1666 } catch (moodle_exception $e) {
1667 $this->assertEquals('disabled', $e->errorcode);
1668 }
1669
1670 $CFG->messaging = 1;
1671
1672 // Invalid users.
1673 try {
1674 $messages = core_message_external::get_messages(0, 0, 'conversations', true, true, 0, 0);
1675 $this->fail('Exception expected due invalid users.');
1676 } catch (moodle_exception $e) {
1677 $this->assertEquals('accessdenied', $e->errorcode);
1678 }
1679
1680 // Invalid user ids.
1681 try {
1682 $messages = core_message_external::get_messages(2500, 0, 'conversations', true, true, 0, 0);
1683 $this->fail('Exception expected due invalid users.');
1684 } catch (moodle_exception $e) {
1685 $this->assertEquals('invaliduser', $e->errorcode);
1686 }
1687
1688 // Invalid users (permissions).
1689 $this->setUser($user2);
1690 try {
1691 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', true, true, 0, 0);
1692 $this->fail('Exception expected due invalid user.');
1693 } catch (moodle_exception $e) {
1694 $this->assertEquals('accessdenied', $e->errorcode);
1695 }
1696
1697 }
ff1f3739 1698
c57fadcc
MN
1699 /**
1700 * Test get_messages where we want all messages from a user, sent to any user.
1701 */
1702 public function test_get_messages_useridto_all() {
1703 $this->resetAfterTest(true);
1704
1705 $user1 = self::getDataGenerator()->create_user();
1706 $user2 = self::getDataGenerator()->create_user();
1707 $user3 = self::getDataGenerator()->create_user();
1708
1709 $this->setUser($user1);
1710
1711 // Send a message from user 1 to two other users.
1712 $this->send_message($user1, $user2, 'some random text 1', 0, 1);
1713 $this->send_message($user1, $user3, 'some random text 2', 0, 2);
1714
1715 // Get messages sent from user 1.
1716 $messages = core_message_external::get_messages(0, $user1->id, 'conversations', false, false, 0, 0);
1717 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1718
1719 // Confirm the data is correct.
1720 $messages = $messages['messages'];
1721 $this->assertCount(2, $messages);
1722
1723 $message1 = array_shift($messages);
1724 $message2 = array_shift($messages);
1725
1726 $this->assertEquals($user1->id, $message1['useridfrom']);
1727 $this->assertEquals($user2->id, $message1['useridto']);
1728
1729 $this->assertEquals($user1->id, $message2['useridfrom']);
1730 $this->assertEquals($user3->id, $message2['useridto']);
1731 }
1732
1733 /**
1734 * Test get_messages where we want all messages to a user, sent by any user.
1735 */
1736 public function test_get_messages_useridfrom_all() {
1737 $this->resetAfterTest();
1738
1739 $user1 = self::getDataGenerator()->create_user();
1740 $user2 = self::getDataGenerator()->create_user();
1741 $user3 = self::getDataGenerator()->create_user();
1742
1743 $this->setUser($user1);
1744
1745 // Send a message to user 1 from two other users.
1746 $this->send_message($user2, $user1, 'some random text 1', 0, 1);
1747 $this->send_message($user3, $user1, 'some random text 2', 0, 2);
1748
1749 // Get messages sent to user 1.
1750 $messages = core_message_external::get_messages($user1->id, 0, 'conversations', false, false, 0, 0);
1751 $messages = external_api::clean_returnvalue(core_message_external::get_messages_returns(), $messages);
1752
1753 // Confirm the data is correct.
1754 $messages = $messages['messages'];
1755 $this->assertCount(2, $messages);
1756
1757 $message1 = array_shift($messages);
1758 $message2 = array_shift($messages);
1759
1760 $this->assertEquals($user2->id, $message1['useridfrom']);
1761 $this->assertEquals($user1->id, $message1['useridto']);
1762
1763 $this->assertEquals($user3->id, $message2['useridfrom']);
1764 $this->assertEquals($user1->id, $message2['useridto']);
1765 }
1766
ff1f3739
JL
1767 /**
1768 * Test get_blocked_users.
1769 */
1770 public function test_get_blocked_users() {
1771 $this->resetAfterTest(true);
1772
1773 $user1 = self::getDataGenerator()->create_user();
1774 $userstranger = self::getDataGenerator()->create_user();
1775 $useroffline1 = self::getDataGenerator()->create_user();
1776 $useroffline2 = self::getDataGenerator()->create_user();
1777 $userblocked = self::getDataGenerator()->create_user();
1778
1779 // Login as user1.
1780 $this->setUser($user1);
f219eac7
MN
1781
1782 \core_message\api::add_contact($user1->id, $useroffline1->id);
1783 \core_message\api::add_contact($user1->id, $useroffline2->id);
ff1f3739
JL
1784
1785 // The userstranger sends a couple of messages to user1.
1786 $this->send_message($userstranger, $user1, 'Hello there!');
1787 $this->send_message($userstranger, $user1, 'How you goin?');
1788
1789 // The userblocked sends a message to user1.
1790 // Note that this user is not blocked at this point.
1791 $this->send_message($userblocked, $user1, 'Here, have some spam.');
1792
1793 // Retrieve the list of blocked users.
1794 $this->setUser($user1);
1795 $blockedusers = core_message_external::get_blocked_users($user1->id);
1796 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1797 $this->assertCount(0, $blockedusers['users']);
1798
1799 // Block the $userblocked and retrieve again the list.
1800 core_message_external::block_contacts(array($userblocked->id));
f219eac7 1801 $this->assertDebuggingCalled();
ff1f3739
JL
1802 $blockedusers = core_message_external::get_blocked_users($user1->id);
1803 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1804 $this->assertCount(1, $blockedusers['users']);
1805
01393790
JL
1806 // Remove the $userblocked and check that the list now is empty.
1807 delete_user($userblocked);
1808 $blockedusers = core_message_external::get_blocked_users($user1->id);
1809 $blockedusers = external_api::clean_returnvalue(core_message_external::get_blocked_users_returns(), $blockedusers);
1810 $this->assertCount(0, $blockedusers['users']);
ff1f3739
JL
1811 }
1812
b6795827
JL
1813 /**
1814 * Test mark_message_read.
1815 */
1816 public function test_mark_message_read() {
1817 $this->resetAfterTest(true);
1818
1819 $user1 = self::getDataGenerator()->create_user();
1820 $user2 = self::getDataGenerator()->create_user();
1821 $user3 = self::getDataGenerator()->create_user();
1822
1823 // Login as user1.
1824 $this->setUser($user1);
f219eac7
MN
1825 \core_message\api::add_contact($user1->id, $user2->id);
1826 \core_message\api::add_contact($user1->id, $user3->id);
b6795827
JL
1827
1828 // The user2 sends a couple of messages to user1.
1829 $this->send_message($user2, $user1, 'Hello there!');
1830 $this->send_message($user2, $user1, 'How you goin?');
1831 $this->send_message($user3, $user1, 'How you goin?');
1832 $this->send_message($user3, $user2, 'How you goin?');
1833
1834 // Retrieve all messages sent by user2 (they are currently unread).
1835 $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
1836
1837 $messageids = array();
1838 foreach ($lastmessages as $m) {
1839 $messageid = core_message_external::mark_message_read($m->id, time());
1840 $messageids[] = external_api::clean_returnvalue(core_message_external::mark_message_read_returns(), $messageid);
1841 }
1842
1843 // Retrieve all messages sent (they are currently read).
1844 $lastmessages = message_get_messages($user1->id, $user2->id, 0, true);
1845 $this->assertCount(2, $lastmessages);
1846 $this->assertArrayHasKey($messageids[0]['messageid'], $lastmessages);
1847 $this->assertArrayHasKey($messageids[1]['messageid'], $lastmessages);
1848
1849 // Retrieve all messages sent by any user (that are currently unread).
1850 $lastmessages = message_get_messages($user1->id, 0, 0, false);
1851 $this->assertCount(1, $lastmessages);
1852
1853 // Invalid message ids.
1854 try {
883ce421 1855 $messageid = core_message_external::mark_message_read(1337, time());
b6795827
JL
1856 $this->fail('Exception expected due invalid messageid.');
1857 } catch (dml_missing_record_exception $e) {
883ce421 1858 $this->assertEquals('invalidrecordunknown', $e->errorcode);
b6795827
JL
1859 }
1860
1861 // A message to a different user.
1862 $lastmessages = message_get_messages($user2->id, $user3->id, 0, false);
1863 $messageid = array_pop($lastmessages)->id;
1864 try {
1865 $messageid = core_message_external::mark_message_read($messageid, time());
1866 $this->fail('Exception expected due invalid messageid.');
1867 } catch (invalid_parameter_exception $e) {
1868 $this->assertEquals('invalidparameter', $e->errorcode);
1869 }
2b595d96
MN
1870 }
1871
1872 /**
1873 * Test mark_notification_read.
1874 */
1875 public function test_mark_notification_read() {
1876 $this->resetAfterTest(true);
1877
1878 $user1 = self::getDataGenerator()->create_user();
1879 $user2 = self::getDataGenerator()->create_user();
1880 $user3 = self::getDataGenerator()->create_user();
1881
1882 // Login as user1.
1883 $this->setUser($user1);
f219eac7
MN
1884 \core_message\api::add_contact($user1->id, $user2->id);
1885 \core_message\api::add_contact($user1->id, $user3->id);
b6795827 1886
2b595d96
MN
1887 // The user2 sends a couple of notifications to user1.
1888 $this->send_message($user2, $user1, 'Hello there!', 1);
1889 $this->send_message($user2, $user1, 'How you goin?', 1);
1890 $this->send_message($user3, $user1, 'How you goin?', 1);
1891 $this->send_message($user3, $user2, 'How you goin?', 1);
1892
1893 // Retrieve all notifications sent by user2 (they are currently unread).
1894 $lastnotifications = message_get_messages($user1->id, $user2->id, 1, false);
1895
1896 $notificationids = array();
1897 foreach ($lastnotifications as $n) {
1898 $notificationid = core_message_external::mark_notification_read($n->id, time());
1899 $notificationids[] = external_api::clean_returnvalue(core_message_external::mark_notification_read_returns(),
1900 $notificationid);
1901 }
1902
1903 // Retrieve all notifications sent (they are currently read).
1904 $lastnotifications = message_get_messages($user1->id, $user2->id, 1, true);
1905 $this->assertCount(2, $lastnotifications);
1906 $this->assertArrayHasKey($notificationids[1]['notificationid'], $lastnotifications);
1907 $this->assertArrayHasKey($notificationids[0]['notificationid'], $lastnotifications);
1908
1909 // Retrieve all notifications sent by any user (that are currently unread).
1910 $lastnotifications = message_get_messages($user1->id, 0, 1, false);
1911 $this->assertCount(1, $lastnotifications);
1912
1913 // Invalid notification ids.
1914 try {
1915 $notificationid = core_message_external::mark_notification_read(1337, time());
1916 $this->fail('Exception expected due invalid notificationid.');
1917 } catch (dml_missing_record_exception $e) {
1918 $this->assertEquals('invalidrecord', $e->errorcode);
1919 }
1920
1921 // A notification to a different user.
1922 $lastnotifications = message_get_messages($user2->id, $user3->id, 1, false);
1923 $notificationid = array_pop($lastnotifications)->id;
1924 try {
1925 $notificationid = core_message_external::mark_notification_read($notificationid, time());
1926 $this->fail('Exception expected due invalid notificationid.');
1927 } catch (invalid_parameter_exception $e) {
1928 $this->assertEquals('invalidparameter', $e->errorcode);
1929 }
b6795827
JL
1930 }
1931
419b1128
JL
1932 /**
1933 * Test delete_message.
1934 */
1935 public function test_delete_message() {
1936 global $DB;
1937 $this->resetAfterTest(true);
1938
1939 $user1 = self::getDataGenerator()->create_user();
1940 $user2 = self::getDataGenerator()->create_user();
1941 $user3 = self::getDataGenerator()->create_user();
1942 $user4 = self::getDataGenerator()->create_user();
1943
1944 // Login as user1.
1945 $this->setUser($user1);
f219eac7
MN
1946 \core_message\api::add_contact($user1->id, $user2->id);
1947 \core_message\api::add_contact($user1->id, $user3->id);
419b1128
JL
1948
1949 // User user1 does not interchange messages with user3.
1950 $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE);
1951 $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE);
1952 $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE);
1953 $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE);
1954
1955 // Retrieve all messages sent by user2 (they are currently unread).
1956 $lastmessages = message_get_messages($user1->id, $user2->id, 0, false);
1957
1958 // Delete a message not read, as a user from.
1959 $result = core_message_external::delete_message($m1to2, $user1->id, false);
1960 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1961 $this->assertTrue($result['status']);
1962 $this->assertCount(0, $result['warnings']);
883ce421
MN
1963 $mua = $DB->get_record('message_user_actions', array('messageid' => $m1to2, 'userid' => $user1->id));
1964 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua->action);
419b1128
JL
1965
1966 // Try to delete the same message again.
1967 $result = core_message_external::delete_message($m1to2, $user1->id, false);
1968 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1969 $this->assertFalse($result['status']);
1970
1971 // Try to delete a message that does not belong to me.
1972 try {
1973 $messageid = core_message_external::delete_message($m2to3, $user3->id, false);
1974 $this->fail('Exception expected due invalid messageid.');
1975 } catch (moodle_exception $e) {
1976 $this->assertEquals('You do not have permission to delete this message', $e->errorcode);
1977 }
1978
1979 $this->setUser($user3);
1980 // Delete a message not read, as a user to.
1981 $result = core_message_external::delete_message($m2to3, $user3->id, false);
1982 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1983 $this->assertTrue($result['status']);
1984 $this->assertCount(0, $result['warnings']);
883ce421
MN
1985 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m2to3, 'userid' => $user3->id,
1986 'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
419b1128
JL
1987
1988 // Delete a message read.
548936a6
MN
1989 $message = $DB->get_record('messages', ['id' => $m3to2]);
1990 \core_message\api::mark_message_as_read($user3->id, $message, time());
883ce421 1991 $result = core_message_external::delete_message($m3to2, $user3->id);
419b1128
JL
1992 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
1993 $this->assertTrue($result['status']);
1994 $this->assertCount(0, $result['warnings']);
883ce421
MN
1995 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to2, 'userid' => $user3->id,
1996 'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
419b1128
JL
1997
1998 // Invalid message ids.
1999 try {
2000 $result = core_message_external::delete_message(-1, $user1->id);
2001 $this->fail('Exception expected due invalid messageid.');
2002 } catch (dml_missing_record_exception $e) {
08cb8a34 2003 $this->assertEquals('invalidrecord', $e->errorcode);
419b1128
JL
2004 }
2005
2006 // Invalid user.
2007 try {
2008 $result = core_message_external::delete_message($m1to2, -1, false);
2009 $this->fail('Exception expected due invalid user.');
2010 } catch (moodle_exception $e) {
2011 $this->assertEquals('invaliduser', $e->errorcode);
2012 }
2013
2014 // Not active user.
2015 delete_user($user2);
2016 try {
2017 $result = core_message_external::delete_message($m1to2, $user2->id, false);
2018 $this->fail('Exception expected due invalid user.');
2019 } catch (moodle_exception $e) {
2020 $this->assertEquals('userdeleted', $e->errorcode);
2021 }
2022
2023 // Now, as an admin, try to delete any message.
2024 $this->setAdminUser();
2025 $result = core_message_external::delete_message($m3to4, $user4->id, false);
2026 $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result);
2027 $this->assertTrue($result['status']);
2028 $this->assertCount(0, $result['warnings']);
883ce421
MN
2029 $this->assertTrue($DB->record_exists('message_user_actions', array('messageid' => $m3to4, 'userid' => $user4->id,
2030 'action' => \core_message\api::MESSAGE_ACTION_DELETED)));
419b1128
JL
2031
2032 }
2033
3274d5ca
RW
2034 public function test_mark_all_notifications_as_read_invalid_user_exception() {
2035 $this->resetAfterTest(true);
2036
6aa01968
MN
2037 $this->expectException('moodle_exception');
2038 core_message_external::mark_all_notifications_as_read(-2132131, 0);
3274d5ca
RW
2039 }
2040
2041 public function test_mark_all_notifications_as_read_access_denied_exception() {
2042 $this->resetAfterTest(true);
2043
2044 $sender = $this->getDataGenerator()->create_user();
2045 $user = $this->getDataGenerator()->create_user();
2046
2047 $this->setUser($user);
6aa01968
MN
2048 $this->expectException('moodle_exception');
2049 core_message_external::mark_all_notifications_as_read($sender->id, 0);
3274d5ca
RW
2050 }
2051
2052 public function test_mark_all_notifications_as_read_missing_from_user_exception() {
2053 $this->resetAfterTest(true);
2054
2055 $sender = $this->getDataGenerator()->create_user();
2056
2057 $this->setUser($sender);
6aa01968
MN
2058 $this->expectException('moodle_exception');
2059 core_message_external::mark_all_notifications_as_read($sender->id, 99999);
3274d5ca
RW
2060 }
2061
2062 public function test_mark_all_notifications_as_read() {
7d69958e
RW
2063 global $DB;
2064
3274d5ca
RW
2065 $this->resetAfterTest(true);
2066
2067 $sender1 = $this->getDataGenerator()->create_user();
2068 $sender2 = $this->getDataGenerator()->create_user();
2069 $sender3 = $this->getDataGenerator()->create_user();
2070 $recipient = $this->getDataGenerator()->create_user();
2071
2072 $this->setUser($recipient);
2073
6aa01968
MN
2074 $this->send_message($sender1, $recipient, 'Notification', 1);
2075 $this->send_message($sender1, $recipient, 'Notification', 1);
2076 $this->send_message($sender2, $recipient, 'Notification', 1);
2077 $this->send_message($sender2, $recipient, 'Notification', 1);
2078 $this->send_message($sender3, $recipient, 'Notification', 1);
2079 $this->send_message($sender3, $recipient, 'Notification', 1);
3274d5ca
RW
2080
2081 core_message_external::mark_all_notifications_as_read($recipient->id, $sender1->id);
883ce421
MN
2082 $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]);
2083 $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]);
3274d5ca 2084
7d69958e
RW
2085 $this->assertCount(2, $readnotifications);
2086 $this->assertCount(4, $unreadnotifications);
3274d5ca
RW
2087
2088 core_message_external::mark_all_notifications_as_read($recipient->id, 0);
883ce421
MN
2089 $readnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NOT NULL', [$recipient->id]);
2090 $unreadnotifications = $DB->get_records_select('notifications', 'useridto = ? AND timeread IS NULL', [$recipient->id]);
3274d5ca 2091
7d69958e
RW
2092 $this->assertCount(6, $readnotifications);
2093 $this->assertCount(0, $unreadnotifications);
3274d5ca 2094 }
e86f0cb4
JL
2095
2096 /**
2097 * Test get_user_notification_preferences
2098 */
2099 public function test_get_user_notification_preferences() {
2100 $this->resetAfterTest(true);
2101
2102 $user = self::getDataGenerator()->create_user();
2103 $this->setUser($user);
2104
2105 // Set a couple of preferences to test.
2106 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2107 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2108
2109 $prefs = core_message_external::get_user_notification_preferences();
2110 $prefs = external_api::clean_returnvalue(core_message_external::get_user_notification_preferences_returns(), $prefs);
2111 // Check processors.
46c5c883 2112 $this->assertGreaterThanOrEqual(2, count($prefs['preferences']['processors']));
e86f0cb4
JL
2113 $this->assertEquals($user->id, $prefs['preferences']['userid']);
2114
2115 // Check components.
46c5c883 2116 $this->assertGreaterThanOrEqual(8, count($prefs['preferences']['components']));
e86f0cb4
JL
2117
2118 // Check some preferences that we previously set.
2119 $found = 0;
2120 foreach ($prefs['preferences']['components'] as $component) {
2121 foreach ($component['notifications'] as $prefdata) {
2122 if ($prefdata['preferencekey'] != 'message_provider_mod_assign_assign_notification') {
2123 continue;
2124 }
2125 foreach ($prefdata['processors'] as $processor) {
2126 if ($processor['name'] == 'popup') {
2127 $this->assertTrue($processor['loggedin']['checked']);
2128 $found++;
2129 } else if ($processor['name'] == 'email') {
2130 $this->assertTrue($processor['loggedoff']['checked']);
2131 $found++;
2132 }
2133 }
2134 }
2135 }
2136 $this->assertEquals(2, $found);
2137 }
2138
2139 /**
2140 * Test get_user_notification_preferences permissions
2141 */
2142 public function test_get_user_notification_preferences_permissions() {
2143 $this->resetAfterTest(true);
2144
2145 $user = self::getDataGenerator()->create_user();
2146 $otheruser = self::getDataGenerator()->create_user();
2147 $this->setUser($user);
2148
2149 $this->expectException('moodle_exception');
2150 $prefs = core_message_external::get_user_notification_preferences($otheruser->id);
2151 }
6aa01968
MN
2152
2153 /**
2154 * Tests searching users in a course.
2155 */
548cac7d 2156 public function test_data_for_messagearea_search_users_in_course() {
6aa01968
MN
2157 $this->resetAfterTest(true);
2158
2159 // Create some users.
2160 $user1 = new stdClass();
2161 $user1->firstname = 'User';
2162 $user1->lastname = 'One';
2163 $user1 = self::getDataGenerator()->create_user($user1);
2164
2165 // The person doing the search.
2166 $this->setUser($user1);
2167
2168 // Set the second user's status to online by setting their last access to now.
2169 $user2 = new stdClass();
2170 $user2->firstname = 'User';
2171 $user2->lastname = 'Two';
2172 $user2->lastaccess = time();
2173 $user2 = self::getDataGenerator()->create_user($user2);
2174
2175 // Block the second user.
f219eac7 2176 \core_message\api::block_user($user1->id, $user2->id);
6aa01968
MN
2177
2178 $user3 = new stdClass();
2179 $user3->firstname = 'User';
2180 $user3->lastname = 'Three';
2181 $user3 = self::getDataGenerator()->create_user($user3);
2182
2183 // Create a course.
2184 $course1 = new stdClass();
2185 $course1->fullname = 'Course';
2186 $course1->shortname = 'One';
2187 $course1 = $this->getDataGenerator()->create_course();
2188
2189 // Enrol the user we are doing the search for and one user in the course.
2190 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2191 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2192
2193 // Perform a search.
2194 $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User');
2195
2196 // We need to execute the return values cleaning process to simulate the web service.
2197 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(),
2198 $result);
2199
2200 // Check that we only retrieved a user that was enrolled, and that the user performing the search was not returned.
2201 $users = $result['contacts'];
2202 $this->assertCount(1, $users);
2203
2204 $user = $users[0];
2205 $this->assertEquals($user2->id, $user['userid']);
2206 $this->assertEquals(fullname($user2), $user['fullname']);
2207 $this->assertFalse($user['ismessaging']);
2208 $this->assertFalse($user['sentfromcurrentuser']);
2209 $this->assertNull($user['lastmessage']);
2210 $this->assertNull($user['messageid']);
cb805753 2211 $this->assertNull($user['isonline']);
6aa01968
MN
2212 $this->assertFalse($user['isread']);
2213 $this->assertTrue($user['isblocked']);
2214 $this->assertNull($user['unreadcount']);
2215 }
2216
2217 /**
2218 * Tests searching users in course as another user.
2219 */
548cac7d 2220 public function test_data_for_messagearea_search_users_in_course_as_other_user() {
6aa01968
MN
2221 $this->resetAfterTest(true);
2222
2223 // The person doing the search for another user.
2224 $this->setAdminUser();
2225
2226 // Create some users.
2227 $user1 = new stdClass();
2228 $user1->firstname = 'User';
2229 $user1->lastname = 'One';
2230 $user1 = self::getDataGenerator()->create_user($user1);
2231
2232 $user2 = new stdClass();
2233 $user2->firstname = 'User';
2234 $user2->lastname = 'Two';
2235 $user2 = self::getDataGenerator()->create_user($user2);
2236
2237 $user3 = new stdClass();
2238 $user3->firstname = 'User';
2239 $user3->lastname = 'Three';
2240 $user3 = self::getDataGenerator()->create_user($user3);
2241
2242 // Create a course.
2243 $course1 = new stdClass();
2244 $course1->fullname = 'Course';
2245 $course1->shortname = 'One';
2246 $course1 = $this->getDataGenerator()->create_course();
2247
2248 // Enrol the user we are doing the search for and one user in the course.
2249 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
2250 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
2251
2252 // Perform a search.
2253 $result = core_message_external::data_for_messagearea_search_users_in_course($user1->id, $course1->id, 'User');
2254
2255 // We need to execute the return values cleaning process to simulate the web service server.
2256 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_in_course_returns(),
2257 $result);
2258
2259 // Check that we got the user enrolled, and that the user we are performing the search on behalf of was not returned.
2260 $users = $result['contacts'];
2261 $this->assertCount(1, $users);
2262
2263 $user = $users[0];
2264 $this->assertEquals($user2->id, $user['userid']);
2265 $this->assertEquals(fullname($user2), $user['fullname']);
2266 $this->assertFalse($user['ismessaging']);
2267 $this->assertFalse($user['sentfromcurrentuser']);
2268 $this->assertNull($user['lastmessage']);
2269 $this->assertNull($user['messageid']);
2270 $this->assertFalse($user['isonline']);
2271 $this->assertFalse($user['isread']);
2272 $this->assertFalse($user['isblocked']);
2273 $this->assertNull($user['unreadcount']);
2274 }
2275
2276 /**
2277 * Tests searching users in course as another user without the proper capabilities.
2278 */
548cac7d 2279 public function test_data_for_messagearea_search_users_in_course_as_other_user_without_cap() {
6aa01968
MN
2280 $this->resetAfterTest(true);
2281
2282 // Create some users.
2283 $user1 = self::getDataGenerator()->create_user();
2284 $user2 = self::getDataGenerator()->create_user();
2285
2286 // The person doing the search for another user.
2287 $this->setUser($user1);
2288
2289 // Create a course.
2290 $course = $this->getDataGenerator()->create_course();
2291
2292 // Ensure an exception is thrown.
2293 $this->expectException('moodle_exception');
2294 core_message_external::data_for_messagearea_search_users_in_course($user2->id, $course->id, 'User');
548cac7d 2295 $this->assertDebuggingCalled();
6aa01968
MN
2296 }
2297
2298 /**
2299 * Tests searching users in course with messaging disabled.
2300 */
548cac7d 2301 public function test_data_for_messagearea_search_users_in_course_messaging_disabled() {
6aa01968
MN
2302 global $CFG;
2303
2304 $this->resetAfterTest(true);
2305
2306 // Create some skeleton data just so we can call the WS..
2307 $user = self::getDataGenerator()->create_user();
2308 $course = $this->getDataGenerator()->create_course();
2309
2310 // The person doing the search for another user.
2311 $this->setUser($user);
2312
2313 // Disable messaging.
2314 $CFG->messaging = 0;
2315
2316 // Ensure an exception is thrown.
2317 $this->expectException('moodle_exception');
2318 core_message_external::data_for_messagearea_search_users_in_course($user->id, $course->id, 'User');
548cac7d 2319 $this->assertDebuggingCalled();
6aa01968
MN
2320 }
2321
2322 /**
2323 * Tests searching users.
2324 */
548cac7d 2325 public function test_data_for_messagearea_search_users() {
6aa01968
MN
2326 $this->resetAfterTest(true);
2327
2328 // Create some users.
2329 $user1 = new stdClass();
2330 $user1->firstname = 'User';
2331 $user1->lastname = 'One';
2332 $user1 = self::getDataGenerator()->create_user($user1);
2333
2334 // Set as the user performing the search.
2335 $this->setUser($user1);
2336
2337 $user2 = new stdClass();
2338 $user2->firstname = 'User search';
2339 $user2->lastname = 'Two';
2340 $user2 = self::getDataGenerator()->create_user($user2);
2341
2342 $user3 = new stdClass();
2343 $user3->firstname = 'User search';
2344 $user3->lastname = 'Three';
2345 $user3 = self::getDataGenerator()->create_user($user3);
2346
2347 $user4 = new stdClass();
2348 $user4->firstname = 'User';
2349 $user4->lastname = 'Four';
2350 $user4 = self::getDataGenerator()->create_user($user4);
2351
2352 $user5 = new stdClass();
2353 $user5->firstname = 'User search';
2354 $user5->lastname = 'Five';
2355 $user5 = self::getDataGenerator()->create_user($user5);
2356
2357 $user6 = new stdClass();
2358 $user6->firstname = 'User';
2359 $user6->lastname = 'Six';
2360 $user6 = self::getDataGenerator()->create_user($user6);
2361
2362 // Create some courses.
2363 $course1 = new stdClass();
2364 $course1->fullname = 'Course search';
2365 $course1->shortname = 'One';
2366 $course1 = $this->getDataGenerator()->create_course($course1);
2367
2368 $course2 = new stdClass();
2369 $course2->fullname = 'Course';
2370 $course2->shortname = 'Two';
2371 $course2 = $this->getDataGenerator()->create_course($course2);
2372
2373 $course3 = new stdClass();
2374 $course3->fullname = 'Course';
2375 $course3->shortname = 'Three search';
2376 $course3 = $this->getDataGenerator()->create_course($course3);
2377
87d4ab65
AG
2378 $course4 = new stdClass();
2379 $course4->fullname = 'Course Four';
2380 $course4->shortname = 'CF100';
2381 $course4 = $this->getDataGenerator()->create_course($course4);
2382
2383 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 'student');
2384 $this->getDataGenerator()->enrol_user($user1->id, $course2->id, 'student');
2385 $this->getDataGenerator()->enrol_user($user1->id, $course3->id, 'student');
2386
6aa01968 2387 // Add some users as contacts.
f219eac7
MN
2388 \core_message\api::add_contact($user1->id, $user2->id);
2389 \core_message\api::add_contact($user1->id, $user3->id);
2390 \core_message\api::add_contact($user1->id, $user4->id);
6aa01968 2391
548cac7d
AA
2392 // Perform a search $CFG->messagingallusers setting enabled.
2393 set_config('messagingallusers', 1);
6aa01968
MN
2394 $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
2395
2396 // We need to execute the return values cleaning process to simulate the web service server.
2397 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(),
2398 $result);
2399
2400 // Confirm that we returns contacts, courses and non-contacts.
2401 $contacts = $result['contacts'];
2402 $courses = $result['courses'];
2403 $noncontacts = $result['noncontacts'];
2404
2405 // Check that we retrieved the correct contacts.
2406 $this->assertCount(2, $contacts);
2407 $this->assertEquals($user3->id, $contacts[0]['userid']);
2408 $this->assertEquals($user2->id, $contacts[1]['userid']);
2409
2410 // Check that we retrieved the correct courses.
2411 $this->assertCount(2, $courses);
2412 $this->assertEquals($course3->id, $courses[0]['id']);
2413 $this->assertEquals($course1->id, $courses[1]['id']);
2414
2415 // Check that we retrieved the correct non-contacts.
2416 $this->assertCount(1, $noncontacts);
2417 $this->assertEquals($user5->id, $noncontacts[0]['userid']);
2418 }
2419
2420 /**
2421 * Tests searching users as another user.
2422 */
548cac7d 2423 public function test_data_for_messagearea_search_users_as_other_user() {
6aa01968
MN
2424 $this->resetAfterTest(true);
2425
2426 // The person doing the search.
2427 $this->setAdminUser();
2428
2429 // Create some users.
2430 $user1 = new stdClass();
2431 $user1->firstname = 'User';
2432 $user1->lastname = 'One';
2433 $user1 = self::getDataGenerator()->create_user($user1);
2434
2435 $user2 = new stdClass();
2436 $user2->firstname = 'User search';
2437 $user2->lastname = 'Two';
2438 $user2 = self::getDataGenerator()->create_user($user2);
2439
2440 $user3 = new stdClass();
2441 $user3->firstname = 'User search';
2442 $user3->lastname = 'Three';
2443 $user3 = self::getDataGenerator()->create_user($user3);
2444
2445 $user4 = new stdClass();
2446 $user4->firstname = 'User';
2447 $user4->lastname = 'Four';
2448 $user4 = self::getDataGenerator()->create_user($user4);
2449
2450 $user5 = new stdClass();
2451 $user5->firstname = 'User search';
2452 $user5->lastname = 'Five';
2453 $user5 = self::getDataGenerator()->create_user($user5);
2454
2455 $user6 = new stdClass();
2456 $user6->firstname = 'User';
2457 $user6->lastname = 'Six';
2458 $user6 = self::getDataGenerator()->create_user($user6);
2459
2460 // Create some courses.
2461 $course1 = new stdClass();
2462 $course1->fullname = 'Course search';
2463 $course1->shortname = 'One';
2464 $course1 = $this->getDataGenerator()->create_course($course1);
2465
2466 $course2 = new stdClass();
2467 $course2->fullname = 'Course';
2468 $course2->shortname = 'Two';
2469 $course2 = $this->getDataGenerator()->create_course($course2);
2470
2471 $course3 = new stdClass();
2472 $course3->fullname = 'Course';
2473 $course3->shortname = 'Three search';
2474 $course3 = $this->getDataGenerator()->create_course($course3);
2475
2476 // Add some users as contacts.
f219eac7
MN
2477 \core_message\api::add_contact($user1->id, $user2->id);
2478 \core_message\api::add_contact($user1->id, $user3->id);
2479 \core_message\api::add_contact($user1->id, $user4->id);
6aa01968 2480
548cac7d
AA
2481 // Perform a search $CFG->messagingallusers setting enabled.
2482 set_config('messagingallusers', 1);
6aa01968
MN
2483 $result = core_message_external::data_for_messagearea_search_users($user1->id, 'search');
2484
2485 // We need to execute the return values cleaning process to simulate the web service server.
2486 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_users_returns(),
2487 $result);
2488
2489 // Confirm that we returns contacts, courses and non-contacts.
2490 $contacts = $result['contacts'];
2491 $courses = $result['courses'];
2492 $noncontacts = $result['noncontacts'];
2493
2494 // Check that we retrieved the correct contacts.
2495 $this->assertCount(2, $contacts);
2496 $this->assertEquals($user3->id, $contacts[0]['userid']);
2497 $this->assertEquals($user2->id, $contacts[1]['userid']);
2498
2499 // Check that we retrieved the correct courses.
87d4ab65 2500 $this->assertCount(0, $courses);
6aa01968
MN
2501
2502 // Check that we retrieved the correct non-contacts.
2503 $this->assertCount(1, $noncontacts);
2504 $this->assertEquals($user5->id, $noncontacts[0]['userid']);
2505 }
2506
2507 /**
2508 * Tests searching users as another user without the proper capabilities.
2509 */
548cac7d 2510 public function test_data_for_messagearea_search_users_as_other_user_without_cap() {
6aa01968
MN
2511 $this->resetAfterTest(true);
2512
2513 // Create some users.
2514 $user1 = self::getDataGenerator()->create_user();
2515 $user2 = self::getDataGenerator()->create_user();
2516
2517 // The person doing the search for another user.
2518 $this->setUser($user1);
2519
2520 // Ensure an exception is thrown.
2521 $this->expectException('moodle_exception');
2522 core_message_external::data_for_messagearea_search_users($user2->id, 'User');
548cac7d 2523 $this->assertDebuggingCalled();
6aa01968
MN
2524 }
2525
2526 /**
2527 * Tests searching users with messaging disabled.
2528 */
548cac7d 2529 public function test_data_for_messagearea_search_users_messaging_disabled() {
6aa01968
MN
2530 global $CFG;
2531
2532 $this->resetAfterTest(true);
2533
2534 // Create some skeleton data just so we can call the WS.
2535 $user = self::getDataGenerator()->create_user();
2536
2537 // The person doing the search.
2538 $this->setUser($user);
2539
2540 // Disable messaging.
2541 $CFG->messaging = 0;
2542
2543 // Ensure an exception is thrown.
2544 $this->expectException('moodle_exception');
2545 core_message_external::data_for_messagearea_search_users($user->id, 'User');
548cac7d
AA
2546 $this->assertDebuggingCalled();
2547 }
2548
2549 /**
41485be2
JD
2550 * Tests searching for users when site-wide messaging is disabled.
2551 *
2552 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
2553 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
2554 * profile.
548cac7d 2555 */
41485be2 2556 public function test_message_search_users_messagingallusers_disabled() {
3edac090 2557 global $DB;
41485be2 2558 $this->resetAfterTest();
548cac7d
AA
2559
2560 // Create some users.
41485be2 2561 $users = [];
3edac090 2562 foreach (range(1, 8) as $i) {
41485be2
JD
2563 $user = new stdClass();
2564 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2565 $user->lastname = $i;
2566 $user = $this->getDataGenerator()->create_user($user);
2567 $users[$i] = $user;
2568 }
548cac7d 2569
41485be2
JD
2570 // Enrol a few users in the same course, but leave them as non-contacts.
2571 $course1 = $this->getDataGenerator()->create_course();
3edac090
JD
2572 $course2 = $this->getDataGenerator()->create_course();
2573
41485be2
JD
2574 $this->setAdminUser();
2575 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2576 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2577 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
548cac7d 2578
41485be2
JD
2579 // Add some other users as contacts.
2580 \core_message\api::add_contact($users[1]->id, $users[2]->id);
2581 \core_message\api::add_contact($users[3]->id, $users[1]->id);
2582 \core_message\api::add_contact($users[1]->id, $users[4]->id);
548cac7d 2583
3edac090
JD
2584 // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
2585 $this->getDataGenerator()->enrol_user($users[8]->id, $course2->id, 'editingteacher');
2586 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
2587 set_config('coursecontact', $teacherrole->id);
2588
41485be2 2589 // Create individual conversations between some users, one contact and one non-contact.
548cac7d 2590 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
41485be2 2591 [$users[1]->id, $users[2]->id]);
548cac7d 2592 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
41485be2 2593 [$users[6]->id, $users[1]->id]);
548cac7d 2594
41485be2
JD
2595 // Create a group conversation between 4 users, including a contact and a non-contact.
2596 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2597 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
548cac7d 2598
41485be2
JD
2599 // Set as the user performing the search.
2600 $this->setUser($users[1]);
548cac7d 2601
41485be2 2602 // Perform a search with $CFG->messagingallusers disabled.
548cac7d 2603 set_config('messagingallusers', 0);
41485be2
JD
2604 $result = core_message_external::message_search_users($users[1]->id, 'search');
2605 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
548cac7d
AA
2606
2607 // Confirm that we returns contacts and non-contacts.
41485be2
JD
2608 $this->assertArrayHasKey('contacts', $result);
2609 $this->assertArrayHasKey('noncontacts', $result);
548cac7d
AA
2610 $contacts = $result['contacts'];
2611 $noncontacts = $result['noncontacts'];
2612
2613 // Check that we retrieved the correct contacts.
2614 $this->assertCount(2, $contacts);
41485be2
JD
2615 $this->assertEquals($users[2]->id, $contacts[0]['id']);
2616 $this->assertEquals($users[3]->id, $contacts[1]['id']);
2617
2618 // Verify the correct conversations were returned for the contacts.
2619 $this->assertCount(2, $contacts[0]['conversations']);
2620 // We can't rely on the ordering of conversations within the results, so sort by id first.
2621 usort($contacts[0]['conversations'], function($a, $b) {
2622 return $a['id'] < $b['id'];
2623 });
2624 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']);
2625 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']);
2626
2627 $this->assertCount(0, $contacts[1]['conversations']);
548cac7d
AA
2628
2629 // Check that we retrieved the correct non-contacts.
3edac090
JD
2630 // When site wide messaging is disabled, we expect to see only those users who we share a course with and whose profiles
2631 // are visible in that course. This excludes users like course contacts.
888a467a
AA
2632 $this->assertCount(3, $noncontacts);
2633 // Self-conversation first.
2634 $this->assertEquals($users[1]->id, $noncontacts[0]['id']);
2635 $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2636 $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
41485be2
JD
2637
2638 // Verify the correct conversations were returned for the non-contacts.
41485be2 2639 $this->assertCount(1, $noncontacts[1]['conversations']);
888a467a
AA
2640 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[1]['conversations'][0]['type']);
2641
2642 $this->assertCount(1, $noncontacts[2]['conversations']);
2643 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]['conversations'][0]['type']);
548cac7d
AA
2644 }
2645
2646 /**
41485be2
JD
2647 * Tests searching for users when site-wide messaging is enabled.
2648 *
2649 * This test verifies that any contacts are returned, as well as any non-contacts, regardless of whether the searching user
2650 * can view their respective profile.
548cac7d 2651 */
41485be2 2652 public function test_message_search_users_messagingallusers_enabled() {
3edac090 2653 global $DB;
41485be2 2654 $this->resetAfterTest();
548cac7d
AA
2655
2656 // Create some users.
41485be2 2657 $users = [];
3edac090 2658 foreach (range(1, 9) as $i) {
41485be2
JD
2659 $user = new stdClass();
2660 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2661 $user->lastname = $i;
2662 $user = $this->getDataGenerator()->create_user($user);
2663 $users[$i] = $user;
2664 }
548cac7d 2665
41485be2
JD
2666 // Enrol a few users in the same course, but leave them as non-contacts.
2667 $course1 = $this->getDataGenerator()->create_course();
3edac090
JD
2668 $course2 = $this->getDataGenerator()->create_course();
2669
41485be2
JD
2670 $this->setAdminUser();
2671 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2672 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2673 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
548cac7d 2674
41485be2
JD
2675 // Add some other users as contacts.
2676 \core_message\api::add_contact($users[1]->id, $users[2]->id);
2677 \core_message\api::add_contact($users[3]->id, $users[1]->id);
2678 \core_message\api::add_contact($users[1]->id, $users[4]->id);
548cac7d 2679
3edac090
JD
2680 // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
2681 $this->getDataGenerator()->enrol_user($users[9]->id, $course2->id, 'editingteacher');
2682 $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
2683 set_config('coursecontact', $teacherrole->id);
2684
41485be2 2685 // Create individual conversations between some users, one contact and one non-contact.
548cac7d 2686 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
41485be2 2687 [$users[1]->id, $users[2]->id]);
548cac7d 2688 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
41485be2 2689 [$users[6]->id, $users[1]->id]);
548cac7d 2690
41485be2
JD
2691 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
2692 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2693 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
548cac7d 2694
41485be2
JD
2695 // Set as the user performing the search.
2696 $this->setUser($users[1]);
2697
2698 // Perform a search with $CFG->messagingallusers enabled.
2699 set_config('messagingallusers', 1);
2700 $result = core_message_external::message_search_users($users[1]->id, 'search');
2701 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
548cac7d
AA
2702
2703 // Confirm that we returns contacts and non-contacts.
41485be2
JD
2704 $this->assertArrayHasKey('contacts', $result);
2705 $this->assertArrayHasKey('noncontacts', $result);
548cac7d
AA
2706 $contacts = $result['contacts'];
2707 $noncontacts = $result['noncontacts'];
2708
2709 // Check that we retrieved the correct contacts.
2710 $this->assertCount(2, $contacts);
41485be2
JD
2711 $this->assertEquals($users[2]->id, $contacts[0]['id']);
2712 $this->assertEquals($users[3]->id, $contacts[1]['id']);
548cac7d 2713
41485be2
JD
2714 // Verify the correct conversations were returned for the contacts.
2715 $this->assertCount(2, $contacts[0]['conversations']);
2716 // We can't rely on the ordering of conversations within the results, so sort by id first.
2717 usort($contacts[0]['conversations'], function($a, $b) {
2718 return $a['id'] < $b['id'];
2719 });
2720 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]['conversations'][0]['type']);
2721 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]['conversations'][1]['type']);
548cac7d 2722
41485be2 2723 $this->assertCount(0, $contacts[1]['conversations']);
548cac7d 2724
41485be2 2725 // Check that we retrieved the correct non-contacts.
3edac090
JD
2726 // If site wide messaging is enabled, we expect to be able to search for any users whose profiles we can view.
2727 // In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1.
888a467a
AA
2728 $this->assertCount(4, $noncontacts);
2729 $this->assertEquals($users[1]->id, $noncontacts[0]['id']);
2730 $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2731 $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
2732 $this->assertEquals($users[9]->id, $noncontacts[3]['id']);
41485be2
JD
2733
2734 // Verify the correct conversations were returned for the non-contacts.
41485be2 2735 $this->assertCount(1, $noncontacts[1]['conversations']);
888a467a
AA
2736 $this->assertCount(1, $noncontacts[2]['conversations']);
2737 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $noncontacts[1]['conversations'][0]['type']);
2738 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]['conversations'][0]['type']);
2739 $this->assertCount(0, $noncontacts[3]['conversations']);
548cac7d
AA
2740 }
2741
734b198f
SA
2742 /**
2743 * Verify searching for users find themselves when they have self-conversations.
2744 */
2745 public function test_message_search_users_self_conversations() {
2746 $this->resetAfterTest();
2747
2748 // Create some users.
2749 $user1 = new stdClass();
2750 $user1->firstname = 'User';
2751 $user1->lastname = 'One';
2752 $user1 = $this->getDataGenerator()->create_user($user1);
2753 $user2 = new stdClass();
2754 $user2->firstname = 'User';
2755 $user2->lastname = 'Two';
2756 $user2 = $this->getDataGenerator()->create_user($user2);
2757
888a467a
AA
2758 // Get self-conversation for user1.
2759 $sc1 = \core_message\api::get_self_conversation($user1->id);
734b198f
SA
2760 testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi myself!');
2761
2762 // Perform a search as user1.
2763 $this->setUser($user1);
2764 $result = core_message_external::message_search_users($user1->id, 'One');
2765 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2766
2767 // Check results are empty.
2768 $this->assertCount(0, $result['contacts']);
2769 $this->assertCount(1, $result['noncontacts']);
2770 }
2771
548cac7d 2772 /**
41485be2 2773 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
548cac7d 2774 */
41485be2
JD
2775 public function test_message_search_users_with_empty_result() {
2776 $this->resetAfterTest();
548cac7d 2777
41485be2
JD
2778 // Create some users, but make sure neither will match the search term.
2779 $user1 = new stdClass();
2780 $user1->firstname = 'User';
2781 $user1->lastname = 'One';
2782 $user1 = $this->getDataGenerator()->create_user($user1);
2783 $user2 = new stdClass();
2784 $user2->firstname = 'User';
2785 $user2->lastname = 'Two';
2786 $user2 = $this->getDataGenerator()->create_user($user2);
548cac7d 2787
41485be2 2788 // Perform a search as user1.
548cac7d 2789 $this->setUser($user1);
41485be2
JD
2790 $result = core_message_external::message_search_users($user1->id, 'search');
2791 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
548cac7d 2792
41485be2
JD
2793 // Check results are empty.
2794 $this->assertCount(0, $result['contacts']);
2795 $this->assertCount(0, $result['noncontacts']);
548cac7d
AA
2796 }
2797
2798 /**
41485be2 2799 * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
548cac7d 2800 */
41485be2
JD
2801 public function test_message_search_users_limit_offset() {
2802 $this->resetAfterTest();
548cac7d 2803
41485be2
JD
2804 // Create 20 users.
2805 $users = [];
2806 foreach (range(1, 20) as $i) {
2807 $user = new stdClass();
2808 $user->firstname = "User search";
2809 $user->lastname = $i;
2810 $user = $this->getDataGenerator()->create_user($user);
2811 $users[$i] = $user;
2812 }
2813
e4987f0f 2814 // Enrol the first 8 users in the same course, but leave them as non-contacts.
41485be2
JD
2815 $this->setAdminUser();
2816 $course1 = $this->getDataGenerator()->create_course();
888a467a 2817 foreach (range(1, 8) as $i) {
41485be2
JD
2818 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
2819 }
2820
2821 // Add 5 users, starting at the 11th user, as contacts for user1.
2822 foreach (range(11, 15) as $i) {
2823 \core_message\api::add_contact($users[1]->id, $users[$i]->id);
2824 }
548cac7d
AA
2825
2826 // Set as the user performing the search.
41485be2 2827 $this->setUser($users[1]);
548cac7d 2828
41485be2
JD
2829 // Search using a limit of 3.
2830 // This tests the case where we have more results than the limit for both contacts and non-contacts.
2831 $result = core_message_external::message_search_users($users[1]->id, 'search', 0, 3);
2832 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2833 $contacts = $result['contacts'];
2834 $noncontacts = $result['noncontacts'];
548cac7d 2835
41485be2
JD
2836 // Check that we retrieved the correct contacts.
2837 $this->assertCount(3, $contacts);
2838 $this->assertEquals($users[11]->id, $contacts[0]['id']);
2839 $this->assertEquals($users[12]->id, $contacts[1]['id']);
2840 $this->assertEquals($users[13]->id, $contacts[2]['id']);
548cac7d 2841
41485be2 2842 // Check that we retrieved the correct non-contacts.
888a467a 2843 // Consider first conversation is self-conversation.
41485be2 2844 $this->assertCount(3, $noncontacts);
888a467a
AA
2845 $this->assertEquals($users[1]->id, $noncontacts[0]['id']);
2846 $this->assertEquals($users[2]->id, $noncontacts[1]['id']);
2847 $this->assertEquals($users[3]->id, $noncontacts[2]['id']);
41485be2
JD
2848
2849 // Now, offset to get the next batch of results.
2850 // We expect to see 2 contacts, and 3 non-contacts.
2851 $result = core_message_external::message_search_users($users[1]->id, 'search', 3, 3);
2852 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2853 $contacts = $result['contacts'];
2854 $noncontacts = $result['noncontacts'];
2855 $this->assertCount(2, $contacts);
2856 $this->assertEquals($users[14]->id, $contacts[0]['id']);
2857 $this->assertEquals($users[15]->id, $contacts[1]['id']);
548cac7d 2858
41485be2 2859 $this->assertCount(3, $noncontacts);
888a467a
AA
2860 $this->assertEquals($users[4]->id, $noncontacts[0]['id']);
2861 $this->assertEquals($users[5]->id, $noncontacts[1]['id']);
2862 $this->assertEquals($users[6]->id, $noncontacts[2]['id']);
41485be2
JD
2863
2864 // Now, offset to get the next batch of results.
2865 // We expect to see 0 contacts, and 2 non-contacts.
2866 $result = core_message_external::message_search_users($users[1]->id, 'search', 6, 3);
2867 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
2868 $contacts = $result['contacts'];
2869 $noncontacts = $result['noncontacts'];
2870 $this->assertCount(0, $contacts);
548cac7d 2871
41485be2 2872 $this->assertCount(2, $noncontacts);
888a467a
AA
2873 $this->assertEquals($users[7]->id, $noncontacts[0]['id']);
2874 $this->assertEquals($users[8]->id, $noncontacts[1]['id']);
41485be2 2875 }
548cac7d 2876
41485be2
JD
2877 /**
2878 * Tests searching users as another user having the 'moodle/user:viewdetails' capability.
2879 */
2880 public function test_message_search_users_with_cap() {
2881 $this->resetAfterTest();
2882 global $DB;
548cac7d 2883
41485be2
JD
2884 // Create some users.
2885 $users = [];
2886 foreach (range(1, 8) as $i) {
2887 $user = new stdClass();
2888 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
2889 $user->lastname = $i;
2890 $user = $this->getDataGenerator()->create_user($user);
2891 $users[$i] = $user;
2892 }
548cac7d 2893
41485be2
JD
2894 // Enrol a few users in the same course, but leave them as non-contacts.
2895 $course1 = $this->getDataGenerator()->create_course();
2896 $this->setAdminUser();
2897 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
2898 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
2899 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
548cac7d 2900
41485be2
JD
2901 // Add some other users as contacts.
2902 \core_message\api::add_contact($users[1]->id, $users[2]->id);
2903 \core_message\api::add_contact($users[3]->id, $users[1]->id);
2904 \core_message\api::add_contact($users[1]->id, $users[4]->id);
548cac7d 2905
41485be2
JD
2906 // Set as the user performing the search.
2907 $this->setUser($users[1]);
2908
2909 // Grant the authenticated user role the capability 'user:viewdetails' at site context.
2910 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
2911 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance());
2912
2913 // Perform a search with $CFG->messagingallusers disabled.
2914 set_config('messagingallusers', 0);
2915 $result = core_message_external::message_search_users($users[1]->id, 'search');
2916 $result = external_api::clean_returnvalue(core_message_external::message_search_users_returns(), $result);
548cac7d
AA
2917 $contacts = $result['contacts'];
2918 $noncontacts = $result['noncontacts'];
2919
2920 // Check that we retrieved the correct contacts.
41485be2
JD
2921 $this->assertCount(2, $contacts);
2922 $this->assertEquals($users[2]->id, $contacts[0]['id']);
2923 $this->assertEquals($users[3]->id, $contacts[1]['id']);
548cac7d
AA
2924
2925 // Check that we retrieved the correct non-contacts.
3edac090 2926 // Site-wide messaging is disabled, so we expect to be able to search for any users whose profile we can view.
888a467a
AA
2927 // Consider first conversations is self-conversation.
2928 $this->assertCount(3, $noncontacts);
2929 $this->assertEquals($users[1]->id, $noncontacts[0]['id']);
2930 $this->assertEquals($users[6]->id, $noncontacts[1]['id']);
2931 $this->assertEquals($users[7]->id, $noncontacts[2]['id']);
41485be2 2932 }
548cac7d 2933
41485be2
JD
2934 /**
2935 * Tests searching users as another user without the 'moodle/user:viewdetails' capability.
2936 */
2937 public function test_message_search_users_without_cap() {
2938 $this->resetAfterTest();
2939
2940 // Create some users.
2941 $user1 = $this->getDataGenerator()->create_user();
2942 $user2 = $this->getDataGenerator()->create_user();
2943
2944 // The person doing the search for another user.
2945 $this->setUser($user1);
2946
2947 // Ensure an exception is thrown.
2948 $this->expectException('moodle_exception');
2949 core_message_external::message_search_users($user2->id, 'User');
2950 $this->assertDebuggingCalled();
548cac7d
AA
2951 }
2952
2953 /**
2954 * Tests searching users with messaging disabled.
2955 */
2956 public function test_message_search_users_messaging_disabled() {
41485be2 2957 $this->resetAfterTest();
548cac7d
AA
2958
2959 // Create some skeleton data just so we can call the WS.
41485be2 2960 $user = $this->getDataGenerator()->create_user();
548cac7d
AA
2961
2962 // The person doing the search.
2963 $this->setUser($user);
2964
2965 // Disable messaging.
2966 set_config('messaging', 0);
2967
2968 // Ensure an exception is thrown.
2969 $this->expectException('moodle_exception');
2970 core_message_external::message_search_users($user->id, 'User');
6aa01968
MN
2971 }
2972
2973 /**
2974 * Tests searching messages.
2975 */
2976 public function test_messagearea_search_messages() {
2977 $this->resetAfterTest(true);
2978
2979 // Create some users.
2980 $user1 = self::getDataGenerator()->create_user();
2981 $user2 = self::getDataGenerator()->create_user();
2982
2983 // The person doing the search.
2984 $this->setUser($user1);
2985
2986 // Send some messages back and forth.
2987 $time = time();
2988 $this->send_message($user1, $user2, 'Yo!', 0, $time);
2989 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
2990 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
2991 $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
d2708759 2992 $convid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
6aa01968
MN
2993
2994 // Perform a search.
2995 $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o');
2996
2997 // We need to execute the return values cleaning process to simulate the web service server.
d2708759 2998 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(), $result);
6aa01968
MN
2999
3000 // Confirm the data is correct.
3001 $messages = $result['contacts'];
3002 $this->assertCount(2, $messages);
3003
3004 $message1 = $messages[0];
3005 $message2 = $messages[1];
3006
3007 $this->assertEquals($user2->id, $message1['userid']);
3008 $this->assertEquals(fullname($user2), $message1['fullname']);
3009 $this->assertTrue($message1['ismessaging']);
3010 $this->assertFalse($message1['sentfromcurrentuser']);
3011 $this->assertEquals('Word.', $message1['lastmessage']);
3012 $this->assertNotEmpty($message1['messageid']);
cb805753 3013 $this->assertNull($message1['isonline']);
6aa01968
MN
3014 $this->assertFalse($message1['isread']);
3015 $this->assertFalse($message1['isblocked']);
3016 $this->assertNull($message1['unreadcount']);
d2708759 3017 $this->assertEquals($convid, $message1['conversationid']);
6aa01968
MN
3018
3019 $this->assertEquals($user2->id, $message2['userid']);
3020 $this->assertEquals(fullname($user2), $message2['fullname']);
3021 $this->assertTrue($message2['ismessaging']);
3022 $this->assertTrue($message2['sentfromcurrentuser']);
3023 $this->assertEquals('Yo!', $message2['lastmessage']);
3024 $this->assertNotEmpty($message2['messageid']);
cb805753 3025 $this->assertNull($message2['isonline']);
6aa01968
MN
3026 $this->assertTrue($message2['isread']);
3027 $this->assertFalse($message2['isblocked']);
3028 $this->assertNull($message2['unreadcount']);
d2708759 3029 $this->assertEquals($convid, $message2['conversationid']);
6aa01968
MN
3030 }
3031
3032 /**
3033 * Tests searching messages as another user.
3034 */
3035 public function test_messagearea_search_messages_as_other_user() {
3036 $this->resetAfterTest(true);
3037
3038 // The person doing the search.
3039 $this->setAdminUser();
3040
3041 // Create some users.
3042 $user1 = self::getDataGenerator()->create_user();
3043 $user2 = self::getDataGenerator()->create_user();
3044
3045 // Send some messages back and forth.
3046 $time = time();
3047 $this->send_message($user1, $user2, 'Yo!', 0, $time);
3048 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3049 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
3050 $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
3051
3052 // Perform a search.
3053 $result = core_message_external::data_for_messagearea_search_messages($user1->id, 'o');
3054
3055 // We need to execute the return values cleaning process to simulate the web service server.
3056 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_search_messages_returns(),
3057 $result);
3058
3059 // Confirm the data is correct.
3060 $messages = $result['contacts'];
3061 $this->assertCount(2, $messages);
3062
3063 $message1 = $messages[0];
3064 $message2 = $messages[1];
3065
3066 $this->assertEquals($user2->id, $message1['userid']);
3067 $this->assertEquals(fullname($user2), $message1['fullname']);
3068 $this->assertTrue($message1['ismessaging']);
3069 $this->assertFalse($message1['sentfromcurrentuser']);
3070 $this->assertEquals('Word.', $message1['lastmessage']);
3071 $this->assertNotEmpty($message1['messageid']);
3072 $this->assertFalse($message1['isonline']);
3073 $this->assertFalse($message1['isread']);
3074 $this->assertFalse($message1['isblocked']);
3075 $this->assertNull($message1['unreadcount']);
3076
3077 $this->assertEquals($user2->id, $message2['userid']);
3078 $this->assertEquals(fullname($user2), $message2['fullname']);
3079 $this->assertTrue($message2['ismessaging']);
3080 $this->assertTrue($message2['sentfromcurrentuser']);
3081 $this->assertEquals('Yo!', $message2['lastmessage']);
3082 $this->assertNotEmpty($message2['messageid']);
3083 $this->assertFalse($message2['isonline']);
3084 $this->assertTrue($message2['isread']);
3085 $this->assertFalse($message2['isblocked']);
3086 $this->assertNull($message2['unreadcount']);
3087 }
3088
3089 /**
3090 * Tests searching messages as another user without the proper capabilities.
3091 */
3092 public function test_messagearea_search_messages_as_other_user_without_cap() {
3093 $this->resetAfterTest(true);
3094
3095 // Create some users.
3096 $user1 = self::getDataGenerator()->create_user();
3097 $user2 = self::getDataGenerator()->create_user();
3098
3099 // The person doing the search for another user.
3100 $this->setUser($user1);
3101
3102 // Ensure an exception is thrown.
3103 $this->expectException('moodle_exception');
3104 core_message_external::data_for_messagearea_search_messages($user2->id, 'Search');
3105 }
3106
3107 /**
3108 * Tests searching messages with messaging disabled
3109 */
3110 public function test_messagearea_search_messages_messaging_disabled() {
3111 global $CFG;
3112
3113 $this->resetAfterTest(true);
3114
3115 // Create some skeleton data just so we can call the WS.
3116 $user = self::getDataGenerator()->create_user();
3117
3118 // The person doing the search .
3119 $this->setUser($user);
3120
3121 // Disable messaging.
3122 $CFG->messaging = 0;
3123
3124 // Ensure an exception is thrown.
3125 $this->expectException('moodle_exception');
3126 core_message_external::data_for_messagearea_search_messages($user->id, 'Search');
3127 }
3128
3129 /**
3130 * Tests retrieving conversations.
3131 */
3132 public function test_messagearea_conversations() {
3133 $this->resetAfterTest(true);
3134
3135 // Create some users.
3136 $user1 = self::getDataGenerator()->create_user();
3137 $user2 = self::getDataGenerator()->create_user();
3138 $user3 = self::getDataGenerator()->create_user();
3139 $user4 = self::getDataGenerator()->create_user();
3140
3141 // The person retrieving the conversations.
3142 $this->setUser($user1);
3143
3144 // Send some messages back and forth, have some different conversations with different users.
3145 $time = time();
3146 $this->send_message($user1, $user2, 'Yo!', 0, $time);
3147 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3148 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
4d146f1a 3149 $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
6aa01968
MN
3150
3151 $this->send_message($user1, $user3, 'Booyah', 0, $time + 4);
3152 $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5);
3153 $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6);
4d146f1a 3154 $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7);
6aa01968
MN
3155
3156 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8);
3157 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9);
4d146f1a 3158 $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10);
6aa01968
MN
3159
3160 // Retrieve the conversations.
3161 $result = core_message_external::data_for_messagearea_conversations($user1->id);
3162
3163 // We need to execute the return values cleaning process to simulate the web service server.
3164 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(),
3165 $result);
3166
3167 // Confirm the data is correct.
3168 $messages = $result['contacts'];
3169 $this->assertCount(3, $messages);
3170
3171 $message1 = $messages[0];
3172 $message2 = $messages[1];
3173 $message3 = $messages[2];
3174
3175 $this->assertEquals($user4->id, $message1['userid']);
3176 $this->assertTrue($message1['ismessaging']);
3177 $this->assertTrue($message1['sentfromcurrentuser']);
3178 $this->assertEquals('Dope.', $message1['lastmessage']);
4d146f1a 3179 $this->assertEquals($messageid3, $message1['messageid']);
cb805753 3180 $this->assertNull($message1['isonline']);
4d146f1a 3181 $this->assertFalse($message1['isread']);
6aa01968 3182 $this->assertFalse($message1['isblocked']);
4d146f1a 3183 $this->assertEquals(1, $message1['unreadcount']);
6aa01968
MN
3184
3185 $this->assertEquals($user3->id, $message2['userid']);
3186 $this->assertTrue($message2['ismessaging']);
3187 $this->assertFalse($message2['sentfromcurrentuser']);
3188 $this->assertEquals('Cool.', $message2['lastmessage']);
4d146f1a 3189 $this->assertEquals($messageid2, $message2['messageid']);
cb805753 3190 $this->assertNull($message2['isonline']);
6aa01968
MN
3191 $this->assertFalse($message2['isread']);
3192 $this->assertFalse($message2['isblocked']);
3193 $this->assertEquals(2, $message2['unreadcount']);
3194
3195 $this->assertEquals($user2->id, $message3['userid']);
3196 $this->assertTrue($message3['ismessaging']);
3197 $this->assertFalse($message3['sentfromcurrentuser']);
3198 $this->assertEquals('Word.', $message3['lastmessage']);
4d146f1a 3199 $this->assertEquals($messageid1, $message3['messageid']);
cb805753 3200 $this->assertNull($message3['isonline']);
6aa01968
MN
3201 $this->assertFalse($message3['isread']);
3202 $this->assertFalse($message3['isblocked']);
3203 $this->assertEquals(2, $message3['unreadcount']);
3204 }
3205
3206 /**
3207 * Tests retrieving conversations as another user.
3208 */
3209 public function test_messagearea_conversations_as_other_user() {
3210 $this->resetAfterTest(true);
3211
3212 // Set as admin.
3213 $this->setAdminUser();
3214
3215 // Create some users.
3216 $user1 = self::getDataGenerator()->create_user();
3217 $user2 = self::getDataGenerator()->create_user();
3218 $user3 = self::getDataGenerator()->create_user();
3219 $user4 = self::getDataGenerator()->create_user();
3220
3221 // Send some messages back and forth, have some different conversations with different users.
3222 $time = time();
3223 $this->send_message($user1, $user2, 'Yo!', 0, $time);
3224 $this->send_message($user2, $user1, 'Sup mang?', 0, $time + 1);
3225 $this->send_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 2);
4d146f1a 3226 $messageid1 = $this->send_message($user2, $user1, 'Word.', 0, $time + 3);
6aa01968
MN
3227
3228 $this->send_message($user1, $user3, 'Booyah', 0, $time + 4);
3229 $this->send_message($user3, $user1, 'Whaaat?', 0, $time + 5);
3230 $this->send_message($user1, $user3, 'Nothing.', 0, $time + 6);
4d146f1a 3231 $messageid2 = $this->send_message($user3, $user1, 'Cool.', 0, $time + 7);
6aa01968
MN
3232
3233 $this->send_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 8);
3234 $this->send_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 9);
4d146f1a 3235 $messageid3 = $this->send_message($user1, $user4, 'Dope.', 0, $time + 10);
6aa01968
MN
3236
3237 // Retrieve the conversations.
3238 $result = core_message_external::data_for_messagearea_conversations($user1->id);
3239
3240 // We need to execute the return values cleaning process to simulate the web service server.
3241 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_conversations_returns(),
3242 $result);
3243
3244 // Confirm the data is correct.
3245 $messages = $result['contacts'];
3246 $this->assertCount(3, $messages);
3247
3248 $message1 = $messages[0];
3249 $message2 = $messages[1];
3250 $message3 = $messages[2];
3251
3252 $this->assertEquals($user4->id, $message1['userid']);
3253 $this->assertTrue($message1['ismessaging']);
3254 $this->assertTrue($message1['sentfromcurrentuser']);
3255 $this->assertEquals('Dope.', $message1['lastmessage']);
4d146f1a 3256 $this->assertEquals($messageid3, $message1['messageid']);
6aa01968 3257 $this->assertFalse($message1['isonline']);
4d146f1a 3258 $this->assertFalse($message1['isread']);
6aa01968 3259 $this->assertFalse($message1['isblocked']);
4d146f1a 3260 $this->assertEquals(1, $message1['unreadcount']);
6aa01968
MN
3261
3262 $this->assertEquals($user3->id, $message2['userid']);
3263 $this->assertTrue($message2['ismessaging']);
3264 $this->assertFalse($message2['sentfromcurrentuser']);
3265 $this->assertEquals('Cool.', $message2['lastmessage']);
4d146f1a 3266 $this->assertEquals($messageid2, $message2['messageid']);
6aa01968
MN
3267 $this->assertFalse($message2['isonline']);
3268 $this->assertFalse($message2['isread']);
3269 $this->assertFalse($message2['isblocked']);
3270 $this->assertEquals(2, $message2['unreadcount']);
3271
3272 $this->assertEquals($user2->id, $message3['userid']);
3273 $this->assertTrue($message3['ismessaging']);
3274 $this->assertFalse($message3['sentfromcurrentuser']);
3275 $this->assertEquals('Word.', $message3['lastmessage']);
4d146f1a 3276 $this->assertEquals($messageid1, $message3['messageid']);
6aa01968
MN
3277 $this->assertFalse($message3['isonline']);
3278 $this->assertFalse($message3['isread']);
3279 $this->assertFalse($message3['isblocked']);
3280 $this->assertEquals(2, $message3['unreadcount']);
3281 }
3282
3283 /**
3284 * Tests retrieving conversations as another user without the proper capabilities.
3285 */
3286 public function test_messagearea_conversations_as_other_user_without_cap() {
3287 $this->resetAfterTest(true);
3288
3289 // Create some users.
3290 $user1 = self::getDataGenerator()->create_user();
3291 $user2 = self::getDataGenerator()->create_user();
3292
3293 // The person retrieving the conversations for another user.
3294 $this->setUser($user1);
3295
3296 // Ensure an exception is thrown.
3297 $this->expectException('moodle_exception');
3298 core_message_external::data_for_messagearea_conversations($user2->id);
3299 }
3300
3301 /**
3302 * Tests retrieving conversations with messaging disabled.
3303 */
3304 public function test_messagearea_conversations_messaging_disabled() {
3305 global $CFG;
3306
3307 $this->resetAfterTest(true);
3308
3309 // Create some skeleton data just so we can call the WS.
3310 $user = self::getDataGenerator()->create_user();
3311
3312 // The person retrieving the conversations.
3313 $this->setUser($user);
3314
3315 // Disable messaging.
3316 $CFG->messaging = 0;
3317
3318 // Ensure an exception is thrown.
3319 $this->expectException('moodle_exception');
3320 core_message_external::data_for_messagearea_conversations($user->id);
3321 }
3322
3323 /**
3324 * Tests retrieving contacts.
3325 */
3326 public function test_messagearea_contacts() {
3327 $this->resetAfterTest(true);
3328
3329 // Create some users.
3330 $user1 = self::getDataGenerator()->create_user();
3331
3332 // Set as the user.
3333 $this->setUser($user1);
3334
3335 $user2 = new stdClass();
3336 $user2->firstname = 'User';
3337 $user2->lastname = 'A';
3338 $user2 = self::getDataGenerator()->create_user($user2);
3339
3340 $user3 = new stdClass();
3341 $user3->firstname = 'User';
3342 $user3->lastname = 'B';
3343 $user3 = self::getDataGenerator()->create_user($user3);
3344
3345 $user4 = new stdClass();
3346 $user4->firstname = 'User';
3347 $user4->lastname = 'C';
3348 $user4 = self::getDataGenerator()->create_user($user4);
3349
3350 $user5 = new stdClass();
3351 $user5->firstname = 'User';
3352 $user5->lastname = 'D';
3353 $user5 = self::getDataGenerator()->create_user($user5);
3354
3355 // Add some users as contacts.
f219eac7
MN
3356 \core_message\api::add_contact($user1->id, $user2->id);
3357 \core_message\api::add_contact($user1->id, $user3->id);
3358 \core_message\api::add_contact($user1->id, $user4->id);
6aa01968
MN
3359
3360 // Retrieve the contacts.
3361 $result = core_message_external::data_for_messagearea_contacts($user1->id);
3362
3363 // We need to execute the return values cleaning process to simulate the web service server.
3364 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(),
3365 $result);
3366
3367 // Confirm the data is correct.
3368 $contacts = $result['contacts'];
f219eac7 3369 usort($contacts, ['static', 'sort_contacts']);
6aa01968
MN
3370 $this->assertCount(3, $contacts);
3371
3372 $contact1 = $contacts[0];
3373 $contact2 = $contacts[1];
3374 $contact3 = $contacts[2];
3375
3376 $this->assertEquals($user2->id, $contact1['userid']);
3377 $this->assertFalse($contact1['ismessaging']);
3378 $this->assertFalse($contact1['sentfromcurrentuser']);
3379 $this->assertNull($contact1['lastmessage']);
3380 $this->assertNull($contact1['messageid']);
cb805753 3381 $this->assertNull($contact1['isonline']);
6aa01968
MN
3382 $this->assertFalse($contact1['isread']);
3383 $this->assertFalse($contact1['isblocked']);
3384 $this->assertNull($contact1['unreadcount']);
3385
3386 $this->assertEquals($user3->id, $contact2['userid']);
3387 $this->assertFalse($contact2['ismessaging']);
3388 $this->assertFalse($contact2['sentfromcurrentuser']);
3389 $this->assertNull($contact2['lastmessage']);
3390 $this->assertNull($contact2['messageid']);
cb805753 3391 $this->assertNull($contact2['isonline']);
6aa01968
MN
3392 $this->assertFalse($contact2['isread']);
3393 $this->assertFalse($contact2['isblocked']);
3394 $this->assertNull($contact2['unreadcount']);
3395
3396 $this->assertEquals($user4->id, $contact3['userid']);
3397 $this->assertFalse($contact3['ismessaging']);
3398 $this->assertFalse($contact3['sentfromcurrentuser']);
3399 $this->assertNull($contact3['lastmessage']);
3400 $this->assertNull($contact3['messageid']);
cb805753 3401 $this->assertNull($contact3['isonline']);
6aa01968
MN
3402 $this->assertFalse($contact3['isread']);
3403 $this->assertFalse($contact3['isblocked']);
3404 $this->assertNull($contact3['unreadcount']);
3405 }
3406
3407 /**
3408 * Tests retrieving contacts as another user.
3409 */
3410 public function test_messagearea_contacts_as_other_user() {
3411 $this->resetAfterTest(true);
3412
3413 $this->setAdminUser();
3414
3415 // Create some users.
3416 $user1 = self::getDataGenerator()->create_user();
3417
3418 $user2 = new stdClass();
3419 $user2->firstname = 'User';
3420 $user2->lastname = 'A';
3421 $user2 = self::getDataGenerator()->create_user($user2);
3422
3423 $user3 = new stdClass();
3424 $user3->firstname = 'User';
3425 $user3->lastname = 'B';
3426 $user3 = self::getDataGenerator()->create_user($user3);
3427
3428 $user4 = new stdClass();
3429 $user4->firstname = 'User';
3430 $user4->lastname = 'C';
3431 $user4 = self::getDataGenerator()->create_user($user4);
3432
3433 $user5 = new stdClass();
3434 $user5->firstname = 'User';
3435 $user5->lastname = 'D';
3436 $user5 = self::getDataGenerator()->create_user($user5);
3437
3438 // Add some users as contacts.
f219eac7
MN
3439 \core_message\api::add_contact($user1->id, $user2->id);
3440 \core_message\api::add_contact($user1->id, $user3->id);
3441 \core_message\api::add_contact($user1->id, $user4->id);
6aa01968
MN
3442
3443 // Retrieve the contacts.
3444 $result = core_message_external::data_for_messagearea_contacts($user1->id);
3445
3446 // We need to execute the return values cleaning process to simulate the web service server.
3447 $result = external_api::clean_returnvalue(core_message_external::data_for_messagearea_contacts_returns(),
3448 $result);
3449
3450 // Confirm the data is correct.
3451 $contacts = $result['contacts'];
f219eac7 3452 usort($contacts, ['static', 'sort_contacts']);
6aa01968
MN
3453 $this->assertCount(3, $contacts);
3454
3455 $contact1 = $contacts[0];
3456 $contact2 = $contacts[1];
3457 $contact3 = $contacts[2];
3458
3459