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