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