MDL-63913 core_message: add method to get unread conversation counts
[moodle.git] / message / tests / api_test.php
CommitLineData
79f6c36c
MN
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 * Test message API.
19 *
20 * @package core_message
21 * @category test
22 * @copyright 2016 Mark Nelson <markn@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24 */
25
26defined('MOODLE_INTERNAL') || die();
27
28global $CFG;
29
30require_once($CFG->dirroot . '/message/tests/messagelib_test.php');
31
fb04293b
SA
32use \core_message\tests\helper as testhelper;
33
79f6c36c
MN
34/**
35 * Test message API.
36 *
37 * @package core_message
38 * @category test
39 * @copyright 2016 Mark Nelson <markn@moodle.com>
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 */
42class core_message_api_testcase extends core_message_messagelib_testcase {
43
1f64514d 44 public function test_mark_all_read_for_user_touser() {
79f6c36c
MN
45 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
46 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
47
7d69958e
RW
48 $this->send_fake_message($sender, $recipient, 'Notification', 1);
49 $this->send_fake_message($sender, $recipient, 'Notification', 1);
50 $this->send_fake_message($sender, $recipient, 'Notification', 1);
79f6c36c
MN
51 $this->send_fake_message($sender, $recipient);
52 $this->send_fake_message($sender, $recipient);
53 $this->send_fake_message($sender, $recipient);
54
55 \core_message\api::mark_all_read_for_user($recipient->id);
74ad60bf 56 $this->assertDebuggingCalled();
79f6c36c
MN
57 $this->assertEquals(message_count_unread_messages($recipient), 0);
58 }
59
1f64514d 60 public function test_mark_all_read_for_user_touser_with_fromuser() {
79f6c36c
MN
61 $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
62 $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
63 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
64
7d69958e
RW
65 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
66 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
67 $this->send_fake_message($sender1, $recipient, 'Notification', 1);
79f6c36c
MN
68 $this->send_fake_message($sender1, $recipient);
69 $this->send_fake_message($sender1, $recipient);
70 $this->send_fake_message($sender1, $recipient);
7d69958e
RW
71 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
72 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
73 $this->send_fake_message($sender2, $recipient, 'Notification', 1);
79f6c36c
MN
74 $this->send_fake_message($sender2, $recipient);
75 $this->send_fake_message($sender2, $recipient);
76 $this->send_fake_message($sender2, $recipient);
77
78 \core_message\api::mark_all_read_for_user($recipient->id, $sender1->id);
74ad60bf 79 $this->assertDebuggingCalled();
29c3b0b4 80 $this->assertEquals(message_count_unread_messages($recipient), 3);
79f6c36c
MN
81 }
82
1f64514d 83 public function test_mark_all_read_for_user_touser_with_type() {
79f6c36c
MN
84 $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
85 $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
86
7d69958e
RW
87 $this->send_fake_message($sender, $recipient, 'Notification', 1);
88 $this->send_fake_message($sender, $recipient, 'Notification', 1);
89 $this->send_fake_message($sender, $recipient, 'Notification', 1);
79f6c36c
MN
90 $this->send_fake_message($sender, $recipient);
91 $this->send_fake_message($sender, $recipient);
92 $this->send_fake_message($sender, $recipient);
93
94 \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_NOTIFICATION);
74ad60bf 95 $this->assertDebuggingCalled();
79f6c36c
MN
96 $this->assertEquals(message_count_unread_messages($recipient), 3);
97
98 \core_message\api::mark_all_read_for_user($recipient->id, 0, MESSAGE_TYPE_MESSAGE);
74ad60bf 99 $this->assertDebuggingCalled();
79f6c36c
MN
100 $this->assertEquals(message_count_unread_messages($recipient), 0);
101 }
102
5b0769db
MN
103 /**
104 * Test count_blocked_users.
5b0769db 105 */
1f64514d 106 public function test_count_blocked_users() {
f219eac7
MN
107 global $USER;
108
5b0769db
MN
109 // Set this user as the admin.
110 $this->setAdminUser();
111
f219eac7 112 // Create user to add to the admin's block list.
5b0769db 113 $user1 = $this->getDataGenerator()->create_user();
f7dfa9ba 114 $user2 = $this->getDataGenerator()->create_user();
5b0769db
MN
115
116 $this->assertEquals(0, \core_message\api::count_blocked_users());
117
f219eac7
MN
118 // Add 1 blocked user to admin's blocked user list.
119 \core_message\api::block_user($USER->id, $user1->id);
5b0769db 120
f219eac7 121 $this->assertEquals(0, \core_message\api::count_blocked_users($user1));
5b0769db
MN
122 $this->assertEquals(1, \core_message\api::count_blocked_users());
123 }
1f64514d
MN
124
125 /**
126 * Tests searching users in a course.
127 */
128 public function test_search_users_in_course() {
129 // Create some users.
130 $user1 = new stdClass();
131 $user1->firstname = 'User';
132 $user1->lastname = 'One';
133 $user1 = self::getDataGenerator()->create_user($user1);
134
135 // The person doing the search.
136 $this->setUser($user1);
137
138 // Second user is going to have their last access set to now, so they are online.
139 $user2 = new stdClass();
140 $user2->firstname = 'User';
141 $user2->lastname = 'Two';
142 $user2->lastaccess = time();
143 $user2 = self::getDataGenerator()->create_user($user2);
144
145 // Block the second user.
f219eac7 146 \core_message\api::block_user($user1->id, $user2->id);
1f64514d
MN
147
148 $user3 = new stdClass();
149 $user3->firstname = 'User';
150 $user3->lastname = 'Three';
151 $user3 = self::getDataGenerator()->create_user($user3);
152
153 // Create a course.
154 $course1 = new stdClass();
155 $course1->fullname = 'Course';
156 $course1->shortname = 'One';
157 $course1 = $this->getDataGenerator()->create_course($course1);
158
159 // Enrol the searcher and one user in the course.
160 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
161 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
162
163 // Perform a search.
164 $results = \core_message\api::search_users_in_course($user1->id, $course1->id, 'User');
165
166 $this->assertEquals(1, count($results));
167
168 $user = $results[0];
169 $this->assertEquals($user2->id, $user->userid);
170 $this->assertEquals(fullname($user2), $user->fullname);
171 $this->assertFalse($user->ismessaging);
172 $this->assertNull($user->lastmessage);
173 $this->assertNull($user->messageid);
cb805753 174 $this->assertNull($user->isonline);
1f64514d
MN
175 $this->assertFalse($user->isread);
176 $this->assertTrue($user->isblocked);
177 $this->assertNull($user->unreadcount);
178 }
179
180 /**
181 * Tests searching users.
182 */
183 public function test_search_users() {
09a05b79
AN
184 global $DB;
185
1f64514d
MN
186 // Create some users.
187 $user1 = new stdClass();
188 $user1->firstname = 'User';
189 $user1->lastname = 'One';
190 $user1 = self::getDataGenerator()->create_user($user1);
191
192 // Set as the user performing the search.
193 $this->setUser($user1);
194
195 $user2 = new stdClass();
196 $user2->firstname = 'User search';
197 $user2->lastname = 'Two';
198 $user2 = self::getDataGenerator()->create_user($user2);
199
200 $user3 = new stdClass();
201 $user3->firstname = 'User search';
202 $user3->lastname = 'Three';
203 $user3 = self::getDataGenerator()->create_user($user3);
204
205 $user4 = new stdClass();
206 $user4->firstname = 'User';
207 $user4->lastname = 'Four';
208 $user4 = self::getDataGenerator()->create_user($user4);
209
210 $user5 = new stdClass();
211 $user5->firstname = 'User search';
212 $user5->lastname = 'Five';
213 $user5 = self::getDataGenerator()->create_user($user5);
214
215 $user6 = new stdClass();
216 $user6->firstname = 'User';
217 $user6->lastname = 'Six';
218 $user6 = self::getDataGenerator()->create_user($user6);
219
220 // Create some courses.
221 $course1 = new stdClass();
222 $course1->fullname = 'Course search';
223 $course1->shortname = 'One';
224 $course1 = $this->getDataGenerator()->create_course($course1);
225
226 $course2 = new stdClass();
227 $course2->fullname = 'Course';
228 $course2->shortname = 'Two';
229 $course2 = $this->getDataGenerator()->create_course($course2);
230
231 $course3 = new stdClass();
232 $course3->fullname = 'Course';
233 $course3->shortname = 'Three search';
234 $course3 = $this->getDataGenerator()->create_course($course3);
235
87d4ab65
AG
236 $course4 = new stdClass();
237 $course4->fullname = 'Course Four';
238 $course4->shortname = 'CF100';
239 $course4 = $this->getDataGenerator()->create_course($course4);
240
09a05b79
AN
241 $course5 = new stdClass();
242 $course5->fullname = 'Course';
243 $course5->shortname = 'Five search';
244 $course5 = $this->getDataGenerator()->create_course($course5);
245
246 $role = $DB->get_record('role', ['shortname' => 'student']);
247 $this->getDataGenerator()->enrol_user($user1->id, $course1->id, $role->id);
248 $this->getDataGenerator()->enrol_user($user1->id, $course2->id, $role->id);
249 $this->getDataGenerator()->enrol_user($user1->id, $course3->id, $role->id);
250 $this->getDataGenerator()->enrol_user($user1->id, $course5->id, $role->id);
87d4ab65 251
1f64514d 252 // Add some users as contacts.
f219eac7
MN
253 \core_message\api::add_contact($user1->id, $user2->id);
254 \core_message\api::add_contact($user1->id, $user3->id);
255 \core_message\api::add_contact($user1->id, $user4->id);
1f64514d 256
09a05b79
AN
257 // Remove the viewparticipants capability from one of the courses.
258 $course5context = context_course::instance($course5->id);
259 assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $role->id, $course5context->id);
09a05b79 260
548cac7d
AA
261 // Perform a search $CFG->messagingallusers setting enabled.
262 set_config('messagingallusers', 1);
1f64514d
MN
263 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
264
265 // Check that we retrieved the correct contacts.
266 $this->assertEquals(2, count($contacts));
267 $this->assertEquals($user3->id, $contacts[0]->userid);
268 $this->assertEquals($user2->id, $contacts[1]->userid);
269
270 // Check that we retrieved the correct courses.
271 $this->assertEquals(2, count($courses));
272 $this->assertEquals($course3->id, $courses[0]->id);
273 $this->assertEquals($course1->id, $courses[1]->id);
274
275 // Check that we retrieved the correct non-contacts.
276 $this->assertEquals(1, count($noncontacts));
277 $this->assertEquals($user5->id, $noncontacts[0]->userid);
278 }
279
548cac7d
AA
280 /**
281 * Tests searching users with empty result.
282 */
283 public function test_search_users_with_empty_result() {
284
285 // Create some users.
286 $user1 = new stdClass();
287 $user1->firstname = 'User';
288 $user1->lastname = 'One';
289 $user1 = self::getDataGenerator()->create_user($user1);
290
291 // Set as the user performing the search.
292 $this->setUser($user1);
293
294 $user2 = new stdClass();
295 $user2->firstname = 'User';
296 $user2->lastname = 'Two';
297 $user2 = self::getDataGenerator()->create_user($user2);
298
299 // Perform a search $CFG->messagingallusers setting enabled.
300 set_config('messagingallusers', 1);
301 list($contacts, $courses, $noncontacts) = \core_message\api::search_users($user1->id, 'search');
302
303 // Check results are empty.
304 $this->assertEquals(0, count($contacts));
305 $this->assertEquals(0, count($courses));
306 $this->assertEquals(0, count($noncontacts));
307 }
308
309 /**
41485be2
JD
310 * Tests searching for users when site-wide messaging is disabled.
311 *
312 * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
313 * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
314 * profile.
548cac7d 315 */
41485be2
JD
316 public function test_message_search_users_messagingallusers_disabled() {
317 $this->resetAfterTest();
318
548cac7d 319 // Create some users.
41485be2
JD
320 $users = [];
321 foreach (range(1, 7) as $i) {
322 $user = new stdClass();
323 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
324 $user->lastname = $i;
325 $user = $this->getDataGenerator()->create_user($user);
326 $users[$i] = $user;
327 }
328
329 // Enrol a few users in the same course, but leave them as non-contacts.
330 $course1 = $this->getDataGenerator()->create_course();
331 $this->setAdminUser();
332 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
333 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
334 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
335
336 // Add some other users as contacts.
337 \core_message\api::add_contact($users[1]->id, $users[2]->id);
338 \core_message\api::add_contact($users[3]->id, $users[1]->id);
339 \core_message\api::add_contact($users[1]->id, $users[4]->id);
340
341 // Create individual conversations between some users, one contact and one non-contact.
342 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
343 [$users[1]->id, $users[2]->id]);
344 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
345 [$users[6]->id, $users[1]->id]);
346
347 // Create a group conversation between 4 users, including a contact and a non-contact.
348 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
349 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
548cac7d
AA
350
351 // Set as the user performing the search.
41485be2 352 $this->setUser($users[1]);
548cac7d 353
41485be2
JD
354 // Perform a search with $CFG->messagingallusers disabled.
355 set_config('messagingallusers', 0);
356 $result = \core_message\api::message_search_users($users[1]->id, 'search');
548cac7d 357
41485be2
JD
358 // Confirm that we returns contacts and non-contacts.
359 $this->assertArrayHasKey(0, $result);
360 $this->assertArrayHasKey(1, $result);
361 $contacts = $result[0];
362 $noncontacts = $result[1];
548cac7d 363
41485be2
JD
364 // Check that we retrieved the correct contacts.
365 $this->assertCount(2, $contacts);
366 $this->assertEquals($users[2]->id, $contacts[0]->id);
367 $this->assertEquals($users[3]->id, $contacts[1]->id);
548cac7d 368
41485be2
JD
369 // Verify the correct conversations were returned for the contacts.
370 $this->assertCount(2, $contacts[0]->conversations);
371 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
372 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
548cac7d 373
41485be2 374 $this->assertCount(0, $contacts[1]->conversations);
548cac7d 375
41485be2
JD
376 // Check that we retrieved the correct non-contacts.
377 // When site wide messaging is disabled, we expect to see only those users whose profiles we can view.
378 $this->assertCount(2, $noncontacts);
379 $this->assertEquals($users[6]->id, $noncontacts[0]->id);
380 $this->assertEquals($users[7]->id, $noncontacts[1]->id);
548cac7d 381
41485be2
JD
382 // Verify the correct conversations were returned for the non-contacts.
383 $this->assertCount(1, $noncontacts[0]->conversations);
384 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
385 $noncontacts[0]->conversations[$ic2->id]->type);
548cac7d 386
41485be2
JD
387 $this->assertCount(1, $noncontacts[1]->conversations);
388 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[1]->conversations[$gc1->id]->type);
389 }
548cac7d 390
41485be2
JD
391 /**
392 * Tests searching for users when site-wide messaging is enabled.
393 *
394 * This test verifies that any contacts are returned, as well as any non-contacts, regardless of whether the searching user
395 * can view their respective profile.
396 */
397 public function test_message_search_users_messagingallusers_enabled() {
398 $this->resetAfterTest();
399
400 // Create some users.
401 $users = [];
402 foreach (range(1, 8) as $i) {
403 $user = new stdClass();
404 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
405 $user->lastname = $i;
406 $user = $this->getDataGenerator()->create_user($user);
407 $users[$i] = $user;
408 }
409
410 // Enrol a few users in the same course, but leave them as non-contacts.
411 $course1 = $this->getDataGenerator()->create_course();
412 $this->setAdminUser();
413 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
414 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
415 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
416
417 // Add some other users as contacts.
418 \core_message\api::add_contact($users[1]->id, $users[2]->id);
419 \core_message\api::add_contact($users[3]->id, $users[1]->id);
420 \core_message\api::add_contact($users[1]->id, $users[4]->id);
421
422 // Create individual conversations between some users, one contact and one non-contact.
423 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
424 [$users[1]->id, $users[2]->id]);
425 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
426 [$users[6]->id, $users[1]->id]);
427
428 // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
429 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
430 [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
431
432 // Set as the user performing the search.
433 $this->setUser($users[1]);
434
435 // Perform a search with $CFG->messagingallusers enabled.
548cac7d 436 set_config('messagingallusers', 1);
41485be2
JD
437 $result = \core_message\api::message_search_users($users[1]->id, 'search');
438
439 // Confirm that we returns contacts and non-contacts.
440 $this->assertArrayHasKey(0, $result);
441 $this->assertArrayHasKey(1, $result);
442 $contacts = $result[0];
443 $noncontacts = $result[1];
548cac7d
AA
444
445 // Check that we retrieved the correct contacts.
446 $this->assertCount(2, $contacts);
41485be2
JD
447 $this->assertEquals($users[2]->id, $contacts[0]->id);
448 $this->assertEquals($users[3]->id, $contacts[1]->id);
449
450 // Verify the correct conversations were returned for the contacts.
451 $this->assertCount(2, $contacts[0]->conversations);
452 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
453 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
454
455 $this->assertCount(0, $contacts[1]->conversations);
548cac7d
AA
456
457 // Check that we retrieved the correct non-contacts.
41485be2
JD
458 // If site wide messaging is enabled, we expect to be able to search for any users.
459 $this->assertCount(4, $noncontacts);
460 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
461 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
462 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
463 $this->assertEquals($users[8]->id, $noncontacts[3]->id);
464
465 // Verify the correct conversations were returned for the non-contacts.
466 $this->assertCount(0, $noncontacts[0]->conversations);
467
468 $this->assertCount(1, $noncontacts[1]->conversations);
469 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
470 $noncontacts[1]->conversations[$ic2->id]->type);
471
472 $this->assertCount(1, $noncontacts[2]->conversations);
473 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
474
475 $this->assertCount(1, $noncontacts[3]->conversations);
476 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[3]->conversations[$gc1->id]->type);
477 }
478
479 /**
480 * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
481 */
482 public function test_message_search_users_with_empty_result() {
483 $this->resetAfterTest();
484
485 // Create some users, but make sure neither will match the search term.
486 $user1 = new stdClass();
487 $user1->firstname = 'User';
488 $user1->lastname = 'One';
489 $user1 = $this->getDataGenerator()->create_user($user1);
490 $user2 = new stdClass();
491 $user2->firstname = 'User';
492 $user2->lastname = 'Two';
493 $user2 = $this->getDataGenerator()->create_user($user2);
494
495 // Perform a search as user1.
496 $this->setUser($user1);
497 $result = \core_message\api::message_search_users($user1->id, 'search');
498
499 // Check results are empty.
500 $this->assertCount(0, $result[0]);
501 $this->assertCount(0, $result[1]);
502 }
503
504 /**
505 * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
506 */
507 public function test_message_search_users_limit_offset() {
508 $this->resetAfterTest();
509
510 // Create 20 users.
511 $users = [];
512 foreach (range(1, 20) as $i) {
513 $user = new stdClass();
514 $user->firstname = "User search";
515 $user->lastname = $i;
516 $user = $this->getDataGenerator()->create_user($user);
517 $users[$i] = $user;
518 }
519
520 // Enrol the first 9 users in the same course, but leave them as non-contacts.
521 $this->setAdminUser();
522 $course1 = $this->getDataGenerator()->create_course();
523 foreach (range(1, 9) as $i) {
524 $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
525 }
526
527 // Add 5 users, starting at the 11th user, as contacts for user1.
528 foreach (range(11, 15) as $i) {
529 \core_message\api::add_contact($users[1]->id, $users[$i]->id);
530 }
531
532 // Set as the user performing the search.
533 $this->setUser($users[1]);
534
535 // Search using a limit of 3.
536 // This tests the case where we have more results than the limit for both contacts and non-contacts.
537 $result = \core_message\api::message_search_users($users[1]->id, 'search', 0, 3);
538 $contacts = $result[0];
539 $noncontacts = $result[1];
540
541 // Check that we retrieved the correct contacts.
542 $this->assertCount(3, $contacts);
543 $this->assertEquals($users[11]->id, $contacts[0]->id);
544 $this->assertEquals($users[12]->id, $contacts[1]->id);
545 $this->assertEquals($users[13]->id, $contacts[2]->id);
546
547 // Check that we retrieved the correct non-contacts.
548 $this->assertCount(3, $noncontacts);
549 $this->assertEquals($users[2]->id, $noncontacts[0]->id);
550 $this->assertEquals($users[3]->id, $noncontacts[1]->id);
551 $this->assertEquals($users[4]->id, $noncontacts[2]->id);
552
553 // Now, offset to get the next batch of results.
554 // We expect to see 2 contacts, and 3 non-contacts.
555 $result = \core_message\api::message_search_users($users[1]->id, 'search', 3, 3);
556 $contacts = $result[0];
557 $noncontacts = $result[1];
558 $this->assertCount(2, $contacts);
559 $this->assertEquals($users[14]->id, $contacts[0]->id);
560 $this->assertEquals($users[15]->id, $contacts[1]->id);
561
548cac7d 562 $this->assertCount(3, $noncontacts);
41485be2
JD
563 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
564 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
565 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
566
567 // Now, offset to get the next batch of results.
568 // We expect to see 0 contacts, and 2 non-contacts.
569 $result = \core_message\api::message_search_users($users[1]->id, 'search', 6, 3);
570 $contacts = $result[0];
571 $noncontacts = $result[1];
572 $this->assertCount(0, $contacts);
573
574 $this->assertCount(2, $noncontacts);
575 $this->assertEquals($users[8]->id, $noncontacts[0]->id);
576 $this->assertEquals($users[9]->id, $noncontacts[1]->id);
577 }
548cac7d 578
41485be2
JD
579 /**
580 * Tests searching users as a user having the 'moodle/user:viewdetails' capability.
581 */
582 public function test_message_search_users_with_cap() {
583 $this->resetAfterTest();
584 global $DB;
585
586 // Create some users.
587 $users = [];
588 foreach (range(1, 8) as $i) {
589 $user = new stdClass();
590 $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
591 $user->lastname = $i;
592 $user = $this->getDataGenerator()->create_user($user);
593 $users[$i] = $user;
594 }
595
596 // Enrol a few users in the same course, but leave them as non-contacts.
597 $course1 = $this->getDataGenerator()->create_course();
598 $this->setAdminUser();
599 $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
600 $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
601 $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
602
603 // Add some other users as contacts.
604 \core_message\api::add_contact($users[1]->id, $users[2]->id);
605 \core_message\api::add_contact($users[3]->id, $users[1]->id);
606 \core_message\api::add_contact($users[1]->id, $users[4]->id);
607
608 // Set as the user performing the search.
609 $this->setUser($users[1]);
610
611 // Grant the authenticated user role the capability 'user:viewdetails' at site context.
612 $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
613 assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, context_system::instance());
614
615 // Perform a search with $CFG->messagingallusers disabled.
548cac7d 616 set_config('messagingallusers', 0);
41485be2
JD
617 $result = \core_message\api::message_search_users($users[1]->id, 'search');
618 $contacts = $result[0];
619 $noncontacts = $result[1];
548cac7d
AA
620
621 // Check that we retrieved the correct contacts.
622 $this->assertCount(2, $contacts);
41485be2
JD
623 $this->assertEquals($users[2]->id, $contacts[0]->id);
624 $this->assertEquals($users[3]->id, $contacts[1]->id);
548cac7d
AA
625
626 // Check that we retrieved the correct non-contacts.
41485be2
JD
627 // Site-wide messaging is disabled, but since we can see all users, we expect to be able to search for any users.
628 $this->assertCount(4, $noncontacts);
629 $this->assertEquals($users[5]->id, $noncontacts[0]->id);
630 $this->assertEquals($users[6]->id, $noncontacts[1]->id);
631 $this->assertEquals($users[7]->id, $noncontacts[2]->id);
632 $this->assertEquals($users[8]->id, $noncontacts[3]->id);
633 }
634
635 /**
636 * Tests searching users with messaging disabled.
637 */
638 public function test_message_search_users_messaging_disabled() {
639 $this->resetAfterTest();
640
641 // Create a user.
642 $user = $this->getDataGenerator()->create_user();
643
644 // Disable messaging.
645 set_config('messaging', 0);
646
647 // Ensure an exception is thrown.
648 $this->expectException('moodle_exception');
649 \core_message\api::message_search_users($user->id, 'User');
548cac7d
AA
650 }
651
652 /**
653 * Tests getting conversations between 2 users.
654 */
655 public function test_get_conversations_between_users() {
656 // Create some users.
657 $user1 = new stdClass();
658 $user1->firstname = 'User';
659 $user1->lastname = 'One';
660 $user1 = self::getDataGenerator()->create_user($user1);
661
662 $user2 = new stdClass();
663 $user2->firstname = 'User';
664 $user2->lastname = 'Two';
665 $user2 = self::getDataGenerator()->create_user($user2);
666
667 $user3 = new stdClass();
668 $user3->firstname = 'User search';
669 $user3->lastname = 'Three';
670 $user3 = self::getDataGenerator()->create_user($user3);
671
672 $user4 = new stdClass();
673 $user4->firstname = 'User';
674 $user4->lastname = 'Four';
675 $user4 = self::getDataGenerator()->create_user($user4);
676
677 $user5 = new stdClass();
678 $user5->firstname = 'User';
679 $user5->lastname = 'Five';
680 $user5 = self::getDataGenerator()->create_user($user5);
681
682 $user6 = new stdClass();
683 $user6->firstname = 'User search';
684 $user6->lastname = 'Six';
685 $user6 = self::getDataGenerator()->create_user($user6);
686
687 // Add some users as contacts.
688 \core_message\api::add_contact($user1->id, $user2->id);
689 \core_message\api::add_contact($user6->id, $user1->id);
690
691 // Create private conversations with some users.
692 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
693 array($user1->id, $user2->id));
694 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
695 array($user3->id, $user1->id));
696
697 // Create a group conversation with users.
698 \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
699 array($user1->id, $user2->id, $user3->id, $user4->id),
700 'Project chat');
701
702 // Check that we retrieved the correct conversations.
703 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user2->id));
704 $this->assertCount(2, \core_message\api::get_conversations_between_users($user2->id, $user1->id));
705 $this->assertCount(2, \core_message\api::get_conversations_between_users($user1->id, $user3->id));
706 $this->assertCount(2, \core_message\api::get_conversations_between_users($user3->id, $user1->id));
707 $this->assertCount(1, \core_message\api::get_conversations_between_users($user1->id, $user4->id));
708 $this->assertCount(1, \core_message\api::get_conversations_between_users($user4->id, $user1->id));
709 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user5->id));
710 $this->assertCount(0, \core_message\api::get_conversations_between_users($user5->id, $user1->id));
711 $this->assertCount(0, \core_message\api::get_conversations_between_users($user1->id, $user6->id));
712 $this->assertCount(0, \core_message\api::get_conversations_between_users($user6->id, $user1->id));
713 }
714
1f64514d
MN
715 /**
716 * Tests searching messages.
717 */
718 public function test_search_messages() {
719 // Create some users.
720 $user1 = self::getDataGenerator()->create_user();
721 $user2 = self::getDataGenerator()->create_user();
f219eac7 722 $user3 = self::getDataGenerator()->create_user();
1f64514d
MN
723
724 // The person doing the search.
725 $this->setUser($user1);
726
727 // Send some messages back and forth.
728 $time = 1;
f219eac7
MN
729 $this->send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time);
730 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
731 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
732 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
733 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
734
735 // Block user 3.
736 \core_message\api::block_user($user1->id, $user3->id);
1f64514d
MN
737
738 // Perform a search.
739 $messages = \core_message\api::search_messages($user1->id, 'o');
740
741 // Confirm the data is correct.
f219eac7 742 $this->assertEquals(3, count($messages));
1f64514d
MN
743
744 $message1 = $messages[0];
745 $message2 = $messages[1];
f219eac7 746 $message3 = $messages[2];
1f64514d
MN
747
748 $this->assertEquals($user2->id, $message1->userid);
749 $this->assertEquals($user2->id, $message1->useridfrom);
750 $this->assertEquals(fullname($user2), $message1->fullname);
751 $this->assertTrue($message1->ismessaging);
752 $this->assertEquals('Word.', $message1->lastmessage);
753 $this->assertNotEmpty($message1->messageid);
cb805753 754 $this->assertNull($message1->isonline);
1f64514d
MN
755 $this->assertFalse($message1->isread);
756 $this->assertFalse($message1->isblocked);
757 $this->assertNull($message1->unreadcount);
758
759 $this->assertEquals($user2->id, $message2->userid);
760 $this->assertEquals($user1->id, $message2->useridfrom);
761 $this->assertEquals(fullname($user2), $message2->fullname);
762 $this->assertTrue($message2->ismessaging);
763 $this->assertEquals('Yo!', $message2->lastmessage);
764 $this->assertNotEmpty($message2->messageid);
cb805753 765 $this->assertNull($message2->isonline);
1f64514d
MN
766 $this->assertTrue($message2->isread);
767 $this->assertFalse($message2->isblocked);
768 $this->assertNull($message2->unreadcount);
f219eac7
MN
769
770 $this->assertEquals($user3->id, $message3->userid);
771 $this->assertEquals($user3->id, $message3->useridfrom);
772 $this->assertEquals(fullname($user3), $message3->fullname);
773 $this->assertTrue($message3->ismessaging);
774 $this->assertEquals('Don\'t block me.', $message3->lastmessage);
775 $this->assertNotEmpty($message3->messageid);
776 $this->assertNull($message3->isonline);
777 $this->assertFalse($message3->isread);
778 $this->assertTrue($message3->isblocked);
779 $this->assertNull($message3->unreadcount);
1f64514d
MN
780 }
781
782 /**
b8ff2c44
JD
783 * Test verifying that favourited conversations can be retrieved.
784 */
785 public function test_get_favourite_conversations() {
786 // Create some users.
787 $user1 = self::getDataGenerator()->create_user();
788 $user2 = self::getDataGenerator()->create_user();
789 $user3 = self::getDataGenerator()->create_user();
790 $user4 = self::getDataGenerator()->create_user();
791
792 // The person doing the search.
793 $this->setUser($user1);
794
795 // No conversations yet.
796 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
797
798 // Create some conversations for user1.
799 $time = 1;
800 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
801 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
802 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
803 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
804
805 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
806 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
807 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
808 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
809
810 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
811 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
812 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
813
814 // Favourite the first 2 conversations for user1.
815 $convoids = [];
816 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
817 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
818 $user1context = context_user::instance($user1->id);
819 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
820 foreach ($convoids as $convoid) {
821 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
822 }
823
824 // We should have 3 conversations.
825 $this->assertCount(3, \core_message\api::get_conversations($user1->id));
826
827 // And 2 favourited conversations.
828 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
829 $this->assertCount(2, $conversations);
830 }
831
832 /**
833 * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
834 */
835 public function test_get_favourite_conversations_limit_offset() {
836 // Create some users.
837 $user1 = self::getDataGenerator()->create_user();
838 $user2 = self::getDataGenerator()->create_user();
839 $user3 = self::getDataGenerator()->create_user();
840 $user4 = self::getDataGenerator()->create_user();
841
842 // The person doing the search.
843 $this->setUser($user1);
844
845 // No conversations yet.
846 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
847
848 // Create some conversations for user1.
849 $time = 1;
850 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
851 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
852 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
853 $messageid1 = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
854
855 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
856 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
857 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
858 $messageid2 = $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
859
860 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
861 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
862 $messageid3 = $this->send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
863
864 // Favourite the all conversations for user1.
865 $convoids = [];
866 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
867 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
868 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user4->id]);
869 $user1context = context_user::instance($user1->id);
870 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
871 foreach ($convoids as $convoid) {
872 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
873 }
874
875 // Get all records, using offset 0 and large limit.
876 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
877
878 // Now, get 10 conversations starting at the second record. We should see 2 conversations.
879 $this->assertCount(2, \core_message\api::get_conversations($user1->id, 1, 10, null, true));
880
881 // Now, try to get favourited conversations using an invalid offset.
882 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 4, 10, null, true));
883 }
884
885 /**
886 * Tests retrieving favourite conversations when a conversation contains a deleted user.
887 */
888 public function test_get_favourite_conversations_with_deleted_user() {
889 // Create some users.
890 $user1 = self::getDataGenerator()->create_user();
891 $user2 = self::getDataGenerator()->create_user();
892 $user3 = self::getDataGenerator()->create_user();
893
894 // Send some messages back and forth, have some different conversations with different users.
895 $time = 1;
896 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
897 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
898 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
899 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
900
901 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
902 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
903 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
904 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
905
906 // Favourite the all conversations for user1.
907 $convoids = [];
908 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
909 $convoids[] = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
910 $user1context = context_user::instance($user1->id);
911 $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
912 foreach ($convoids as $convoid) {
913 $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
914 }
915
916 // Delete the second user.
917 delete_user($user2);
918
919 // Retrieve the conversations.
920 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
921
922 // We should only have one conversation because the other user was deleted.
923 $this->assertCount(1, $conversations);
924
925 // Confirm the conversation is from the non-deleted user.
926 $conversation = reset($conversations);
eb5865da 927 $this->assertEquals($convoids[1], $conversation->id);
b8ff2c44
JD
928 }
929
930 /**
931 * Test confirming that conversations can be marked as favourites.
932 */
933 public function test_set_favourite_conversation() {
934 // Create some users.
935 $user1 = self::getDataGenerator()->create_user();
936 $user2 = self::getDataGenerator()->create_user();
937 $user3 = self::getDataGenerator()->create_user();
938
939 // Send some messages back and forth, have some different conversations with different users.
940 $time = 1;
941 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
942 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
943 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
944 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
945
946 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
947 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
948 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
949 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
950
951 // Favourite the first conversation as user 1.
952 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
9e189a91 953 $favourite = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
b8ff2c44
JD
954
955 // Verify we have a single favourite conversation a user 1.
956 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
957
958 // Verify we have no favourites as user2, despite being a member in that conversation.
959 $this->assertCount(0, \core_message\api::get_conversations($user2->id, 0, 20, null, true));
960
9e189a91
RW
961 // Try to favourite the same conversation again should just return the existing favourite.
962 $repeatresult = \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
963 $this->assertEquals($favourite->id, $repeatresult->id);
b8ff2c44
JD
964 }
965
966 /**
967 * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
968 */
969 public function test_set_favourite_conversation_nonexistent_conversation() {
970 // Create some users.
971 $user1 = self::getDataGenerator()->create_user();
972 // Try to favourite a non-existent conversation.
973 $this->expectException(\moodle_exception::class);
974 \core_message\api::set_favourite_conversation(0, $user1->id);
975 }
976
977 /**
978 * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
979 */
980 public function test_set_favourite_conversation_non_member() {
981 // Create some users.
982 $user1 = self::getDataGenerator()->create_user();
983 $user2 = self::getDataGenerator()->create_user();
984 $user3 = self::getDataGenerator()->create_user();
985
986 // Send some messages back and forth, have some different conversations with different users.
987 $time = 1;
988 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
989 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
990 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
991 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
992
993 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
994 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
995 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
996 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
997
998 // Try to favourite the first conversation as user 3, who is not a member.
999 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1000 $this->expectException(\moodle_exception::class);
1001 \core_message\api::set_favourite_conversation($conversationid1, $user3->id);
1002 }
1003
1004 /**
1005 * Test confirming that those conversations marked as favourites can be unfavourited.
1006 */
1007 public function test_unset_favourite_conversation() {
1008 // Create some users.
1009 $user1 = self::getDataGenerator()->create_user();
1010 $user2 = self::getDataGenerator()->create_user();
1011 $user3 = self::getDataGenerator()->create_user();
1012
1013 // Send some messages back and forth, have some different conversations with different users.
1014 $time = 1;
1015 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1016 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1017 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1018 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1019
1020 $this->send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
1021 $this->send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
1022 $this->send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
1023 $this->send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1024
1025 // Favourite the first conversation as user 1 and the second as user 3.
1026 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1027 $conversationid2 = \core_message\api::get_conversation_between_users([$user1->id, $user3->id]);
1028 \core_message\api::set_favourite_conversation($conversationid1, $user1->id);
1029 \core_message\api::set_favourite_conversation($conversationid2, $user3->id);
1030
1031 // Verify we have a single favourite conversation for both user 1 and user 3.
1032 $this->assertCount(1, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1033 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1034
1035 // Now unfavourite the conversation as user 1.
1036 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1037
1038 // Verify we have a single favourite conversation user 3 only, and none for user1.
1039 $this->assertCount(1, \core_message\api::get_conversations($user3->id, 0, 20, null, true));
1040 $this->assertCount(0, \core_message\api::get_conversations($user1->id, 0, 20, null, true));
1041
1042 // Try to favourite the same conversation again as user 1.
1043 $this->expectException(\moodle_exception::class);
1044 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1045 }
1046
1047 /**
1048 * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
1049 */
1050 public function test_unset_favourite_conversation_not_favourite() {
1051 // Create some users.
1052 $user1 = self::getDataGenerator()->create_user();
1053 $user2 = self::getDataGenerator()->create_user();
1054
1055 // Send some messages back and forth, have some different conversations with different users.
1056 $time = 1;
1057 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1058 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1059 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1060 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1061
1062 // Now try to unfavourite the conversation as user 1.
1063 $conversationid1 = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
1064 $this->expectException(\moodle_exception::class);
1065 \core_message\api::unset_favourite_conversation($conversationid1, $user1->id);
1066 }
1067
1068 /**
1069 * Test verifying that a non-existent conversation cannot be unset as a favourite.
1070 */
1071 public function test_unset_favourite_conversation_non_existent_conversation() {
1072 // Create some users.
1073 $user1 = self::getDataGenerator()->create_user();
1074
1075 // Now try to unfavourite the conversation as user 1.
1076 $this->expectException(\moodle_exception::class);
1077 \core_message\api::unset_favourite_conversation(0, $user1->id);
1078 }
1079
1f64514d 1080 /**
eb5865da 1081 * Helper to seed the database with initial state.
1f64514d 1082 */
eb5865da 1083 protected function create_conversation_test_data() {
1f64514d
MN
1084 // Create some users.
1085 $user1 = self::getDataGenerator()->create_user();
1086 $user2 = self::getDataGenerator()->create_user();
1087 $user3 = self::getDataGenerator()->create_user();
1088 $user4 = self::getDataGenerator()->create_user();
1089
eb5865da 1090 $time = 1;
1f64514d 1091
eb5865da
JD
1092 // Create some conversations. We want:
1093 // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
1094 // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
1095 // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
1096 // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
1097 // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
1098
1099 // Individual conversation, user1 is a member, last message from other user.
1100 $ic1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1101 [$user1->id, $user2->id]);
1102 testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
1103 testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
1104
1105 // Individual conversation, user1 is a member, last message from user1.
1106 $ic2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1107 [$user1->id, $user3->id]);
1108 testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
1109 testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
1110
1111 // Individual conversation, user1 is not a member.
1112 $ic3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1113 [$user2->id, $user3->id]);
1114 testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
1115 testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
1116
1117 // Group conversation, user1 is not a member.
1118 $gc1 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1119 [$user2->id, $user3->id, $user4->id], 'Project discussions');
1120 testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
1121 testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
1122
1123 // Group conversation, user1 is a member, last message from another user.
1124 $gc2 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1125 [$user1->id, $user3->id, $user4->id], 'Group chat');
1126 testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
1127 testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
1128 testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
1129
1130 // Group conversation, user1 is a member, last message from user1.
1131 $gc3 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1132 [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
1133 testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
1134 testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
1135 testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
1136
1137 // Empty group conversations (x2), user1 is a member.
1138 $gc4 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1139 [$user1->id, $user2->id, $user3->id], 'Empty group');
1140 $gc5 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1141 [$user1->id, $user2->id, $user4->id], 'Another empty group');
1142
1143 // Empty group conversation, user1 is NOT a member.
1144 $gc6 = \core_message\api::create_conversation(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1145 [$user2->id, $user3->id, $user4->id], 'Empty group 3');
1146
1147 return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
1148 }
bb2924d0 1149
eb5865da
JD
1150 /**
1151 * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
1152 */
1153 public function test_get_conversations_no_restrictions() {
74fc14e5 1154 global $DB;
eb5865da
JD
1155 // No conversations should exist yet.
1156 $user1 = self::getDataGenerator()->create_user();
1157 $this->assertEquals([], \core_message\api::get_conversations($user1->id));
1f64514d 1158
eb5865da
JD
1159 // Get a bunch of conversations, some group, some individual and in different states.
1160 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1161 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1162
1163 // Get all conversations for user1.
1164 $conversations = core_message\api::get_conversations($user1->id);
1165
1166 // Verify there are 2 individual conversation, 2 group conversations, and 2 empty group conversations.
1167 // The conversations with the most recent messages should be listed first, followed by the empty
1168 // conversations, with the most recently created first.
1169 $this->assertCount(6, $conversations);
1170 $typecounts = array_count_values(array_column($conversations, 'type'));
1171 $this->assertEquals(2, $typecounts[1]);
1172 $this->assertEquals(4, $typecounts[2]);
1173
1174 // Those conversations having messages should be listed first, ordered by most recent message time.
1175 $this->assertEquals($gc3->id, $conversations[0]->id);
1176 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
1177 $this->assertFalse($conversations[0]->isfavourite);
1178 $this->assertCount(1, $conversations[0]->members);
1179 $this->assertEquals(4, $conversations[0]->membercount);
1180 $this->assertCount(1, $conversations[0]->messages);
74fc14e5
JD
1181 $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]);
1182 $expectedmessagetext = message_format_message_text($message);
1183 $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text);
eb5865da
JD
1184 $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
1185
1186 $this->assertEquals($gc2->id, $conversations[1]->id);
1187 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
1188 $this->assertFalse($conversations[1]->isfavourite);
1189 $this->assertCount(1, $conversations[1]->members);
1190 $this->assertEquals(3, $conversations[1]->membercount);
1191 $this->assertCount(1, $conversations[1]->messages);
74fc14e5
JD
1192 $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]);
1193 $expectedmessagetext = message_format_message_text($message);
1194 $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text);
eb5865da
JD
1195 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1196
1197 $this->assertEquals($ic2->id, $conversations[2]->id);
1198 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
1199 $this->assertFalse($conversations[2]->isfavourite);
1200 $this->assertCount(1, $conversations[2]->members);
1201 $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
1202 $this->assertEquals(2, $conversations[2]->membercount);
1203 $this->assertCount(1, $conversations[2]->messages);
74fc14e5
JD
1204 $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]);
1205 $expectedmessagetext = message_format_message_text($message);
1206 $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text);
eb5865da
JD
1207 $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
1208
1209 $this->assertEquals($ic1->id, $conversations[3]->id);
1210 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
1211 $this->assertFalse($conversations[3]->isfavourite);
1212 $this->assertCount(1, $conversations[3]->members);
1213 $this->assertEquals(2, $conversations[3]->membercount);
1214 $this->assertCount(1, $conversations[3]->messages);
74fc14e5
JD
1215 $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]);
1216 $expectedmessagetext = message_format_message_text($message);
1217 $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text);
eb5865da
JD
1218 $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
1219
1220 // Of the groups without messages, we expect to see the most recently created first.
1221 $this->assertEquals($gc5->id, $conversations[4]->id);
1222 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
1223 $this->assertFalse($conversations[4]->isfavourite);
1224 $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
1225 $this->assertEquals(3, $conversations[4]->membercount);
1226 $this->assertEmpty($conversations[4]->messages);
1227
1228 $this->assertEquals($gc4->id, $conversations[5]->id);
1229 $this->assertEquals(\core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
1230 $this->assertFalse($conversations[5]->isfavourite);
1231 $this->assertCount(0, $conversations[5]->members);
1232 $this->assertEquals(3, $conversations[5]->membercount);
1233 $this->assertEmpty($conversations[5]->messages);
1234
1235 // Verify format of the return structure.
1236 foreach ($conversations as $conv) {
1237 $this->assertObjectHasAttribute('id', $conv);
1238 $this->assertObjectHasAttribute('name', $conv);
1239 $this->assertObjectHasAttribute('subname', $conv);
003cdcce 1240 $this->assertObjectHasAttribute('imageurl', $conv);
eb5865da
JD
1241 $this->assertObjectHasAttribute('type', $conv);
1242 $this->assertObjectHasAttribute('isfavourite', $conv);
1243 $this->assertObjectHasAttribute('membercount', $conv);
1244 $this->assertObjectHasAttribute('isread', $conv);
1245 $this->assertObjectHasAttribute('unreadcount', $conv);
1246 $this->assertObjectHasAttribute('members', $conv);
1247 foreach ($conv->members as $member) {
1248 $this->assertObjectHasAttribute('id', $member);
1249 $this->assertObjectHasAttribute('fullname', $member);
1250 $this->assertObjectHasAttribute('profileimageurl', $member);
1251 $this->assertObjectHasAttribute('profileimageurlsmall', $member);
1252 $this->assertObjectHasAttribute('isonline', $member);
1253 $this->assertObjectHasAttribute('showonlinestatus', $member);
1254 $this->assertObjectHasAttribute('isblocked', $member);
1255 $this->assertObjectHasAttribute('iscontact', $member);
d15c1e77 1256 $this->assertObjectHasAttribute('isdeleted', $member);
cef1d977
MN
1257 $this->assertObjectHasAttribute('canmessage', $member);
1258 $this->assertObjectHasAttribute('requirescontact', $member);
1259 $this->assertObjectHasAttribute('contactrequests', $member);
eb5865da
JD
1260 }
1261 $this->assertObjectHasAttribute('messages', $conv);
1262 foreach ($conv->messages as $message) {
1263 $this->assertObjectHasAttribute('id', $message);
1264 $this->assertObjectHasAttribute('useridfrom', $message);
1265 $this->assertObjectHasAttribute('text', $message);
1266 $this->assertObjectHasAttribute('timecreated', $message);
1267 }
1268 }
1269 }
1f64514d 1270
74fc14e5
JD
1271 /**
1272 * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately.
1273 */
1274 public function test_get_conversations_message_format() {
1275 global $DB;
1276 // Create some users.
1277 $user1 = self::getDataGenerator()->create_user();
1278 $user2 = self::getDataGenerator()->create_user();
1279
1280 // Create conversation.
1281 $conversation = \core_message\api::create_conversation(
1282 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1283 [$user1->id, $user2->id]
1284 );
1285
1286 // Send some messages back and forth.
1287 $time = 1;
1288 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1);
1289 $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2);
1290
1291 // Verify the format of the html message.
1292 $message = $DB->get_record('messages', ['id' => $mid]);
1293 $expectedmessagetext = message_format_message_text($message);
1294 $conversations = \core_message\api::get_conversations($user1->id);
1295 $messages = $conversations[0]->messages;
1296 $this->assertEquals($expectedmessagetext, $messages[0]->text);
1297 }
1298
eb5865da
JD
1299 /**
1300 * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
1301 */
1302 public function test_get_conversations_limit_offset() {
1303 // Get a bunch of conversations, some group, some individual and in different states.
1304 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1305 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1f64514d 1306
eb5865da
JD
1307 // Get all conversations for user1, limited to 1 result.
1308 $conversations = core_message\api::get_conversations($user1->id, 0, 1);
1f64514d 1309
eb5865da
JD
1310 // Verify the first conversation.
1311 $this->assertCount(1, $conversations);
1312 $conversation = array_shift($conversations);
1313 $this->assertEquals($conversation->id, $gc3->id);
1f64514d 1314
eb5865da
JD
1315 // Verify the next conversation.
1316 $conversations = \core_message\api::get_conversations($user1->id, 1, 1);
1317 $this->assertCount(1, $conversations);
1318 $this->assertEquals($gc2->id, $conversations[0]->id);
1f64514d 1319
eb5865da
JD
1320 // Verify the next conversation.
1321 $conversations = \core_message\api::get_conversations($user1->id, 2, 1);
1322 $this->assertCount(1, $conversations);
1323 $this->assertEquals($ic2->id, $conversations[0]->id);
1f64514d 1324
eb5865da
JD
1325 // Skip one and get both empty conversations.
1326 $conversations = \core_message\api::get_conversations($user1->id, 4, 2);
1327 $this->assertCount(2, $conversations);
1328 $this->assertEquals($gc5->id, $conversations[0]->id);
1329 $this->assertEmpty($conversations[0]->messages);
1330 $this->assertEquals($gc4->id, $conversations[1]->id);
1331 $this->assertEmpty($conversations[1]->messages);
1f64514d 1332
eb5865da
JD
1333 // Ask for an offset that doesn't exist and verify no conversations are returned.
1334 $conversations = \core_message\api::get_conversations($user1->id, 10, 1);
1335 $this->assertCount(0, $conversations);
1f64514d
MN
1336 }
1337
4d146f1a 1338 /**
eb5865da 1339 * Test verifying the type filtering behaviour of the
4d146f1a 1340 */
eb5865da
JD
1341 public function test_get_conversations_type_filter() {
1342 // Get a bunch of conversations, some group, some individual and in different states.
1343 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1344 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1345
1346 // Verify we can ask for only individual conversations.
1347 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1348 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1349 $this->assertCount(2, $conversations);
4d146f1a 1350
eb5865da
JD
1351 // Verify we can ask for only group conversations.
1352 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1353 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP);
1354 $this->assertCount(4, $conversations);
4d146f1a 1355
eb5865da
JD
1356 // Verify an exception is thrown if an unrecognized type is specified.
1357 $this->expectException(\moodle_exception::class);
1358 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, 0);
1359 }
4d146f1a 1360
eb5865da
JD
1361 /**
1362 * Tests retrieving conversations when a conversation contains a deleted user.
1363 */
1364 public function test_get_conversations_with_deleted_user() {
1365 // Get a bunch of conversations, some group, some individual and in different states.
1366 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1367 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
4d146f1a 1368
eb5865da
JD
1369 // Delete the second user and retrieve the conversations.
1370 // We should have 5, as $ic1 drops off the list.
1371 // Group conversations remain albeit with less members.
1372 delete_user($user2);
52beee65
MN
1373 // This is to confirm an exception is not thrown when a user AND the user context is deleted.
1374 // We no longer delete the user context, but historically we did.
1375 context_helper::delete_instance(CONTEXT_USER, $user2->id);
eb5865da
JD
1376 $conversations = \core_message\api::get_conversations($user1->id);
1377 $this->assertCount(5, $conversations);
1378 $this->assertEquals($gc3->id, $conversations[0]->id);
1379 $this->assertcount(1, $conversations[0]->members);
1380 $this->assertEquals($gc2->id, $conversations[1]->id);
1381 $this->assertcount(1, $conversations[1]->members);
1382 $this->assertEquals($ic2->id, $conversations[2]->id);
1383 $this->assertEquals($gc5->id, $conversations[3]->id);
1384 $this->assertEquals($gc4->id, $conversations[4]->id);
1385
1386 // Delete a user from a group conversation where that user had sent the most recent message.
1387 // This user will still be present in the members array, as will the message in the messages array.
1388 delete_user($user4);
1389 $conversations = \core_message\api::get_conversations($user1->id);
1390 $this->assertCount(5, $conversations);
1391 $this->assertEquals($gc2->id, $conversations[1]->id);
1392 $this->assertcount(1, $conversations[1]->members);
1393 $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
1394 $this->assertcount(1, $conversations[1]->messages);
1395 $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1396
1397 // Delete the third user and retrieve the conversations.
1398 // We should have 4, as $ic1, $ic2 drop off the list.
1399 // Group conversations remain albeit with less members.
1400 delete_user($user3);
1401 $conversations = \core_message\api::get_conversations($user1->id);
1402 $this->assertCount(4, $conversations);
1403 $this->assertEquals($gc3->id, $conversations[0]->id);
1404 $this->assertcount(1, $conversations[0]->members);
1405 $this->assertEquals($gc2->id, $conversations[1]->id);
1406 $this->assertcount(1, $conversations[1]->members);
1407 $this->assertEquals($gc5->id, $conversations[2]->id);
1408 $this->assertEquals($gc4->id, $conversations[3]->id);
1409 }
4d146f1a 1410
aa748351
JD
1411 /**
1412 * Test confirming the behaviour of get_conversations() when users delete all messages.
1413 */
1414 public function test_get_conversations_deleted_messages() {
1415 // Get a bunch of conversations, some group, some individual and in different states.
1416 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1417 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1418
1419 $conversations = \core_message\api::get_conversations($user1->id);
1420 $this->assertCount(6, $conversations);
1421
1422 // Delete all messages from a group conversation the user is in - it should be returned.
1423 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $gc2->id));
1424 $convmessages = \core_message\api::get_conversation_messages($user1->id, $gc2->id);
1425 $messages = $convmessages['messages'];
1426 foreach ($messages as $message) {
1427 \core_message\api::delete_message($user1->id, $message->id);
1428 }
1429 $conversations = \core_message\api::get_conversations($user1->id);
1430 $this->assertCount(6, $conversations);
1431 $this->assertContains($gc2->id, array_column($conversations, 'id'));
1432
1433 // Delete all messages from an individual conversation the user is in - it should not be returned.
1434 $this->assertTrue(\core_message\api::is_user_in_conversation($user1->id, $ic1->id));
1435 $convmessages = \core_message\api::get_conversation_messages($user1->id, $ic1->id);
1436 $messages = $convmessages['messages'];
1437 foreach ($messages as $message) {
1438 \core_message\api::delete_message($user1->id, $message->id);
1439 }
1440 $conversations = \core_message\api::get_conversations($user1->id);
1441 $this->assertCount(5, $conversations);
1442 $this->assertNotContains($ic1->id, array_column($conversations, 'id'));
1443 }
1444
e926b4d0
AN
1445 /**
1446 * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single
1447 * favourite.
1448 */
1449 public function test_get_conversations_favourite_conversations_single() {
1450 // Get a bunch of conversations, some group, some individual and in different states.
1451 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1452 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1453
1454 // Mark a single conversation as favourites.
1455 \core_message\api::set_favourite_conversation($ic2->id, $user1->id);
1456
1457 // Get the conversation, first with no restrictions, confirming the favourite status of the conversations.
1458 $conversations = \core_message\api::get_conversations($user1->id);
1459 $this->assertCount(6, $conversations);
1460 foreach ($conversations as $conv) {
1461 if (in_array($conv->id, [$ic2->id])) {
1462 $this->assertTrue($conv->isfavourite);
1463 } else {
1464 $this->assertFalse($conv->isfavourite);
1465 }
1466 }
1467
1468 // Now, get ONLY favourite conversations.
1469 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1470 $this->assertCount(1, $conversations);
1471 foreach ($conversations as $conv) {
1472 $this->assertTrue($conv->isfavourite);
1473 $this->assertEquals($ic2->id, $conv->id);
1474 }
1475
1476 // Now, try ONLY favourites of type 'group'.
1477 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1478 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1479 $this->assertEmpty($conversations);
1480
1481 // And NO favourite conversations.
1482 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1483 $this->assertCount(5, $conversations);
1484 foreach ($conversations as $conv) {
1485 $this->assertFalse($conv->isfavourite);
1486 $this->assertNotEquals($ic2, $conv->id);
1487 }
1488 }
1489
eb5865da
JD
1490 /**
1491 * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
1492 */
1493 public function test_get_conversations_favourite_conversations() {
1494 // Get a bunch of conversations, some group, some individual and in different states.
1495 list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1496 $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
4d146f1a 1497
eb5865da
JD
1498 // Try to get ONLY favourite conversations, when no favourites exist.
1499 $this->assertEquals([], \core_message\api::get_conversations($user1->id, 0, 20, null, true));
4d146f1a 1500
eb5865da
JD
1501 // Try to get NO favourite conversations, when no favourites exist.
1502 $this->assertCount(6, \core_message\api::get_conversations($user1->id, 0, 20, null, false));
4d146f1a 1503
eb5865da
JD
1504 // Mark a few conversations as favourites.
1505 \core_message\api::set_favourite_conversation($ic1->id, $user1->id);
1506 \core_message\api::set_favourite_conversation($gc2->id, $user1->id);
1507 \core_message\api::set_favourite_conversation($gc5->id, $user1->id);
e926b4d0 1508 $favouriteids = [$ic1->id, $gc2->id, $gc5->id];
4d146f1a 1509
eb5865da
JD
1510 // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
1511 $conversations = \core_message\api::get_conversations($user1->id);
1512 $this->assertCount(6, $conversations);
1513 foreach ($conversations as $conv) {
e926b4d0 1514 if (in_array($conv->id, $favouriteids)) {
eb5865da 1515 $this->assertTrue($conv->isfavourite);
e926b4d0
AN
1516 } else {
1517 $this->assertFalse($conv->isfavourite);
eb5865da
JD
1518 }
1519 }
4d146f1a 1520
eb5865da
JD
1521 // Now, get ONLY favourite conversations.
1522 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, true);
1523 $this->assertCount(3, $conversations);
1524 foreach ($conversations as $conv) {
1525 $this->assertTrue($conv->isfavourite);
e926b4d0 1526 $this->assertNotFalse(array_search($conv->id, $favouriteids));
eb5865da 1527 }
4d146f1a 1528
eb5865da
JD
1529 // Now, try ONLY favourites of type 'group'.
1530 $conversations = \core_message\api::get_conversations($user1->id, 0, 20,
1531 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1532 $this->assertCount(2, $conversations);
1533 foreach ($conversations as $conv) {
1534 $this->assertTrue($conv->isfavourite);
e926b4d0 1535 $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id]));
eb5865da 1536 }
4d146f1a 1537
eb5865da
JD
1538 // And NO favourite conversations.
1539 $conversations = \core_message\api::get_conversations($user1->id, 0, 20, null, false);
1540 $this->assertCount(3, $conversations);
1541 foreach ($conversations as $conv) {
1542 $this->assertFalse($conv->isfavourite);
e926b4d0 1543 $this->assertFalse(array_search($conv->id, $favouriteids));
eb5865da 1544 }
4d146f1a
RW
1545 }
1546
cef1d977
MN
1547 /**
1548 * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this
1549 * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want
1550 * to confirm this happens.
1551 */
1552 public function test_get_conversations_user_in_group_and_individual_chat() {
1553 $this->resetAfterTest();
1554
1555 $user1 = self::getDataGenerator()->create_user();
1556 $user2 = self::getDataGenerator()->create_user();
1557 $user3 = self::getDataGenerator()->create_user();
1558
1559 $conversation = \core_message\api::create_conversation(
1560 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1561 [
1562 $user1->id,
1563 $user2->id
1564 ],
1565 'Individual conversation'
1566 );
1567
1568 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1569
1570 $conversation = \core_message\api::create_conversation(
1571 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
1572 [
1573 $user1->id,
1574 $user2->id,
1575 ],
1576 'Group conversation'
1577 );
1578
1579 testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1580
1581 \core_message\api::create_contact_request($user1->id, $user2->id);
1582 \core_message\api::create_contact_request($user1->id, $user3->id);
1583
1584 $conversations = \core_message\api::get_conversations($user2->id);
1585
1586 $groupconversation = array_shift($conversations);
1587 $individualconversation = array_shift($conversations);
1588
1589 $this->assertEquals('Group conversation', $groupconversation->name);
1590 $this->assertEquals('Individual conversation', $individualconversation->name);
1591
1592 $this->assertCount(1, $groupconversation->members);
1593 $this->assertCount(1, $individualconversation->members);
1594
1595 $groupmember = reset($groupconversation->members);
1596 $this->assertNull($groupmember->requirescontact);
1597 $this->assertNull($groupmember->canmessage);
1598 $this->assertEmpty($groupmember->contactrequests);
1599
1600 $individualmember = reset($individualconversation->members);
1601 $this->assertNotNull($individualmember->requirescontact);
1602 $this->assertNotNull($individualmember->canmessage);
1603 $this->assertNotEmpty($individualmember->contactrequests);
1604 }
1605
f512355b 1606 /**
eb5865da 1607 * Test verifying that group linked conversations are returned and contain a subname matching the course name.
f512355b 1608 */
eb5865da 1609 public function test_get_conversations_group_linked() {
003cdcce
JD
1610 global $CFG;
1611
f512355b
MN
1612 // Create some users.
1613 $user1 = self::getDataGenerator()->create_user();
1614 $user2 = self::getDataGenerator()->create_user();
1615 $user3 = self::getDataGenerator()->create_user();
1616
eb5865da 1617 $course1 = $this->getDataGenerator()->create_course();
f512355b 1618
9cef5491 1619 // Create a group with a linked conversation and a valid image.
eb5865da
JD
1620 $this->setAdminUser();
1621 $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1622 $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1623 $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
003cdcce
JD
1624 $group1 = $this->getDataGenerator()->create_group([
1625 'courseid' => $course1->id,
1626 'enablemessaging' => 1,
1627 'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
1628 ]);
f512355b 1629
eb5865da
JD
1630 // Add users to group1.
1631 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1632 $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
f512355b 1633
9cef5491 1634 // Verify the group with the image works as expected.
f512355b 1635 $conversations = \core_message\api::get_conversations($user1->id);
003cdcce 1636 $this->assertEquals(2, $conversations[0]->membercount);
eb5865da 1637 $this->assertEquals($course1->shortname, $conversations[0]->subname);
003cdcce
JD
1638 $groupimageurl = get_group_picture_url($group1, $group1->courseid, true);
1639 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
9cef5491
JD
1640
1641 // Create a group with a linked conversation and without any image.
1642 $group2 = $this->getDataGenerator()->create_group([
1643 'courseid' => $course1->id,
1644 'enablemessaging' => 1,
1645 ]);
1646
1647 // Add users to group2.
1648 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1649 $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
1650
1651 // Verify the group without any image works as expected too.
1652 $conversations = \core_message\api::get_conversations($user3->id);
1653 $this->assertEquals(2, $conversations[0]->membercount);
1654 $this->assertEquals($course1->shortname, $conversations[0]->subname);
1655 $groupimageurl = get_group_picture_url($group2, $group2->courseid, true);
1656 $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
f512355b
MN
1657 }
1658
e12d9f49
RW
1659 /**
1660 * The data provider for get_conversations_mixed.
1661 *
1662 * This provides sets of data to for testing.
1663 * @return array
1664 */
1665 public function get_conversations_mixed_provider() {
1666 return array(
4d146f1a
RW
1667 'Test that conversations with messages contacts is correctly ordered.' => array(
1668 'users' => array(
1669 'user1',
1670 'user2',
1671 'user3',
1672 ),
1673 'contacts' => array(
1674 ),
1675 'messages' => array(
1676 array(
1677 'from' => 'user1',
1678 'to' => 'user2',
1679 'state' => 'unread',
1680 'subject' => 'S1',
1681 ),
1682 array(
1683 'from' => 'user2',
1684 'to' => 'user1',
1685 'state' => 'unread',
1686 'subject' => 'S2',
1687 ),
1688 array(
1689 'from' => 'user1',
1690 'to' => 'user2',
1691 'state' => 'unread',
1692 'timecreated' => 0,
1693 'subject' => 'S3',
1694 ),
1695 array(
1696 'from' => 'user1',
1697 'to' => 'user3',
1698 'state' => 'read',
1699 'timemodifier' => 1,
1700 'subject' => 'S4',
1701 ),
1702 array(
1703 'from' => 'user3',
1704 'to' => 'user1',
1705 'state' => 'read',
1706 'timemodifier' => 1,
1707 'subject' => 'S5',
1708 ),
1709 array(
1710 'from' => 'user1',
1711 'to' => 'user3',
1712 'state' => 'read',
1713 'timecreated' => 0,
1714 'subject' => 'S6',
1715 ),
1716 ),
1717 'expectations' => array(
1718 'user1' => array(
1719 // User1 has conversed most recently with user3. The most recent message is M5.
1720 array(
1721 'messageposition' => 0,
1722 'with' => 'user3',
74fc14e5 1723 'subject' => '<p>S5</p>',
e12d9f49 1724 'unreadcount' => 0,
4d146f1a
RW
1725 ),
1726 // User1 has also conversed with user2. The most recent message is S2.
1727 array(
1728 'messageposition' => 1,
1729 'with' => 'user2',
74fc14e5 1730 'subject' => '<p>S2</p>',
e12d9f49 1731 'unreadcount' => 1,
4d146f1a
RW
1732 ),
1733 ),
1734 'user2' => array(
1735 // User2 has only conversed with user1. Their most recent shared message was S2.
1736 array(
1737 'messageposition' => 0,
1738 'with' => 'user1',
74fc14e5 1739 'subject' => '<p>S2</p>',
e12d9f49 1740 'unreadcount' => 2,
4d146f1a
RW
1741 ),
1742 ),
1743 'user3' => array(
1744 // User3 has only conversed with user1. Their most recent shared message was S5.
1745 array(
1746 'messageposition' => 0,
1747 'with' => 'user1',
74fc14e5 1748 'subject' => '<p>S5</p>',
e12d9f49 1749 'unreadcount' => 0,
4d146f1a
RW
1750 ),
1751 ),
1752 ),
1753 ),
4d146f1a
RW
1754 'Test conversations with a single user, where some messages are read and some are not.' => array(
1755 'users' => array(
1756 'user1',
1757 'user2',
1758 ),
1759 'contacts' => array(
1760 ),
1761 'messages' => array(
1762 array(
1763 'from' => 'user1',
1764 'to' => 'user2',
1765 'state' => 'read',
1766 'subject' => 'S1',
1767 ),
1768 array(
1769 'from' => 'user2',
1770 'to' => 'user1',
1771 'state' => 'read',
1772 'subject' => 'S2',
1773 ),
1774 array(
1775 'from' => 'user1',
1776 'to' => 'user2',
1777 'state' => 'unread',
1778 'timemodifier' => 1,
1779 'subject' => 'S3',
1780 ),
1781 array(
1782 'from' => 'user1',
1783 'to' => 'user2',
1784 'state' => 'unread',
1785 'timemodifier' => 1,
1786 'subject' => 'S4',
1787 ),
1788 ),
1789 'expectations' => array(
1790 // The most recent message between user1 and user2 was S4.
1791 'user1' => array(
1792 array(
1793 'messageposition' => 0,
1794 'with' => 'user2',
74fc14e5 1795 'subject' => '<p>S4</p>',
e12d9f49 1796 'unreadcount' => 0,
4d146f1a
RW
1797 ),
1798 ),
1799 'user2' => array(
1800 // The most recent message between user1 and user2 was S4.
1801 array(
1802 'messageposition' => 0,
1803 'with' => 'user1',
74fc14e5 1804 'subject' => '<p>S4</p>',
e12d9f49 1805 'unreadcount' => 2,
4d146f1a
RW
1806 ),
1807 ),
1808 ),
1809 ),
1810 'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1811 'are out of order' => array(
1812 // This can happen through a combination of factors including multi-master DB replication with messages
1813 // read somehow (e.g. API).
1814 'users' => array(
1815 'user1',
1816 'user2',
1817 ),
1818 'contacts' => array(
1819 ),
1820 'messages' => array(
1821 array(
1822 'from' => 'user1',
1823 'to' => 'user2',
1824 'state' => 'read',
1825 'subject' => 'S1',
1826 'timemodifier' => 1,
1827 ),
1828 array(
1829 'from' => 'user2',
1830 'to' => 'user1',
1831 'state' => 'read',
1832 'subject' => 'S2',
1833 'timemodifier' => 2,
1834 ),
1835 array(
1836 'from' => 'user1',
1837 'to' => 'user2',
1838 'state' => 'unread',
1839 'subject' => 'S3',
1840 ),
1841 array(
1842 'from' => 'user1',
1843 'to' => 'user2',
1844 'state' => 'unread',
1845 'subject' => 'S4',
1846 ),
1847 ),
1848 'expectations' => array(
1849 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1850 'user1' => array(
1851 array(
1852 'messageposition' => 0,
1853 'with' => 'user2',
74fc14e5 1854 'subject' => '<p>S2</p>',
e12d9f49 1855 'unreadcount' => 0,
4d146f1a
RW
1856 ),
1857 ),
1858 'user2' => array(
1859 array(
1860 'messageposition' => 0,
1861 'with' => 'user1',
74fc14e5 1862 'subject' => '<p>S2</p>',
e12d9f49
RW
1863 'unreadcount' => 2
1864 ),
1865 ),
1866 ),
1867 ),
1868 'Test unread message count is correct for both users' => array(
1869 'users' => array(
1870 'user1',
1871 'user2',
1872 ),
1873 'contacts' => array(
1874 ),
1875 'messages' => array(
1876 array(
1877 'from' => 'user1',
1878 'to' => 'user2',
1879 'state' => 'read',
1880 'subject' => 'S1',
1881 'timemodifier' => 1,
1882 ),
1883 array(
1884 'from' => 'user2',
1885 'to' => 'user1',
1886 'state' => 'read',
1887 'subject' => 'S2',
1888 'timemodifier' => 2,
1889 ),
1890 array(
1891 'from' => 'user1',
1892 'to' => 'user2',
1893 'state' => 'read',
1894 'subject' => 'S3',
1895 'timemodifier' => 3,
1896 ),
1897 array(
1898 'from' => 'user1',
1899 'to' => 'user2',
1900 'state' => 'read',
1901 'subject' => 'S4',
1902 'timemodifier' => 4,
1903 ),
1904 array(
1905 'from' => 'user1',
1906 'to' => 'user2',
1907 'state' => 'unread',
1908 'subject' => 'S5',
1909 'timemodifier' => 5,
1910 ),
1911 array(
1912 'from' => 'user2',
1913 'to' => 'user1',
1914 'state' => 'unread',
1915 'subject' => 'S6',
1916 'timemodifier' => 6,
1917 ),
1918 array(
1919 'from' => 'user1',
1920 'to' => 'user2',
1921 'state' => 'unread',
1922 'subject' => 'S7',
1923 'timemodifier' => 7,
1924 ),
1925 array(
1926 'from' => 'user1',
1927 'to' => 'user2',
1928 'state' => 'unread',
1929 'subject' => 'S8',
1930 'timemodifier' => 8,
1931 ),
1932 ),
1933 'expectations' => array(
1934 // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
1935 'user1' => array(
1936 array(
1937 'messageposition' => 0,
1938 'with' => 'user2',
74fc14e5 1939 'subject' => '<p>S8</p>',
e12d9f49
RW
1940 'unreadcount' => 1,
1941 ),
1942 ),
1943 'user2' => array(
1944 array(
1945 'messageposition' => 0,
1946 'with' => 'user1',
74fc14e5 1947 'subject' => '<p>S8</p>',
e12d9f49 1948 'unreadcount' => 3,
4d146f1a
RW
1949 ),
1950 ),
1951 ),
1952 ),
1953 );
1954 }
1955
1956 /**
1957 * Test get_conversations with a mixture of messages.
1958 *
1959 * @dataProvider get_conversations_mixed_provider
1960 * @param array $usersdata The list of users to create for this test.
1961 * @param array $messagesdata The list of messages to create.
1962 * @param array $expectations The list of expected outcomes.
1963 */
1964 public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations) {
1965 global $DB;
1966
1967 // Create all of the users.
1968 $users = array();
1969 foreach ($usersdata as $username) {
1970 $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
1971 }
1972
1973 foreach ($contacts as $username => $contact) {
1974 foreach ($contact as $contactname => $blocked) {
1975 $record = new stdClass();
1976 $record->userid = $users[$username]->id;
1977 $record->contactid = $users[$contactname]->id;
1978 $record->blocked = $blocked;
1979 $record->id = $DB->insert_record('message_contacts', $record);
1980 }
1981 }
1982
1983 $defaulttimecreated = time();
1984 foreach ($messagesdata as $messagedata) {
1985 $from = $users[$messagedata['from']];
1986 $to = $users[$messagedata['to']];
1987 $subject = $messagedata['subject'];
1988
1989 if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
4d146f1a
RW
1990 $messageid = $this->send_fake_message($from, $to, $subject);
1991 } else {
1992 // If there is no state, or the state is not 'unread', assume the message is read.
4d146f1a
RW
1993 $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
1994 }
1995
1996 $updatemessage = new stdClass();
1997 $updatemessage->id = $messageid;
1998 if (isset($messagedata['timecreated'])) {
1999 $updatemessage->timecreated = $messagedata['timecreated'];
2000 } else if (isset($messagedata['timemodifier'])) {
2001 $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
2002 } else {
2003 $updatemessage->timecreated = $defaulttimecreated;
2004 }
e12d9f49 2005
883ce421 2006 $DB->update_record('messages', $updatemessage);
4d146f1a
RW
2007 }
2008
2009 foreach ($expectations as $username => $data) {
2010 // Get the recent conversations for the specified user.
2011 $user = $users[$username];
2012 $conversations = array_values(\core_message\api::get_conversations($user->id));
2013 foreach ($data as $expectation) {
2014 $otheruser = $users[$expectation['with']];
2015 $conversation = $conversations[$expectation['messageposition']];
eb5865da
JD
2016 $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
2017 $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
e12d9f49 2018 $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
4d146f1a
RW
2019 }
2020 }
2021 }
2022
1f64514d
MN
2023 /**
2024 * Tests retrieving contacts.
2025 */
2026 public function test_get_contacts() {
2027 // Create some users.
2028 $user1 = self::getDataGenerator()->create_user();
2029
2030 // Set as the user.
2031 $this->setUser($user1);
2032
2033 $user2 = new stdClass();
2034 $user2->firstname = 'User';
2035 $user2->lastname = 'A';
2036 $user2 = self::getDataGenerator()->create_user($user2);
2037
2038 $user3 = new stdClass();
2039 $user3->firstname = 'User';
2040 $user3->lastname = 'B';
2041 $user3 = self::getDataGenerator()->create_user($user3);
2042
2043 $user4 = new stdClass();
2044 $user4->firstname = 'User';
2045 $user4->lastname = 'C';
2046 $user4 = self::getDataGenerator()->create_user($user4);
2047
2048 $user5 = new stdClass();
2049 $user5->firstname = 'User';
2050 $user5->lastname = 'D';
2051 $user5 = self::getDataGenerator()->create_user($user5);
2052
2053 // Add some users as contacts.
f219eac7
MN
2054 \core_message\api::add_contact($user1->id, $user2->id);
2055 \core_message\api::add_contact($user1->id, $user3->id);
2056 \core_message\api::add_contact($user1->id, $user4->id);
1f64514d
MN
2057
2058 // Retrieve the contacts.
2059 $contacts = \core_message\api::get_contacts($user1->id);
2060
2061 // Confirm the data is correct.
2062 $this->assertEquals(3, count($contacts));
f219eac7 2063 usort($contacts, ['static', 'sort_contacts']);
1f64514d
MN
2064
2065 $contact1 = $contacts[0];
2066 $contact2 = $contacts[1];
2067 $contact3 = $contacts[2];
2068
2069 $this->assertEquals($user2->id, $contact1->userid);
2070 $this->assertEmpty($contact1->useridfrom);
2071 $this->assertFalse($contact1->ismessaging);
2072 $this->assertNull($contact1->lastmessage);
2073 $this->assertNull($contact1->messageid);
cb805753 2074 $this->assertNull($contact1->isonline);
1f64514d
MN
2075 $this->assertFalse($contact1->isread);
2076 $this->assertFalse($contact1->isblocked);
2077 $this->assertNull($contact1->unreadcount);
2078
2079 $this->assertEquals($user3->id, $contact2->userid);
2080 $this->assertEmpty($contact2->useridfrom);
2081 $this->assertFalse($contact2->ismessaging);
2082 $this->assertNull($contact2->lastmessage);
2083 $this->assertNull($contact2->messageid);
cb805753 2084 $this->assertNull($contact2->isonline);
1f64514d
MN
2085 $this->assertFalse($contact2->isread);
2086 $this->assertFalse($contact2->isblocked);
2087 $this->assertNull($contact2->unreadcount);
2088
2089 $this->assertEquals($user4->id, $contact3->userid);
2090 $this->assertEmpty($contact3->useridfrom);
2091 $this->assertFalse($contact3->ismessaging);
2092 $this->assertNull($contact3->lastmessage);
2093 $this->assertNull($contact3->messageid);
cb805753 2094 $this->assertNull($contact3->isonline);
1f64514d
MN
2095 $this->assertFalse($contact3->isread);
2096 $this->assertFalse($contact3->isblocked);
2097 $this->assertNull($contact3->unreadcount);
2098 }
2099
2100 /**
2101 * Tests retrieving messages.
2102 */
2103 public function test_get_messages() {
2104 // Create some users.
2105 $user1 = self::getDataGenerator()->create_user();
2106 $user2 = self::getDataGenerator()->create_user();
2107
2108 // The person doing the search.
2109 $this->setUser($user1);
2110
2111 // Send some messages back and forth.
2112 $time = 1;
2113 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2114 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2115 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2116 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2117
2118 // Retrieve the messages.
2119 $messages = \core_message\api::get_messages($user1->id, $user2->id);
2120
2121 // Confirm the message data is correct.
2122 $this->assertEquals(4, count($messages));
2123
2124 $message1 = $messages[0];
2125 $message2 = $messages[1];
2126 $message3 = $messages[2];
2127 $message4 = $messages[3];
2128
2129 $this->assertEquals($user1->id, $message1->useridfrom);
2130 $this->assertEquals($user2->id, $message1->useridto);
2131 $this->assertTrue($message1->displayblocktime);
2132 $this->assertContains('Yo!', $message1->text);
2133
2134 $this->assertEquals($user2->id, $message2->useridfrom);
2135 $this->assertEquals($user1->id, $message2->useridto);
2136 $this->assertFalse($message2->displayblocktime);
2137 $this->assertContains('Sup mang?', $message2->text);
2138
2139 $this->assertEquals($user1->id, $message3->useridfrom);
2140 $this->assertEquals($user2->id, $message3->useridto);
2141 $this->assertFalse($message3->displayblocktime);
2142 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2143
2144 $this->assertEquals($user2->id, $message4->useridfrom);
2145 $this->assertEquals($user1->id, $message4->useridto);
2146 $this->assertFalse($message4->displayblocktime);
2147 $this->assertContains('Word.', $message4->text);
2148 }
2149
fb04293b
SA
2150 /**
2151 * Tests retrieving conversation messages.
2152 */
2153 public function test_get_conversation_messages() {
2154 // Create some users.
2155 $user1 = self::getDataGenerator()->create_user();
2156 $user2 = self::getDataGenerator()->create_user();
2157
2158 // Create conversation.
2159 $conversation = \core_message\api::create_conversation(
2160 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2161 [$user1->id, $user2->id]
2162 );
2163
2164 // The person doing the search.
2165 $this->setUser($user1);
2166
2167 // Send some messages back and forth.
2168 $time = 1;
2169 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2170 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2171 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2172 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2173
2174 // Retrieve the messages.
2175 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2176
2177 // Confirm the conversation id is correct.
2178 $this->assertEquals($conversation->id, $convmessages['id']);
2179
2180 // Confirm the message data is correct.
2181 $messages = $convmessages['messages'];
2182 $this->assertEquals(4, count($messages));
2183 $message1 = $messages[0];
2184 $message2 = $messages[1];
2185 $message3 = $messages[2];
2186 $message4 = $messages[3];
2187
2188 $this->assertEquals($user1->id, $message1->useridfrom);
2189 $this->assertContains('Yo!', $message1->text);
2190
2191 $this->assertEquals($user2->id, $message2->useridfrom);
2192 $this->assertContains('Sup mang?', $message2->text);
2193
2194 $this->assertEquals($user1->id, $message3->useridfrom);
2195 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2196
2197 $this->assertEquals($user1->id, $message4->useridfrom);
2198 $this->assertContains('Word.', $message4->text);
2199
2200 // Confirm the members data is correct.
2201 $members = $convmessages['members'];
2202 $this->assertEquals(2, count($members));
2203 }
2204
2205 /**
2206 * Tests retrieving group conversation messages.
2207 */
2208 public function test_get_group_conversation_messages() {
2209 // Create some users.
2210 $user1 = self::getDataGenerator()->create_user();
2211 $user2 = self::getDataGenerator()->create_user();
2212 $user3 = self::getDataGenerator()->create_user();
2213 $user4 = self::getDataGenerator()->create_user();
2214
2215 // Create group conversation.
2216 $conversation = \core_message\api::create_conversation(
2217 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2218 [$user1->id, $user2->id, $user3->id, $user4->id]
2219 );
2220
2221 // The person doing the search.
2222 $this->setUser($user1);
2223
2224 // Send some messages back and forth.
2225 $time = 1;
2226 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2227 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2228 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2229 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2230 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
2231
2232 // Retrieve the messages.
2233 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2234
2235 // Confirm the conversation id is correct.
2236 $this->assertEquals($conversation->id, $convmessages['id']);
2237
2238 // Confirm the message data is correct.
2239 $messages = $convmessages['messages'];
2240 $this->assertEquals(5, count($messages));
2241
2242 $message1 = $messages[0];
2243 $message2 = $messages[1];
2244 $message3 = $messages[2];
2245 $message4 = $messages[3];
2246 $message5 = $messages[4];
2247
2248 $this->assertEquals($user1->id, $message1->useridfrom);
2249 $this->assertContains('Yo!', $message1->text);
2250
2251 $this->assertEquals($user2->id, $message2->useridfrom);
2252 $this->assertContains('Sup mang?', $message2->text);
2253
2254 $this->assertEquals($user3->id, $message3->useridfrom);
2255 $this->assertContains('Writing PHPUnit tests!', $message3->text);
2256
2257 $this->assertEquals($user1->id, $message4->useridfrom);
2258 $this->assertContains('Word.', $message4->text);
2259
2260 $this->assertEquals($user2->id, $message5->useridfrom);
2261 $this->assertContains('Yeah!', $message5->text);
2262
2263 // Confirm the members data is correct.
2264 $members = $convmessages['members'];
2265 $this->assertEquals(3, count($members));
2266 }
2267
b95e4c78
JD
2268 /**
2269 * Test verifying the sorting param for get_conversation_messages is respected().
2270 */
2271 public function test_get_conversation_messages_sorting() {
2272 // Create some users.
2273 $user1 = self::getDataGenerator()->create_user();
2274 $user2 = self::getDataGenerator()->create_user();
2275 $user3 = self::getDataGenerator()->create_user();
2276
2277 // Create conversations - 1 group and 1 individual.
2278 $conversation = \core_message\api::create_conversation(
2279 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2280 [$user1->id, $user2->id]
2281 );
2282 $conversation2 = \core_message\api::create_conversation(
2283 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2284 [$user1->id, $user2->id, $user3->id]
2285 );
2286
2287 // Send some messages back and forth.
2288 $time = 1;
2289 $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2290 $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2291 $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2292 $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2293
2294 $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
2295 $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
2296 $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
2297 $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
2298
2299 // The person doing the search.
2300 $this->setUser($user1);
2301
2302 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2303 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id);
2304 $messages = $convmessages['messages'];
2305 $this->assertEquals($m1id, $messages[0]->id);
2306 $this->assertEquals($m2id, $messages[1]->id);
2307 $this->assertEquals($m3id, $messages[2]->id);
2308 $this->assertEquals($m4id, $messages[3]->id);
2309
2310 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2311 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
2312 $messages = $convmessages['messages'];
2313 $this->assertEquals($m1id, $messages[3]->id);
2314 $this->assertEquals($m2id, $messages[2]->id);
2315 $this->assertEquals($m3id, $messages[1]->id);
2316 $this->assertEquals($m4id, $messages[0]->id);
2317
2318 // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2319 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id);
2320 $messages = $convmessages['messages'];
2321 $this->assertEquals($gm1id, $messages[0]->id);
2322 $this->assertEquals($gm2id, $messages[1]->id);
2323 $this->assertEquals($gm3id, $messages[2]->id);
2324 $this->assertEquals($gm4id, $messages[3]->id);
2325
2326 // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2327 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
2328 $messages = $convmessages['messages'];
2329 $this->assertEquals($gm1id, $messages[3]->id);
2330 $this->assertEquals($gm2id, $messages[2]->id);
2331 $this->assertEquals($gm3id, $messages[1]->id);
2332 $this->assertEquals($gm4id, $messages[0]->id);
2333 }
2334
fb04293b
SA
2335 /**
2336 * Test retrieving conversation messages by providing a minimum timecreated value.
2337 */
2338 public function test_get_conversation_messages_time_from_only() {
2339 // Create some users.
2340 $user1 = self::getDataGenerator()->create_user();
2341 $user2 = self::getDataGenerator()->create_user();
2342 $user3 = self::getDataGenerator()->create_user();
2343 $user4 = self::getDataGenerator()->create_user();
2344
2345 // Create group conversation.
2346 $conversation = \core_message\api::create_conversation(
2347 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2348 [$user1->id, $user2->id, $user3->id, $user4->id]
2349 );
2350
2351 // The person doing the search.
2352 $this->setUser($user1);
2353
2354 // Send some messages back and forth.
2355 $time = 1;
2356 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2357 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2358 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2359 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2360
2361 // Retrieve the messages from $time, which should be all of them.
2362 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
2363
2364 // Confirm the conversation id is correct.
2365 $this->assertEquals($conversation->id, $convmessages['id']);
2366
2367 // Confirm the message data is correct.
2368 $messages = $convmessages['messages'];
2369 $this->assertEquals(4, count($messages));
2370
2371 $message1 = $messages[0];
2372 $message2 = $messages[1];
2373 $message3 = $messages[2];
2374 $message4 = $messages[3];
2375
2376 $this->assertContains('Message 1', $message1->text);
2377 $this->assertContains('Message 2', $message2->text);
2378 $this->assertContains('Message 3', $message3->text);
2379 $this->assertContains('Message 4', $message4->text);
2380
2381 // Confirm the members data is correct.
2382 $members = $convmessages['members'];
2383 $this->assertEquals(3, count($members));
2384
2385 // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2386 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2387 'timecreated ASC', $time + 3);
2388
2389 // Confirm the conversation id is correct.
2390 $this->assertEquals($conversation->id, $convmessages['id']);
2391
2392 // Confirm the message data is correct.
2393 $messages = $convmessages['messages'];
2394 $this->assertEquals(2, count($messages));
2395
2396 $message1 = $messages[0];
2397 $message2 = $messages[1];
2398
2399 $this->assertContains('Message 3', $message1->text);
2400 $this->assertContains('Message 4', $message2->text);
2401
2402 // Confirm the members data is correct.
2403 $members = $convmessages['members'];
2404 $this->assertEquals(2, count($members));
2405 }
2406
2407 /**
2408 * Test retrieving conversation messages by providing a maximum timecreated value.
2409 */
2410 public function test_get_conversation_messages_time_to_only() {
2411 // Create some users.
2412 $user1 = self::getDataGenerator()->create_user();
2413 $user2 = self::getDataGenerator()->create_user();
2414 $user3 = self::getDataGenerator()->create_user();
2415 $user4 = self::getDataGenerator()->create_user();
2416
2417 // Create group conversation.
2418 $conversation = \core_message\api::create_conversation(
2419 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2420 [$user1->id, $user2->id, $user3->id, $user4->id]
2421 );
2422
2423 // The person doing the search.
2424 $this->setUser($user1);
2425
2426 // Send some messages back and forth.
2427 $time = 1;
2428 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2429 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2430 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2431 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2432
2433 // Retrieve the messages up until $time + 4, which should be all of them.
2434 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2435 0, $time + 4);
2436
2437 // Confirm the conversation id is correct.
2438 $this->assertEquals($conversation->id, $convmessages['id']);
2439
2440 // Confirm the message data is correct.
2441 $messages = $convmessages['messages'];
2442 $this->assertEquals(4, count($messages));
2443
2444 $message1 = $messages[0];
2445 $message2 = $messages[1];
2446 $message3 = $messages[2];
2447 $message4 = $messages[3];
2448
2449 $this->assertContains('Message 1', $message1->text);
2450 $this->assertContains('Message 2', $message2->text);
2451 $this->assertContains('Message 3', $message3->text);
2452 $this->assertContains('Message 4', $message4->text);
2453
2454 // Confirm the members data is correct.
2455 $members = $convmessages['members'];
2456 $this->assertEquals(3, count($members));
2457
2458 // Retrieve the messages up until $time + 2, which should be the first two.
2459 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2460 0, $time + 2);
2461
2462 // Confirm the conversation id is correct.
2463 $this->assertEquals($conversation->id, $convmessages['id']);
2464
2465 // Confirm the message data is correct.
2466 $messages = $convmessages['messages'];
2467 $this->assertEquals(2, count($messages));
2468
2469 $message1 = $messages[0];
2470 $message2 = $messages[1];
2471
2472 $this->assertContains('Message 1', $message1->text);
2473 $this->assertContains('Message 2', $message2->text);
2474
2475 // Confirm the members data is correct.
2476 $members = $convmessages['members'];
2477 $this->assertEquals(2, count($members));
2478 }
2479
2480 /**
2481 * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
2482 */
2483 public function test_get_conversation_messages_time_from_and_to() {
2484 // Create some users.
2485 $user1 = self::getDataGenerator()->create_user();
2486 $user2 = self::getDataGenerator()->create_user();
2487 $user3 = self::getDataGenerator()->create_user();
2488 $user4 = self::getDataGenerator()->create_user();
2489
2490 // Create group conversation.
2491 $conversation = \core_message\api::create_conversation(
2492 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2493 [$user1->id, $user2->id, $user3->id, $user4->id]
2494 );
2495
2496 // The person doing the search.
2497 $this->setUser($user1);
2498
2499 // Send some messages back and forth.
2500 $time = 1;
2501 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2502 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2503 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2504 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2505
2506 // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2507 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2508 'timecreated ASC', $time + 2, $time + 3);
2509
2510 // Confirm the conversation id is correct.
2511 $this->assertEquals($conversation->id, $convmessages['id']);
2512
2513 // Confirm the message data is correct.
2514 $messages = $convmessages['messages'];
2515 $this->assertEquals(2, count($messages));
2516
2517 $message1 = $messages[0];
2518 $message2 = $messages[1];
2519
2520 $this->assertContains('Message 2', $message1->text);
2521 $this->assertContains('Message 3', $message2->text);
2522
2523 // Confirm the members data is correct.
2524 $members = $convmessages['members'];
2525 $this->assertEquals(2, count($members));
2526 }
2527
2528
2529 /**
2530 * Test retrieving conversation messages by providing a limitfrom value.
2531 */
2532 public function test_get_conversation_messages_limitfrom_only() {
2533 // Create some users.
2534 $user1 = self::getDataGenerator()->create_user();
2535 $user2 = self::getDataGenerator()->create_user();
2536 $user3 = self::getDataGenerator()->create_user();
2537 $user4 = self::getDataGenerator()->create_user();
2538
2539 // Create group conversation.
2540 $conversation = \core_message\api::create_conversation(
2541 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2542 [$user1->id, $user2->id, $user3->id, $user4->id]
2543 );
2544
2545 // The person doing the search.
2546 $this->setUser($user1);
2547
2548 // Send some messages back and forth.
2549 $time = 1;
2550 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2551 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2552 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2553 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2554
2555 // Retrieve the messages from $time, which should be all of them.
2556 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2);
2557
2558 // Confirm the conversation id is correct.
2559 $messages = $convmessages['messages'];
2560 $this->assertEquals($conversation->id, $convmessages['id']);
2561
2562 // Confirm the message data is correct.
2563 $this->assertEquals(2, count($messages));
2564
2565 $message1 = $messages[0];
2566 $message2 = $messages[1];
2567
2568 $this->assertContains('Message 3', $message1->text);
2569 $this->assertContains('Message 4', $message2->text);
2570
2571 // Confirm the members data is correct.
2572 $members = $convmessages['members'];
2573 $this->assertEquals(2, count($members));
2574 }
2575
2576 /**
2577 * Test retrieving conversation messages by providing a limitnum value.
2578 */
2579 public function test_get_conversation_messages_limitnum() {
2580 // Create some users.
2581 $user1 = self::getDataGenerator()->create_user();
2582 $user2 = self::getDataGenerator()->create_user();
2583 $user3 = self::getDataGenerator()->create_user();
2584 $user4 = self::getDataGenerator()->create_user();
2585
2586 // Create group conversation.
2587 $conversation = \core_message\api::create_conversation(
2588 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2589 [$user1->id, $user2->id, $user3->id, $user4->id]
2590 );
2591
2592 // The person doing the search.
2593 $this->setUser($user1);
2594
2595 // Send some messages back and forth.
2596 $time = 1;
2597 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2598 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2599 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2600 testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2601
2602 // Retrieve the messages from $time, which should be all of them.
2603 $convmessages = \core_message\api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
2604
2605 // Confirm the conversation id is correct.
2606 $messages = $convmessages['messages'];
2607 $this->assertEquals($conversation->id, $convmessages['id']);
2608
2609 // Confirm the message data is correct.
2610 $messages = $convmessages['messages'];
2611 $this->assertEquals(1, count($messages));
2612
2613 $message1 = $messages[0];
2614
2615 $this->assertContains('Message 3', $message1->text);
2616
2617 // Confirm the members data is correct.
2618 $members = $convmessages['members'];
2619 $this->assertEquals(1, count($members));
2620 }
2621
1f64514d
MN
2622 /**
2623 * Tests retrieving most recent message.
2624 */
2625 public function test_get_most_recent_message() {
2626 // Create some users.
2627 $user1 = self::getDataGenerator()->create_user();
2628 $user2 = self::getDataGenerator()->create_user();
2629
2630 // The person doing the search.
2631 $this->setUser($user1);
2632
2633 // Send some messages back and forth.
2634 $time = 1;
2635 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2636 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2637 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2638 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2639
2640 // Retrieve the most recent messages.
2641 $message = \core_message\api::get_most_recent_message($user1->id, $user2->id);
2642
2643 // Check the results are correct.
2644 $this->assertEquals($user2->id, $message->useridfrom);
2645 $this->assertEquals($user1->id, $message->useridto);
2646 $this->assertContains('Word.', $message->text);
2647 }
2648
fb04293b
SA
2649 /**
2650 * Tests retrieving most recent conversation message.
2651 */
2652 public function test_get_most_recent_conversation_message() {
2653 // Create some users.
2654 $user1 = self::getDataGenerator()->create_user();
2655 $user2 = self::getDataGenerator()->create_user();
2656 $user3 = self::getDataGenerator()->create_user();
2657
2658 // Create group conversation.
2659 $conversation = \core_message\api::create_conversation(
2660 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
2661 [$user1->id, $user2->id, $user3->id]
2662 );
2663
2664 // The person getting the most recent conversation message.
2665 $this->setUser($user1);
2666
2667 // Send some messages back and forth.
2668 $time = 1;
2669 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2670 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2671 testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2672 testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2673
2674 // Retrieve the most recent messages.
2675 $message = \core_message\api::get_most_recent_conversation_message($conversation->id, $user1->id);
2676
2677 // Check the results are correct.
2678 $this->assertEquals($user2->id, $message->useridfrom);
2679 $this->assertContains('Word.', $message->text);
2680 }
2681
1f64514d
MN
2682 /**
2683 * Tests retrieving a user's profile.
2684 */
2685 public function test_get_profile() {
2686 // Create some users.
2687 $user1 = self::getDataGenerator()->create_user();
2688
2689 $user2 = new stdClass();
2690 $user2->country = 'AU';
2691 $user2->city = 'Perth';
2692 $user2 = self::getDataGenerator()->create_user($user2);
2693
2694 // The person doing the search.
2695 $this->setUser($user1);
2696
2697 // Get the profile.
2698 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2699
2700 $this->assertEquals($user2->id, $profile->userid);
2701 $this->assertEmpty($profile->email);
2702 $this->assertEmpty($profile->country);
2703 $this->assertEmpty($profile->city);
2704 $this->assertEquals(fullname($user2), $profile->fullname);
cb805753 2705 $this->assertNull($profile->isonline);
1f64514d
MN
2706 $this->assertFalse($profile->isblocked);
2707 $this->assertFalse($profile->iscontact);
2708 }
2709
2710 /**
2711 * Tests retrieving a user's profile.
2712 */
2713 public function test_get_profile_as_admin() {
2714 // The person doing the search.
2715 $this->setAdminUser();
2716
2717 // Create some users.
2718 $user1 = self::getDataGenerator()->create_user();
2719
2720 $user2 = new stdClass();
2721 $user2->country = 'AU';
2722 $user2->city = 'Perth';
2723 $user2 = self::getDataGenerator()->create_user($user2);
2724
2725 // Get the profile.
2726 $profile = \core_message\api::get_profile($user1->id, $user2->id);
2727
2728 $this->assertEquals($user2->id, $profile->userid);
2729 $this->assertEquals($user2->email, $profile->email);
2730 $this->assertEquals($user2->country, $profile->country);
2731 $this->assertEquals($user2->city, $profile->city);
2732 $this->assertEquals(fullname($user2), $profile->fullname);
2733 $this->assertFalse($profile->isonline);
2734 $this->assertFalse($profile->isblocked);
2735 $this->assertFalse($profile->iscontact);
2736 }
2737
abf7a261
MN
2738 /**
2739 * Tests checking if a user can mark all messages as read.
2740 */
2741 public function test_can_mark_all_messages_as_read() {
2742 // Set as the admin.
2743 $this->setAdminUser();
2744
2745 // Create some users.
2746 $user1 = self::getDataGenerator()->create_user();
2747 $user2 = self::getDataGenerator()->create_user();
2748 $user3 = self::getDataGenerator()->create_user();
2749
2750 // Send some messages back and forth.
2751 $time = 1;
2752 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2753 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2754 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2755 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2756
2757 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2758
2759 // The admin can do anything.
2760 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2761
2762 // Set as the user 1.
2763 $this->setUser($user1);
2764
2765 // The user can mark the messages as he is in the conversation.
2766 $this->assertTrue(\core_message\api::can_mark_all_messages_as_read($user1->id, $conversationid));
2767
2768 // User 1 can not mark the messages read for user 2.
2769 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user2->id, $conversationid));
2770
2771 // This user is not a part of the conversation.
2772 $this->assertFalse(\core_message\api::can_mark_all_messages_as_read($user3->id, $conversationid));
2773 }
2774
1f64514d
MN
2775 /**
2776 * Tests checking if a user can delete a conversation.
2777 */
2778 public function test_can_delete_conversation() {
2779 // Set as the admin.
2780 $this->setAdminUser();
2781
2782 // Create some users.
2783 $user1 = self::getDataGenerator()->create_user();
2784 $user2 = self::getDataGenerator()->create_user();
2785
15663b0b
MN
2786 // Send some messages back and forth.
2787 $time = 1;
2788 $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2789 $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2790 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2791 $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2792
2793 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2794
1f64514d 2795 // The admin can do anything.
15663b0b 2796 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1f64514d
MN
2797
2798 // Set as the user 1.
2799 $this->setUser($user1);
2800
2801 // They can delete their own messages.
15663b0b 2802 $this->assertTrue(\core_message\api::can_delete_conversation($user1->id, $conversationid));
1f64514d
MN
2803
2804 // They can't delete someone elses.
15663b0b 2805 $this->assertFalse(\core_message\api::can_delete_conversation($user2->id, $conversationid));
1f64514d
MN
2806 }
2807
2808 /**
2809 * Tests deleting a conversation.
2810 */
2811 public function test_delete_conversation() {
2812 global $DB;
2813
2814 // Create some users.
2815 $user1 = self::getDataGenerator()->create_user();
2816 $user2 = self::getDataGenerator()->create_user();
2817
2818 // The person doing the search.
2819 $this->setUser($user1);
2820
2821 // Send some messages back and forth.
2822 $time = 1;
883ce421
MN
2823 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2824 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2825 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2826 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1f64514d
MN
2827
2828 // Delete the conversation as user 1.
2829 \core_message\api::delete_conversation($user1->id, $user2->id);
263ad984
MN
2830 $this->assertDebuggingCalled();
2831
2832 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2833 $this->assertCount(4, $muas);
2834 // Sort by id.
2835 ksort($muas);
2836
2837 $mua1 = array_shift($muas);
2838 $mua2 = array_shift($muas);
2839 $mua3 = array_shift($muas);
2840 $mua4 = array_shift($muas);
2841
2842 $this->assertEquals($user1->id, $mua1->userid);
2843 $this->assertEquals($m1id, $mua1->messageid);
2844 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
2845
2846 $this->assertEquals($user1->id, $mua2->userid);
2847 $this->assertEquals($m2id, $mua2->messageid);
2848 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
2849
2850 $this->assertEquals($user1->id, $mua3->userid);
2851 $this->assertEquals($m3id, $mua3->messageid);
2852 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
2853
2854 $this->assertEquals($user1->id, $mua4->userid);
2855 $this->assertEquals($m4id, $mua4->messageid);
2856 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
2857 }
2858
2859 /**
2860 * Tests deleting a conversation by conversation id.
2861 */
2862 public function test_delete_conversation_by_id() {
2863 global $DB;
2864
2865 // Create some users.
2866 $user1 = self::getDataGenerator()->create_user();
2867 $user2 = self::getDataGenerator()->create_user();
2868
2869 // The person doing the search.
2870 $this->setUser($user1);
2871
2872 // Send some messages back and forth.
2873 $time = 1;
2874 $m1id = $this->send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2875 $m2id = $this->send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2876 $m3id = $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2877 $m4id = $this->send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
2878
2879 // Delete the conversation as user 1.
2880 $conversationid = \core_message\api::get_conversation_between_users([$user1->id, $user2->id]);
2881 \core_message\api::delete_conversation_by_id($user1->id, $conversationid);
1f64514d 2882
883ce421
MN
2883 $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2884 $this->assertCount(4, $muas);
2885 // Sort by id.
2886 ksort($muas);
1f64514d 2887
883ce421
MN
2888 $mua1 = array_shift($muas);
2889 $mua2 = array_shift($muas);
2890 $mua3 = array_shift($muas);
2891 $mua4 = array_shift($muas);
1f64514d 2892
883ce421
MN
2893 $this->assertEquals($user1->id, $mua1->userid);
2894 $this->assertEquals($m1id, $mua1->messageid);
2895 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua1->action);
1f64514d 2896
883ce421
MN
2897 $this->assertEquals($user1->id, $mua2->userid);
2898 $this->assertEquals($m2id, $mua2->messageid);
2899 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua2->action);
1f64514d 2900
883ce421
MN
2901 $this->assertEquals($user1->id, $mua3->userid);
2902 $this->assertEquals($m3id, $mua3->messageid);
2903 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua3->action);
1f64514d 2904
883ce421
MN
2905 $this->assertEquals($user1->id, $mua4->userid);
2906 $this->assertEquals($m4id, $mua4->messageid);
2907 $this->assertEquals(\core_message\api::MESSAGE_ACTION_DELETED, $mua4->action);
1f64514d
MN
2908 }
2909
2910 /**
2911 * Tests counting unread conversations.
2912 */
2913 public function test_count_unread_conversations() {
2914 $this->resetAfterTest(true);
2915
2916 // Create some users.
2917 $user1 = self::getDataGenerator()->create_user();
2918 $user2 = self::getDataGenerator()->create_user();
2919 $user3 = self::getDataGenerator()->create_user();
2920 $user4 = self::getDataGenerator()->create_user();
2921
2922 // The person wanting the conversation count.
2923 $this->setUser($user1);
2924
2925 // Send some messages back and forth, have some different conversations with different users.
2926 $this->send_fake_message($user1, $user2, 'Yo!');
2927 $this->send_fake_message($user2, $user1, 'Sup mang?');
2928 $this->send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2929 $this->send_fake_message($user2, $user1, 'Word.');
2930
2931 $this->send_fake_message($user1, $user3, 'Booyah');
2932 $this->send_fake_message($user3, $user1, 'Whaaat?');
2933 $this->send_fake_message($user1, $user3, 'Nothing.');
2934 $this->send_fake_message($user3, $user1, 'Cool.');
2935
2936 $this->send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2937 $this->send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2938 $this->send_fake_message($user1, $user4, 'Dope.');
2939
2940 // Check the amount for the current user.
2941 $this->assertEquals(3, core_message\api::count_unread_conversations());
2942
2943 // Check the amount for the second user.
2944 $this->assertEquals(1, core_message\api::count_unread_conversations($user2));
2945 }
2946
2947 /**
2948 * Tests deleting a conversation.
2949 */
2950 public function test_get_all_message_preferences() {
2951 $user = self::getDataGenerator()->create_user();
2952 $this->setUser($user);
2953
2954 // Set a couple of preferences to test.
2955 set_user_preference('message_provider_mod_assign_assign_notification_loggedin', 'popup', $user);
2956 set_user_preference('message_provider_mod_assign_assign_notification_loggedoff', 'email', $user);
2957
2958 $processors = get_message_processors();
2959 $providers = message_get_providers_for_user($user->id);
2960 $prefs = \core_message\api::get_all_message_preferences($processors, $providers, $user);
2961
2962 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedin['popup']);
2963 $this->assertEquals(1, $prefs->mod_assign_assign_notification_loggedoff['email']);
2964 }
2965
2966 /**
2967 * Tests the user can post a message.
2968 */
2969 public function test_can_post_message() {
2970 // Create some users.
2971 $user1 = self::getDataGenerator()->create_user();
2972 $user2 = self::getDataGenerator()->create_user();
2973
f7dfa9ba 2974 // Set as the first user.
1f64514d
MN
2975 $this->setUser($user1);
2976
f7dfa9ba
SA
2977 // With the default privacy setting, users can't message them.
2978 $this->assertFalse(\core_message\api::can_post_message($user2));
2979
2980 // Enrol users to the same course.
2981 $course = $this->getDataGenerator()->create_course();
2982 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
2983 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
2984 // After enrolling users to the course, they should be able to message them with the default privacy setting.
1f64514d
MN
2985 $this->assertTrue(\core_message\api::can_post_message($user2));
2986 }
2987
2988 /**
2989 * Tests the user can't post a message without proper capability.
2990 */
7983fb83 2991 public function test_can_post_message_without_sendmessage_cap() {
1f64514d
MN
2992 global $DB;
2993
2994 // Create some users.
2995 $user1 = self::getDataGenerator()->create_user();
2996 $user2 = self::getDataGenerator()->create_user();
2997
2998 // Set as the user 1.
2999 $this->setUser($user1);
3000
3001 // Remove the capability to send a message.
3002 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3003 unassign_capability('moodle/site:sendmessage', $roleids['user'],
3004 context_system::instance());
3005
3006 // Check that we can not post a message without the capability.
3007 $this->assertFalse(\core_message\api::can_post_message($user2));
3008 }
3009
f7dfa9ba
SA
3010 /**
3011 * Tests the user can post a message when they are contact.
3012 */
3013 public function test_can_post_message_when_contact() {
3014 // Create some users.
3015 $user1 = self::getDataGenerator()->create_user();
3016 $user2 = self::getDataGenerator()->create_user();
3017
3018 // Set as the first user.
3019 $this->setUser($user1);
3020
3021 // Check that we can not send user2 a message.
3022 $this->assertFalse(\core_message\api::can_post_message($user2));
3023
3024 // Add users as contacts.
3025 \core_message\api::add_contact($user1->id, $user2->id);
3026
3027 // Check that the return result is now true.
3028 $this->assertTrue(\core_message\api::can_post_message($user2));
3029 }
3030
1f64514d
MN
3031 /**
3032 * Tests the user can't post a message if they are not a contact and the user
3033 * has requested messages only from contacts.
3034 */
3035 public function test_can_post_message_when_not_contact() {
3036 // Create some users.
3037 $user1 = self::getDataGenerator()->create_user();
3038 $user2 = self::getDataGenerator()->create_user();
3039
3040 // Set as the first user.
3041 $this->setUser($user1);
3042
3043 // Set the second user's preference to not receive messages from non-contacts.
f7dfa9ba 3044 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
1f64514d
MN
3045
3046 // Check that we can not send user 2 a message.
3047 $this->assertFalse(\core_message\api::can_post_message($user2));
3048 }
3049
3050 /**
3051 * Tests the user can't post a message if they are blocked.
3052 */
3053 public function test_can_post_message_when_blocked() {
3054 // Create some users.
3055 $user1 = self::getDataGenerator()->create_user();
3056 $user2 = self::getDataGenerator()->create_user();
3057
3058 // Set the user.
3059 $this->setUser($user1);
3060
3061 // Block the second user.
f219eac7 3062 \core_message\api::block_user($user1->id, $user2->id);
1f64514d
MN
3063
3064 // Check that the second user can no longer send the first user a message.
3065 $this->assertFalse(\core_message\api::can_post_message($user1, $user2));
3066 }
3067
f7dfa9ba
SA
3068 /**
3069 * Tests the user can post a message when site-wide messaging setting is enabled,
3070 * even if they are not a contact and are not members of the same course.
3071 */
3072 public function test_can_post_message_site_messaging_setting() {
3073 // Create some users.
3074 $user1 = self::getDataGenerator()->create_user();
3075 $user2 = self::getDataGenerator()->create_user();
3076
3077 // Set as the first user.
3078 $this->setUser($user1);
3079
7983fb83 3080 // By default, user only can be messaged by contacts and members of any of his/her courses.
f7dfa9ba
SA
3081 $this->assertFalse(\core_message\api::can_post_message($user2));
3082
3083 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3084 set_config('messagingallusers', true);
7983fb83
SA
3085
3086 // Set the second user's preference to receive messages from everybody.
3087 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
3088
f7dfa9ba
SA
3089 // Check that we can send user2 a message.
3090 $this->assertTrue(\core_message\api::can_post_message($user2));
7983fb83
SA
3091
3092 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3093 // and members sharing a course with her.
3094 set_config('messagingallusers', false);
3095
3096 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3097 $this->assertFalse(\core_message\api::can_post_message($user2));
3098
3099 // Enrol users to the same course.
3100 $course = $this->getDataGenerator()->create_course();
3101 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3102 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3103 // Check that we can send user2 a message because they are sharing a course.
3104 $this->assertTrue(\core_message\api::can_post_message($user2));
3105
3106 // Set the second user's preference to receive messages only from contacts.
3107 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3108 // Check that now the user2 can't be contacted because user1 is not their contact.
3109 $this->assertFalse(\core_message\api::can_post_message($user2));
3110
3111 // Make contacts user1 and user2.
3112 \core_message\api::add_contact($user2->id, $user1->id);
3113 // Check that we can send user2 a message because they are contacts.
3114 $this->assertTrue(\core_message\api::can_post_message($user2));
3115 }
3116
3117 /**
3118 * Tests the user with the messageanyuser capability can post a message.
3119 */
3120 public function test_can_post_message_with_messageanyuser_cap() {
3121 global $DB;
3122
3123 // Create some users.
3124 $teacher1 = self::getDataGenerator()->create_user();
3125 $student1 = self::getDataGenerator()->create_user();
3126 $student2 = self::getDataGenerator()->create_user();
3127
3128 // Create users not enrolled in any course.
3129 $user1 = self::getDataGenerator()->create_user();
3130
3131 // Create a course.
3132 $course1 = $this->getDataGenerator()->create_course();
3133
3134 // Enrol the users in the course.
3135 $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
3136 $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
3137 $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
3138
3139 // Set some student preferences to not receive messages from non-contacts.
3140 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
3141
3142 // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
3143 $this->assertTrue(\core_message\api::can_post_message($student1, $teacher1));
3144 // Check that the teacher can't contact user1 because it's not his teacher.
3145 $this->assertFalse(\core_message\api::can_post_message($user1, $teacher1));
3146
3147 // Remove the messageanyuser capability from the course1 for teachers.
3148 $coursecontext = context_course::instance($course1->id);
3149 $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
3150 assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
3151 $coursecontext->mark_dirty();
3152
3153 // Check that we can't send user1 a message because they are not contacts.
3154 $this->assertFalse(\core_message\api::can_post_message($student1, $teacher1));
3155 // However, teacher can message student2 because they are sharing a course.
3156 $this->assertTrue(\core_message\api::can_post_message($student2, $teacher1));
f7dfa9ba
SA
3157 }
3158
8e3bf150
JD
3159 /**
3160 * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings.
3161 */
3162 public function test_can_send_message_to_conversation_basic() {
3163 // Create some users.
3164 $user1 = self::getDataGenerator()->create_user();
3165 $user2 = self::getDataGenerator()->create_user();
3166 $user3 = self::getDataGenerator()->create_user();
3167
3168 // Create an individual conversation between user1 and user2.
3169 $ic1 = \core_message\api::create_conversation(
3170 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3171 [
3172 $user1->id,
3173 $user2->id
3174 ]
3175 );
3176
3177 // Create a group conversation between and users 1, 2 and 3.
3178 $gc1 = \core_message\api::create_conversation(
3179 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3180 [
3181 $user1->id,
3182 $user2->id,
3183 $user3->id
3184 ]
3185 );
3186
3187 // For group conversations, there are no user privacy checks, so only membership in the conversation is needed.
3188 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3189
3190 // For individual conversations, the default privacy setting of 'only contacts and course members' applies.
3191 // Users are not in the same course, nor are they contacts, so messages cannot be sent.
3192 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3193
3194 // Enrol the users into the same course.
3195 $course = $this->getDataGenerator()->create_course();
3196 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3197 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3198
3199 // After enrolling users to the course, they should be able to message them with the default privacy setting.
3200 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3201 }
3202
3203 /**
3204 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability.
3205 */
3206 public function test_can_send_message_to_conversation_sendmessage_cap() {
3207 global $DB;
3208
3209 $user1 = self::getDataGenerator()->create_user();
3210 $user2 = self::getDataGenerator()->create_user();
3211 $user3 = self::getDataGenerator()->create_user();
3212
3213 // Enrol the users into the same course.
3214 $course = $this->getDataGenerator()->create_course();
3215 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3216 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3217 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3218
3219 // Create an individual conversation between user1 and user2.
3220 $ic1 = \core_message\api::create_conversation(
3221 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3222 [
3223 $user1->id,
3224 $user2->id
3225 ]
3226 );
3227
3228 // Group conversation between and users 1, 2 and 3.
3229 $gc1 = \core_message\api::create_conversation(
3230 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3231 [
3232 $user1->id,
3233 $user2->id,
3234 $user3->id
3235 ]
3236 );
3237
3238 // Default settings - user1 can send a message to both conversations.
3239 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3240 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3241
3242 // Remove the capability to send a message.
3243 $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3244 unassign_capability('moodle/site:sendmessage', $roleids['user'], context_system::instance());
3245
3246 // Verify that a user cannot send a message to either an individual or a group conversation.
3247 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3248 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3249 }
3250
3251 /**
3252 * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the messageanyuser capability.
3253 */
3254 public function test_can_send_message_to_conversation_messageanyuser_cap() {
3255 global $DB;
3256
3257 $user1 = self::getDataGenerator()->create_user();
3258 $user2 = self::getDataGenerator()->create_user();
3259 $user3 = self::getDataGenerator()->create_user();
3260
3261 // Enrol the users into the same course.
3262 $course = $this->getDataGenerator()->create_course();
3263 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3264 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3265 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3266
3267 // Create an individual conversation between user1 and user2.
3268 $ic1 = \core_message\api::create_conversation(
3269 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3270 [
3271 $user1->id,
3272 $user2->id
3273 ]
3274 );
3275
3276 // Group conversation between and users 1, 2 and 3.
3277 $gc1 = \core_message\api::create_conversation(
3278 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3279 [
3280 $user1->id,
3281 $user2->id,
3282 $user3->id
3283 ]
3284 );
3285
3286 // Update the message preference for user2, so they can only be messaged by contacts.
3287 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3288
3289 // Verify that the user cannot be contacted in the individual conversation and that groups are unaffected.
3290 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3291 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3292
3293 // Assign the 'messageanyuser' capability to user1 at system context.
3294 $systemcontext = context_system::instance();
3295 $authenticateduser = $DB->get_record('role', ['shortname' => 'user']);
3296 assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, $systemcontext->id);
3297
3298 // Check that user1 can now message user2 due to the capability, and that group conversations is again unaffected.
3299 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3300 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3301 }
3302
3303 /**
3304 * Test verifying that users cannot send messages to conversations they are not a part of.
3305 */
3306 public function test_can_post_message_to_conversation_non_member() {
3307 // Create some users.
3308 $user1 = self::getDataGenerator()->create_user();
3309 $user2 = self::getDataGenerator()->create_user();
3310 $user3 = self::getDataGenerator()->create_user();
3311 $user4 = self::getDataGenerator()->create_user();
3312
3313 // Enrol the users into the same course.
3314 $course = $this->getDataGenerator()->create_course();
3315 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3316 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3317 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3318 $this->getDataGenerator()->enrol_user($user4->id, $course->id);
3319
3320 // Create an individual conversation between user1 and user2.
3321 $ic1 = \core_message\api::create_conversation(
3322 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3323 [
3324 $user1->id,
3325 $user2->id
3326 ]
3327 );
3328
3329 // Create a group conversation between and users 1, 2 and 3.
3330 $gc1 = \core_message\api::create_conversation(
3331 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3332 [
3333 $user1->id,
3334 $user2->id,
3335 $user3->id
3336 ]
3337 );
3338
3339 // Verify, non members cannot send a message.
3340 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user4->id, $gc1->id));
3341 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user4->id, $ic1->id));
3342 }
3343
3344 /**
3345 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts only.
3346 */
3347 public function test_can_send_message_to_conversation_privacy_contacts_only() {
3348 // Create some users.
3349 $user1 = self::getDataGenerator()->create_user();
3350 $user2 = self::getDataGenerator()->create_user();
3351 $user3 = self::getDataGenerator()->create_user();
3352
3353 // Create an individual conversation between user1 and user2.
3354 $ic1 = \core_message\api::create_conversation(
3355 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3356 [
3357 $user1->id,
3358 $user2->id
3359 ]
3360 );
3361
3362 // Create a group conversation between and users 1, 2 and 3.
3363 $gc1 = \core_message\api::create_conversation(
3364 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3365 [
3366 $user1->id,
3367 $user2->id,
3368 $user3->id
3369 ]
3370 );
3371
3372 // Set the message privacy preference to 'contacts only' for user 2.
3373 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3374
3375 // Verify that user1 cannot send a message to the individual conversation, but that the group conversation is unaffected.
3376 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3377 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3378
3379 // Now, simulate a contact request (and approval) between user1 and user2.
3380 \core_message\api::create_contact_request($user1->id, $user2->id);
3381 \core_message\api::confirm_contact_request($user1->id, $user2->id);
3382
3383 // Verify user1 can now message user2 again via their individual conversation.
3384 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3385 }
3386
3387 /**
3388 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts / course members.
3389 */
3390 public function test_can_send_message_to_conversation_privacy_contacts_course() {
3391 // Create some users.
3392 $user1 = self::getDataGenerator()->create_user();
3393 $user2 = self::getDataGenerator()->create_user();
3394 $user3 = self::getDataGenerator()->create_user();
3395
3396 // Set the message privacy preference to 'contacts + course members' for user 2.
3397 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
3398
3399 // Create an individual conversation between user1 and user2.
3400 $ic1 = \core_message\api::create_conversation(
3401 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3402 [
3403 $user1->id,
3404 $user2->id
3405 ]
3406 );
3407
3408 // Create a group conversation between and users 1, 2 and 3.
3409 $gc1 = \core_message\api::create_conversation(
3410 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3411 [
3412 $user1->id,
3413 $user2->id,
3414 $user3->id
3415 ]
3416 );
3417
3418 // Verify that users in a group conversation can message one another (i.e. privacy controls ignored).
3419 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3420
3421 // Verify that user1 can not message user2 unless they are either contacts, or share a course.
3422 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3423
3424 // Enrol the users into the same course.
3425 $course = $this->getDataGenerator()->create_course();
3426 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3427 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3428 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3429
3430 // Verify that user1 can send a message to user2, based on the shared course, without being a contact.
3431 $this->assertFalse(\core_message\api::is_contact($user1->id, $user2->id));
3432 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3433 }
3434
3435 /**
3436 * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to any user.
3437 */
3438 public function test_can_send_message_to_conversation_privacy_sitewide() {
3439 // Create some users.
3440 $user1 = self::getDataGenerator()->create_user();
3441 $user2 = self::getDataGenerator()->create_user();
3442 $user3 = self::getDataGenerator()->create_user();
3443
3444 // Create an individual conversation between user1 and user2.
3445 $ic1 = \core_message\api::create_conversation(
3446 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3447 [
3448 $user1->id,
3449 $user2->id
3450 ]
3451 );
3452
3453 // Create a group conversation between and users 1, 2 and 3.
3454 $gc1 = \core_message\api::create_conversation(
3455 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3456 [
3457 $user1->id,
3458 $user2->id,
3459 $user3->id
3460 ]
3461 );
3462
3463 // By default, the messaging privacy dictates that users can only be contacted by contacts, and members of their courses.
3464 // Verify also, that groups are not restricted in this way.
3465 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3466 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3467
3468 // Enable site-wide messagging privacy setting.
3469 // This enables a privacy option for users, allowing them to choose to be contactable by anybody on the site.
3470 set_config('messagingallusers', true);
3471
3472 // Set the second user's preference to receive messages from everybody.
3473 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user2->id);
3474
3475 // Check that user1 can send user2 a message, and that the group conversation is unaffected.
3476 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3477 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3478
3479 // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3480 // and members sharing a course with her.
3481 set_config('messagingallusers', false);
3482
3483 // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3484 // Verify also that the group conversation is unaffected.
3485 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user1->id, $ic1->id));
3486 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3487 }
3488
3489 /**
3490 * Test verifying the behaviour of the can_send_message_to_conversation method when a user is blocked.
3491 */
3492 public function test_can_send_message_to_conversation_when_blocked() {
3493 $user1 = self::getDataGenerator()->create_user();
3494 $user2 = self::getDataGenerator()->create_user();
3495 $user3 = self::getDataGenerator()->create_user();
3496
3497 // Create an individual conversation between user1 and user2.
3498 $ic1 = \core_message\api::create_conversation(
3499 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3500 [
3501 $user1->id,
3502 $user2->id
3503 ]
3504 );
3505
3506 // Create a group conversation between and users 1, 2 and 3.
3507 $gc1 = \core_message\api::create_conversation(
3508 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP,
3509 [
3510 $user1->id,
3511 $user2->id,
3512 $user3->id
3513 ]
3514 );
3515
3516 // Enrol the users into the same course.
3517 $course = $this->getDataGenerator()->create_course();
3518 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3519 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3520 $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3521
3522 // Block the second user.
3523 \core_message\api::block_user($user1->id, $user2->id);
3524
3525 // Check that user2 can not send user1 a message in their individual conversation.
3526 $this->assertFalse(\core_message\api::can_send_message_to_conversation($user2->id, $ic1->id));
3527
3528 // Verify that group conversations are unaffected.
3529 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user1->id, $gc1->id));
3530 $this->assertTrue(\core_message\api::can_send_message_to_conversation($user2->id, $gc1->id));
3531 }
3532
f7dfa9ba
SA
3533 /**
3534 * Tests get_user_privacy_messaging_preference method.
3535 */
3536 public function test_get_user_privacy_messaging_preference() {
3537 // Create some users.
3538 $user1 = self::getDataGenerator()->create_user();
3539 $user2 = self::getDataGenerator()->create_user();
3540 $user3 = self::getDataGenerator()->create_user();
3541
3542 // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3543 set_config('messagingallusers', true);
3544
3545 // Set some user preferences.
3546 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_SITE, $user1->id);
3547 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3548
3549 // Check the returned value for each user.
3550 $this->assertEquals(
3551 \core_message\api::MESSAGE_PRIVACY_SITE,
3552 \core_message\api::get_user_privacy_messaging_preference($user1->id)
3553 );
3554 $this->assertEquals(
3555 \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
3556 \core_message\api::get_user_privacy_messaging_preference($user2->id)
3557 );
3558 $this->assertEquals(
3559 \core_message\api::MESSAGE_PRIVACY_SITE,
3560 \core_message\api::get_user_privacy_messaging_preference($user3->id)
3561 );
3562
3563 // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
3564 set_config('messagingallusers', false);
3565
3566 // Check the returned value for each user.
3567 $this->assertEquals(
3568 \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
3569 \core_message\api::get_user_privacy_messaging_preference($user1->id)
3570 );
3571 $this->assertEquals(
3572 \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS,
3573 \core_message\api::get_user_privacy_messaging_preference($user2->id)
3574 );
3575 $this->assertEquals(
3576 \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER,
3577 \core_message\api::get_user_privacy_messaging_preference($user3->id)
3578 );
3579 }
3580
1f64514d
MN
3581 /**
3582 * Tests that when blocking messages from non-contacts is enabled that
3583 * non-contacts trying to send a message return false.
3584 */
3585 public function test_is_user_non_contact_blocked() {
3586 // Create some users.
3587 $user1 = self::getDataGenerator()->create_user();
3588 $user2 = self::getDataGenerator()->create_user();
3589
3590 // Set as the first user.
3591 $this->setUser($user1);
3592
f7dfa9ba
SA
3593 // By default, user only can be messaged by contacts and members of any of his/her courses.
3594 $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
e5eba802 3595 $this->assertDebuggingCalled();
f7dfa9ba
SA
3596
3597 // Enable all users privacy messaging and check now the default user's preference has been set to allow receiving
3598 // messages from everybody.
3599 set_config('messagingallusers', true);
3600 // Check that the return result is now false because any site user can contact him/her.
1f64514d 3601 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
e5eba802 3602 $this->assertDebuggingCalled();
1f64514d
MN
3603
3604 // Set the second user's preference to not receive messages from non-contacts.
f7dfa9ba
SA
3605 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3606 // Check that the return result is still true (because is even more restricted).
1f64514d 3607 $this->assertTrue(\core_message\api::is_user_non_contact_blocked($user2));
e5eba802 3608 $this->assertDebuggingCalled();
1f64514d
MN
3609
3610 // Add the first user as a contact for the second user.
f219eac7 3611 \core_message\api::add_contact($user2->id, $user1->id);
1f64514d
MN
3612
3613 // Check that the return result is now false.
3614 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
e5eba802 3615 $this->assertDebuggingCalled();
f219eac7 3616
f7dfa9ba
SA
3617 // Set the second user's preference to receive messages from course members.
3618 set_user_preference('message_blocknoncontacts', \core_message\api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
3619 // Check that the return result is still false (because $user1 is still his/her contact).
3620 $this->assertFalse(\core_message\api::is_user_non_contact_blocked($user2));
e5eba802 3621 $this->assertDebuggingCalled();
1f64514d
MN
3622 }
3623
3624 /**
3625 * Tests that we return true when a user is blocked, or false
3626 * if they are not blocked.
3627 */
3628 public function test_is_user_blocked() {
3629 // Create some users.
3630 $user1 = self::getDataGenerator()->create_user();
3631 $user2 = self::getDataGenerator()->create_user();
3632
3633 // Set the user.
3634 $this->setUser($user1);
3635
3636 // User shouldn't be blocked.
26dca05d 3637 $this->assertFalse(\core_message\api::is_user_blocked($user1->id, $user2->id));
c886e2c9 3638 $this->assertDebuggingCalled();
1f64514d
MN