Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace core_message;
18
 
19
use core_message\tests\helper as testhelper;
20
 
21
/**
22
 * Test message API.
23
 *
24
 * @package core_message
25
 * @category test
26
 * @copyright 2016 Mark Nelson <markn@moodle.com>
27
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
11 efrain 28
 * @covers \core_message\api
1 efrain 29
 */
11 efrain 30
final class api_test extends \advanced_testcase {
31
    public function test_mark_all_read_for_user_touser(): void {
32
        $this->resetAfterTest();
1 efrain 33
 
34
        $sender = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
35
        $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
36
 
11 efrain 37
        testhelper::send_fake_message($sender, $recipient, 'Notification', 1);
38
        testhelper::send_fake_message($sender, $recipient, 'Notification', 1);
39
        testhelper::send_fake_message($sender, $recipient, 'Notification', 1);
40
        testhelper::send_fake_message($sender, $recipient);
41
        testhelper::send_fake_message($sender, $recipient);
42
        testhelper::send_fake_message($sender, $recipient);
1 efrain 43
 
44
        $this->assertEquals(1, api::count_unread_conversations($recipient));
45
 
46
        api::mark_all_notifications_as_read($recipient->id);
47
        api::mark_all_messages_as_read($recipient->id);
48
 
49
        // We've marked all of recipients conversation messages as read.
50
        $this->assertEquals(0, api::count_unread_conversations($recipient));
51
    }
52
 
11 efrain 53
    public function test_mark_all_read_for_user_touser_with_fromuser(): void {
54
        $this->resetAfterTest();
55
 
1 efrain 56
        $sender1 = $this->getDataGenerator()->create_user(array('firstname' => 'Test1', 'lastname' => 'User1'));
57
        $sender2 = $this->getDataGenerator()->create_user(array('firstname' => 'Test3', 'lastname' => 'User3'));
58
        $recipient = $this->getDataGenerator()->create_user(array('firstname' => 'Test2', 'lastname' => 'User2'));
11 efrain 59
        $sender1 = $this->getDataGenerator()->create_user(['firstname' => 'Test1', 'lastname' => 'User1']);
60
        $sender2 = $this->getDataGenerator()->create_user(['firstname' => 'Test3', 'lastname' => 'User3']);
61
        $recipient = $this->getDataGenerator()->create_user(['firstname' => 'Test2', 'lastname' => 'User2']);
1 efrain 62
 
11 efrain 63
        testhelper::send_fake_message($sender1, $recipient, 'Notification', 1);
64
        testhelper::send_fake_message($sender1, $recipient, 'Notification', 1);
65
        testhelper::send_fake_message($sender1, $recipient, 'Notification', 1);
66
        testhelper::send_fake_message($sender1, $recipient);
67
        testhelper::send_fake_message($sender1, $recipient);
68
        testhelper::send_fake_message($sender1, $recipient);
69
        testhelper::send_fake_message($sender2, $recipient, 'Notification', 1);
70
        testhelper::send_fake_message($sender2, $recipient, 'Notification', 1);
71
        testhelper::send_fake_message($sender2, $recipient, 'Notification', 1);
72
        testhelper::send_fake_message($sender2, $recipient);
73
        testhelper::send_fake_message($sender2, $recipient);
74
        testhelper::send_fake_message($sender2, $recipient);
1 efrain 75
 
76
        $this->assertEquals(2, api::count_unread_conversations($recipient));
77
 
78
        api::mark_all_notifications_as_read($recipient->id, $sender1->id);
79
        $conversationid = api::get_conversation_between_users([$recipient->id, $sender1->id]);
80
        api::mark_all_messages_as_read($recipient->id, $conversationid);
81
 
82
        // We've marked only the conversation with sender1 messages as read.
83
        $this->assertEquals(1, api::count_unread_conversations($recipient));
84
    }
85
 
86
    /**
87
     * Test count_blocked_users.
88
     */
11 efrain 89
    public function test_count_blocked_users(): void {
1 efrain 90
        global $USER;
11 efrain 91
        $this->resetAfterTest();
1 efrain 92
 
11 efrain 93
 
1 efrain 94
        // Set this user as the admin.
95
        $this->setAdminUser();
96
 
97
        // Create user to add to the admin's block list.
98
        $user1 = $this->getDataGenerator()->create_user();
99
        $user2 = $this->getDataGenerator()->create_user();
100
 
101
        $this->assertEquals(0, api::count_blocked_users());
102
 
103
        // Add 1 blocked user to admin's blocked user list.
104
        api::block_user($USER->id, $user1->id);
105
 
106
        $this->assertEquals(0, api::count_blocked_users($user1));
107
        $this->assertEquals(1, api::count_blocked_users());
108
    }
109
 
110
    /**
111
     * Tests searching for users when site-wide messaging is disabled.
112
     *
113
     * This test verifies that any contacts are returned, as well as any non-contacts whose profile we can view.
114
     * If checks this by placing some users in the same course, where default caps would permit a user to view another user's
115
     * profile.
116
     */
11 efrain 117
    public function test_message_search_users_messagingallusers_disabled(): void {
1 efrain 118
        global $DB;
119
        $this->resetAfterTest();
120
 
121
        // Create some users.
122
        $users = [];
123
        foreach (range(1, 8) as $i) {
124
            $user = new \stdClass();
125
            $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
126
            $user->lastname = $i;
127
            $user = $this->getDataGenerator()->create_user($user);
128
            $users[$i] = $user;
129
        }
130
 
131
        // Enrol a few users in the same course, but leave them as non-contacts.
132
        $course1 = $this->getDataGenerator()->create_course();
133
        $course2 = $this->getDataGenerator()->create_course();
134
 
135
        $this->setAdminUser();
136
        $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
137
        $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
138
        $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
139
 
140
        // Add some other users as contacts.
141
        api::add_contact($users[1]->id, $users[2]->id);
142
        api::add_contact($users[3]->id, $users[1]->id);
143
        api::add_contact($users[1]->id, $users[4]->id);
144
 
145
        // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
146
        $this->getDataGenerator()->enrol_user($users[8]->id, $course2->id, 'editingteacher');
147
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
148
        set_config('coursecontact', $teacherrole->id);
149
 
150
        // Create individual conversations between some users, one contact and one non-contact.
151
        $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
152
            [$users[1]->id, $users[2]->id]);
153
        $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
154
            [$users[6]->id, $users[1]->id]);
155
 
156
        // Create a group conversation between 4 users, including a contact and a non-contact.
157
        $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
158
            [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id], 'Project chat');
159
 
160
        // Set as the user performing the search.
161
        $this->setUser($users[1]);
162
 
163
        // Perform a search with $CFG->messagingallusers disabled.
164
        set_config('messagingallusers', 0);
165
        $result = api::message_search_users($users[1]->id, 'search');
166
 
167
        // Confirm that we returns contacts and non-contacts.
168
        $this->assertArrayHasKey(0, $result);
169
        $this->assertArrayHasKey(1, $result);
170
        $contacts = $result[0];
171
        $noncontacts = $result[1];
172
 
173
        // Check that we retrieved the correct contacts.
174
        $this->assertCount(2, $contacts);
175
        $this->assertEquals($users[2]->id, $contacts[0]->id);
176
        $this->assertEquals($users[3]->id, $contacts[1]->id);
177
 
178
        // Verify the correct conversations were returned for the contacts.
179
        $this->assertCount(2, $contacts[0]->conversations);
180
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
181
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
182
 
183
        $this->assertCount(0, $contacts[1]->conversations);
184
 
185
        // Check that we retrieved the correct non-contacts.
186
        // When site wide messaging is disabled, we expect to see only those users who we share a course with and whose profiles
187
        // are visible in that course. This excludes users like course contacts.
188
        $this->assertCount(3, $noncontacts);
189
        // Self-conversation first.
190
        $this->assertEquals($users[1]->id, $noncontacts[0]->id);
191
        $this->assertEquals($users[6]->id, $noncontacts[1]->id);
192
        $this->assertEquals($users[7]->id, $noncontacts[2]->id);
193
 
194
        // Verify the correct conversations were returned for the non-contacts.
195
        $this->assertCount(1, $noncontacts[1]->conversations);
196
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
197
            $noncontacts[1]->conversations[$ic2->id]->type);
198
 
199
        $this->assertCount(1, $noncontacts[2]->conversations);
200
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
201
    }
202
 
203
    /**
204
     * Tests searching for users when site-wide messaging is enabled.
205
     *
206
     * This test verifies that any contacts are returned, as well as any non-contacts,
207
     * provided the searching user can view their profile.
208
     */
11 efrain 209
    public function test_message_search_users_messagingallusers_enabled(): void {
1 efrain 210
        global $DB;
211
        $this->resetAfterTest();
212
 
213
        // Create some users.
214
        $users = [];
215
        foreach (range(1, 9) as $i) {
216
            $user = new \stdClass();
217
            $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
218
            $user->lastname = $i;
219
            $user = $this->getDataGenerator()->create_user($user);
220
            $users[$i] = $user;
221
        }
222
 
223
        $course1 = $this->getDataGenerator()->create_course();
224
        $coursecontext = \context_course::instance($course1->id);
225
 
226
        // Enrol a few users in the same course, but leave them as non-contacts.
227
        $this->setAdminUser();
228
        $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id, 'student');
229
        $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id, 'student');
230
        $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id, 'student');
231
 
232
        // Add some other users as contacts.
233
        api::add_contact($users[1]->id, $users[2]->id);
234
        api::add_contact($users[3]->id, $users[1]->id);
235
        api::add_contact($users[1]->id, $users[4]->id);
236
 
237
        // Enrol a user as a teacher in the course, and make the teacher role a course contact role.
238
        $this->getDataGenerator()->enrol_user($users[9]->id, $course1->id, 'editingteacher');
239
        $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
240
        set_config('coursecontact', $teacherrole->id);
241
 
242
        // Get self-conversation.
243
        $selfconversation = api::get_self_conversation($users[1]->id);
244
 
245
        // Create individual conversations between some users, one contact and one non-contact.
246
        $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
247
            [$users[1]->id, $users[2]->id]);
248
        $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
249
            [$users[6]->id, $users[1]->id]);
250
 
251
        // Create a group conversation between 5 users, including a contact and a non-contact, and a user NOT in a shared course.
252
        $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
253
            [$users[1]->id, $users[2]->id, $users[4]->id, $users[7]->id, $users[8]->id], 'Project chat');
254
 
255
        // Set as the user performing the search.
256
        $this->setUser($users[1]);
257
 
258
        // Perform a search with $CFG->messagingallusers enabled.
259
        set_config('messagingallusers', 1);
260
        $result = api::message_search_users($users[1]->id, 'search');
261
 
262
        // Confirm that we returns contacts and non-contacts.
263
        $this->assertArrayHasKey(0, $result);
264
        $this->assertArrayHasKey(1, $result);
265
        $contacts = $result[0];
266
        $noncontacts = $result[1];
267
 
268
        // Check that we retrieved the correct contacts.
269
        $this->assertCount(2, $contacts);
270
        $this->assertEquals($users[2]->id, $contacts[0]->id);
271
        $this->assertEquals($users[3]->id, $contacts[1]->id);
272
 
273
        // Verify the correct conversations were returned for the contacts.
274
        $this->assertCount(2, $contacts[0]->conversations);
275
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $contacts[0]->conversations[$gc1->id]->type);
276
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $contacts[0]->conversations[$ic1->id]->type);
277
 
278
        $this->assertCount(0, $contacts[1]->conversations);
279
 
280
        // Check that we retrieved the correct non-contacts.
281
        // If site wide messaging is enabled, we expect to only be able to search for users whose profiles we can view.
282
        // In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1.
283
        // Consider first conversations is self-conversation.
284
        $this->assertCount(4, $noncontacts);
285
        $this->assertEquals($users[1]->id, $noncontacts[0]->id);
286
        $this->assertEquals($users[6]->id, $noncontacts[1]->id);
287
        $this->assertEquals($users[7]->id, $noncontacts[2]->id);
288
        $this->assertEquals($users[9]->id, $noncontacts[3]->id);
289
 
290
        $this->assertCount(1, $noncontacts[1]->conversations);
291
        $this->assertCount(1, $noncontacts[2]->conversations);
292
        $this->assertCount(0, $noncontacts[3]->conversations);
293
 
294
        // Verify the correct conversations were returned for the non-contacts.
295
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF,
296
            $noncontacts[0]->conversations[$selfconversation->id]->type);
297
 
298
        $this->assertCount(1, $noncontacts[1]->conversations);
299
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
300
            $noncontacts[1]->conversations[$ic2->id]->type);
301
 
302
        $this->assertCount(1, $noncontacts[2]->conversations);
303
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $noncontacts[2]->conversations[$gc1->id]->type);
304
 
305
        $this->assertCount(0, $noncontacts[3]->conversations);
306
    }
307
 
308
    /**
309
     * Verify searching for users find themselves when they have self-conversations.
310
     */
11 efrain 311
    public function test_message_search_users_self_conversations(): void {
1 efrain 312
        $this->resetAfterTest();
313
 
314
        // Create some users.
315
        $user1 = new \stdClass();
316
        $user1->firstname = 'User';
317
        $user1->lastname = 'One';
318
        $user1 = $this->getDataGenerator()->create_user($user1);
319
        $user2 = new \stdClass();
320
        $user2->firstname = 'User';
321
        $user2->lastname = 'Two';
322
        $user2 = $this->getDataGenerator()->create_user($user2);
323
 
324
        // Get self-conversation for user1.
325
        $sc1 = api::get_self_conversation($user1->id);
326
        testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi myself!');
327
 
328
        // Perform a search as user1.
329
        $this->setUser($user1);
330
        $result = api::message_search_users($user1->id, 'One');
331
 
332
        // Check user1 is found as non-contacts.
333
        $this->assertCount(0, $result[0]);
334
        $this->assertCount(1, $result[1]);
335
    }
336
 
337
    /**
338
     * Verify searching for users works even if no matching users from either contacts, or non-contacts can be found.
339
     */
11 efrain 340
    public function test_message_search_users_with_empty_result(): void {
1 efrain 341
        $this->resetAfterTest();
342
 
343
        // Create some users, but make sure neither will match the search term.
344
        $user1 = new \stdClass();
345
        $user1->firstname = 'User';
346
        $user1->lastname = 'One';
347
        $user1 = $this->getDataGenerator()->create_user($user1);
348
        $user2 = new \stdClass();
349
        $user2->firstname = 'User';
350
        $user2->lastname = 'Two';
351
        $user2 = $this->getDataGenerator()->create_user($user2);
352
 
353
        // Perform a search as user1.
354
        $this->setUser($user1);
355
        $result = api::message_search_users($user1->id, 'search');
356
 
357
        // Check results are empty.
358
        $this->assertCount(0, $result[0]);
359
        $this->assertCount(0, $result[1]);
360
    }
361
 
362
    /**
363
     * Test verifying that limits and offsets work for both the contacts and non-contacts return data.
364
     */
11 efrain 365
    public function test_message_search_users_limit_offset(): void {
1 efrain 366
        $this->resetAfterTest();
367
 
368
        // Create 20 users.
369
        $users = [];
370
        foreach (range(1, 20) as $i) {
371
            $user = new \stdClass();
372
            $user->firstname = "User search";
373
            $user->lastname = $i;
374
            $user = $this->getDataGenerator()->create_user($user);
375
            $users[$i] = $user;
376
        }
377
 
378
        // Enrol the first 9 users in the same course, but leave them as non-contacts.
379
        $this->setAdminUser();
380
        $course1 = $this->getDataGenerator()->create_course();
381
        foreach (range(1, 8) as $i) {
382
            $this->getDataGenerator()->enrol_user($users[$i]->id, $course1->id);
383
        }
384
 
385
        // Add 5 users, starting at the 11th user, as contacts for user1.
386
        foreach (range(11, 15) as $i) {
387
            api::add_contact($users[1]->id, $users[$i]->id);
388
        }
389
 
390
        // Set as the user performing the search.
391
        $this->setUser($users[1]);
392
 
393
        // Search using a limit of 3.
394
        // This tests the case where we have more results than the limit for both contacts and non-contacts.
395
        $result = api::message_search_users($users[1]->id, 'search', 0, 3);
396
        $contacts = $result[0];
397
        $noncontacts = $result[1];
398
 
399
        // Check that we retrieved the correct contacts.
400
        $this->assertCount(3, $contacts);
401
        $this->assertEquals($users[11]->id, $contacts[0]->id);
402
        $this->assertEquals($users[12]->id, $contacts[1]->id);
403
        $this->assertEquals($users[13]->id, $contacts[2]->id);
404
 
405
        // Check that we retrieved the correct non-contacts.
406
        // Consider first conversations is self-conversation.
407
        $this->assertCount(3, $noncontacts);
408
        $this->assertEquals($users[1]->id, $noncontacts[0]->id);
409
        $this->assertEquals($users[2]->id, $noncontacts[1]->id);
410
        $this->assertEquals($users[3]->id, $noncontacts[2]->id);
411
 
412
        // Now, offset to get the next batch of results.
413
        // We expect to see 2 contacts, and 3 non-contacts.
414
        $result = api::message_search_users($users[1]->id, 'search', 3, 3);
415
        $contacts = $result[0];
416
        $noncontacts = $result[1];
417
        $this->assertCount(2, $contacts);
418
        $this->assertEquals($users[14]->id, $contacts[0]->id);
419
        $this->assertEquals($users[15]->id, $contacts[1]->id);
420
 
421
        $this->assertCount(3, $noncontacts);
422
        $this->assertEquals($users[4]->id, $noncontacts[0]->id);
423
        $this->assertEquals($users[5]->id, $noncontacts[1]->id);
424
        $this->assertEquals($users[6]->id, $noncontacts[2]->id);
425
 
426
        // Now, offset to get the next batch of results.
427
        // We expect to see 0 contacts, and 2 non-contacts.
428
        $result = api::message_search_users($users[1]->id, 'search', 6, 3);
429
        $contacts = $result[0];
430
        $noncontacts = $result[1];
431
        $this->assertCount(0, $contacts);
432
 
433
        $this->assertCount(2, $noncontacts);
434
        $this->assertEquals($users[7]->id, $noncontacts[0]->id);
435
        $this->assertEquals($users[8]->id, $noncontacts[1]->id);
436
    }
437
 
438
    /**
439
     * Tests searching users as a user having the 'moodle/user:viewdetails' capability.
440
     */
11 efrain 441
    public function test_message_search_users_with_cap(): void {
1 efrain 442
        $this->resetAfterTest();
443
        global $DB;
444
 
445
        // Create some users.
446
        $users = [];
447
        foreach (range(1, 8) as $i) {
448
            $user = new \stdClass();
449
            $user->firstname = ($i == 4) ? 'User' : 'User search'; // Ensure the fourth user won't match the search term.
450
            $user->lastname = $i;
451
            $user = $this->getDataGenerator()->create_user($user);
452
            $users[$i] = $user;
453
        }
454
 
455
        // Enrol a few users in the same course, but leave them as non-contacts.
456
        $course1 = $this->getDataGenerator()->create_course();
457
        $this->setAdminUser();
458
        $this->getDataGenerator()->enrol_user($users[1]->id, $course1->id);
459
        $this->getDataGenerator()->enrol_user($users[6]->id, $course1->id);
460
        $this->getDataGenerator()->enrol_user($users[7]->id, $course1->id);
461
 
462
        // Add some other users as contacts.
463
        api::add_contact($users[1]->id, $users[2]->id);
464
        api::add_contact($users[3]->id, $users[1]->id);
465
        api::add_contact($users[1]->id, $users[4]->id);
466
 
467
        // Set as the user performing the search.
468
        $this->setUser($users[1]);
469
 
470
        // Grant the authenticated user role the capability 'user:viewdetails' at site context.
471
        $authenticatedrole = $DB->get_record('role', ['shortname' => 'user'], '*', MUST_EXIST);
472
        assign_capability('moodle/user:viewdetails', CAP_ALLOW, $authenticatedrole->id, \context_system::instance());
473
 
474
        // Perform a search with $CFG->messagingallusers disabled.
475
        set_config('messagingallusers', 0);
476
        $result = api::message_search_users($users[1]->id, 'search');
477
        $contacts = $result[0];
478
        $noncontacts = $result[1];
479
 
480
        // Check that we retrieved the correct contacts.
481
        $this->assertCount(2, $contacts);
482
        $this->assertEquals($users[2]->id, $contacts[0]->id);
483
        $this->assertEquals($users[3]->id, $contacts[1]->id);
484
 
485
        // Check that we retrieved the correct non-contacts.
486
        // Site-wide messaging is disabled, so we expect to be able to search for any users whose profiles we can view.
487
        // Consider first conversations is self-conversation.
488
        $this->assertCount(3, $noncontacts);
489
        $this->assertEquals($users[1]->id, $noncontacts[0]->id);
490
        $this->assertEquals($users[6]->id, $noncontacts[1]->id);
491
        $this->assertEquals($users[7]->id, $noncontacts[2]->id);
492
    }
493
 
494
    /**
495
     * Tests searching users with messaging disabled.
496
     */
11 efrain 497
    public function test_message_search_users_messaging_disabled(): void {
1 efrain 498
        $this->resetAfterTest();
499
 
500
        // Create a user.
501
        $user = $this->getDataGenerator()->create_user();
502
 
503
        // Disable messaging.
504
        set_config('messaging', 0);
505
 
506
        // Ensure an exception is thrown.
507
        $this->expectException('moodle_exception');
508
        api::message_search_users($user->id, 'User');
509
    }
510
 
511
    /**
512
     * Tests getting conversations between 2 users.
513
     */
11 efrain 514
    public function test_get_conversations_between_users(): void {
515
        $this->resetAfterTest();
516
 
1 efrain 517
        // Create some users.
518
        $user1 = new \stdClass();
519
        $user1->firstname = 'User';
520
        $user1->lastname = 'One';
521
        $user1 = self::getDataGenerator()->create_user($user1);
522
 
523
        $user2 = new \stdClass();
524
        $user2->firstname = 'User';
525
        $user2->lastname = 'Two';
526
        $user2 = self::getDataGenerator()->create_user($user2);
527
 
528
        $user3 = new \stdClass();
529
        $user3->firstname = 'User search';
530
        $user3->lastname = 'Three';
531
        $user3 = self::getDataGenerator()->create_user($user3);
532
 
533
        $user4 = new \stdClass();
534
        $user4->firstname = 'User';
535
        $user4->lastname = 'Four';
536
        $user4 = self::getDataGenerator()->create_user($user4);
537
 
538
        $user5 = new \stdClass();
539
        $user5->firstname = 'User';
540
        $user5->lastname = 'Five';
541
        $user5 = self::getDataGenerator()->create_user($user5);
542
 
543
        $user6 = new \stdClass();
544
        $user6->firstname = 'User search';
545
        $user6->lastname = 'Six';
546
        $user6 = self::getDataGenerator()->create_user($user6);
547
 
548
        // Add some users as contacts.
549
        api::add_contact($user1->id, $user2->id);
550
        api::add_contact($user6->id, $user1->id);
551
 
552
        // Create private conversations with some users.
553
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
554
            array($user1->id, $user2->id));
555
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
556
            array($user3->id, $user1->id));
557
 
558
        // Create a group conversation with users.
559
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
560
            array($user1->id, $user2->id, $user3->id, $user4->id),
561
            'Project chat');
562
 
563
        // Check that we retrieved the correct conversations.
564
        $this->assertCount(2, api::get_conversations_between_users($user1->id, $user2->id));
565
        $this->assertCount(2, api::get_conversations_between_users($user2->id, $user1->id));
566
        $this->assertCount(2, api::get_conversations_between_users($user1->id, $user3->id));
567
        $this->assertCount(2, api::get_conversations_between_users($user3->id, $user1->id));
568
        $this->assertCount(1, api::get_conversations_between_users($user1->id, $user4->id));
569
        $this->assertCount(1, api::get_conversations_between_users($user4->id, $user1->id));
570
        $this->assertCount(0, api::get_conversations_between_users($user1->id, $user5->id));
571
        $this->assertCount(0, api::get_conversations_between_users($user5->id, $user1->id));
572
        $this->assertCount(0, api::get_conversations_between_users($user1->id, $user6->id));
573
        $this->assertCount(0, api::get_conversations_between_users($user6->id, $user1->id));
574
    }
575
 
576
    /**
577
     * Tests getting self-conversations.
578
     */
11 efrain 579
    public function test_get_self_conversation(): void {
580
        $this->resetAfterTest();
581
 
1 efrain 582
        // Create some users.
583
        $user1 = new \stdClass();
584
        $user1->firstname = 'User';
585
        $user1->lastname = 'One';
586
        $user1 = self::getDataGenerator()->create_user($user1);
587
 
588
        $user2 = new \stdClass();
589
        $user2->firstname = 'User';
590
        $user2->lastname = 'Two';
591
        $user2 = self::getDataGenerator()->create_user($user2);
592
 
593
        $user3 = new \stdClass();
594
        $user3->firstname = 'User search';
595
        $user3->lastname = 'Three';
596
        $user3 = self::getDataGenerator()->create_user($user3);
597
 
598
        // Add some users as contacts.
599
        api::add_contact($user1->id, $user2->id);
600
        api::add_contact($user3->id, $user1->id);
601
 
602
        // Create private conversations with some users.
603
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
604
            array($user1->id, $user2->id));
605
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
606
            array($user3->id, $user1->id));
607
 
608
        // Create a group conversation with users.
609
        $gc = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
610
            array($user1->id, $user2->id, $user3->id),
611
            'Project chat');
612
 
613
        // Get self-conversations.
614
        $rsc1 = api::get_self_conversation($user1->id);
615
        $rsc2 = api::get_self_conversation($user2->id);
616
        $rsc3 = api::get_self_conversation($user3->id);
617
 
618
        // Send message to self-conversation.
619
        testhelper::send_fake_message_to_conversation($user1, $rsc1->id, 'Message to myself!');
620
 
621
        // Check that we retrieved the correct conversations.
622
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc1->type);
623
        $members = api::get_conversation_members($user1->id, $rsc1->id);
624
        $this->assertCount(1, $members);
625
        $member = reset($members);
626
        $this->assertEquals($user1->id, $member->id);
627
 
628
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_SELF, $rsc2->type);
629
        $members = api::get_conversation_members($user2->id, $rsc2->id);
630
        $this->assertCount(1, $members);
631
        $member = reset($members);
632
        $this->assertEquals($user2->id, $member->id);
633
 
634
        api::delete_all_conversation_data($rsc3->id);
635
        $selfconversation = api::get_self_conversation($user3->id);
636
        $members = api::get_conversation_members($user1->id, $selfconversation->id);
637
        $this->assertCount(1, $members);
638
    }
639
 
640
    /**
641
     * Tests searching messages.
642
     */
11 efrain 643
    public function test_search_messages(): void {
1 efrain 644
        $this->resetAfterTest();
645
 
646
        // Create some users.
647
        $user1 = self::getDataGenerator()->create_user();
648
        $user2 = self::getDataGenerator()->create_user();
649
        $user3 = self::getDataGenerator()->create_user();
650
 
651
        // The person doing the search.
652
        $this->setUser($user1);
653
 
654
        // Get self-conversation.
655
        $sc = api::get_self_conversation($user1->id);
656
 
657
        // Create group conversation.
658
        $gc = api::create_conversation(
659
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
660
            [$user1->id, $user2->id, $user3->id]
661
        );
662
 
663
        // Send some messages back and forth.
664
        $time = 1;
665
        testhelper::send_fake_message_to_conversation($user1, $sc->id, 'Test message to self!', $time);
666
        testhelper::send_fake_message_to_conversation($user1, $gc->id, 'My hero!', $time + 1);
11 efrain 667
        testhelper::send_fake_message($user3, $user1, 'Don\'t block me.', 0, $time + 2);
668
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 3);
669
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 4);
670
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 5);
671
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 6);
1 efrain 672
 
673
        $convid = api::get_conversation_between_users([$user1->id, $user2->id]);
674
        $conv2id = api::get_conversation_between_users([$user1->id, $user3->id]);
675
 
676
        // Block user 3.
677
        api::block_user($user1->id, $user3->id);
678
 
679
        // Perform a search.
680
        $messages = api::search_messages($user1->id, 'o');
681
 
682
        // Confirm the data is correct.
683
        $this->assertEquals(5, count($messages));
684
        $message1 = $messages[0];
685
        $message2 = $messages[1];
686
        $message3 = $messages[2];
687
        $message4 = $messages[3];
688
        $message5 = $messages[4];
689
 
690
        $this->assertEquals($user2->id, $message1->userid);
691
        $this->assertEquals($user2->id, $message1->useridfrom);
692
        $this->assertEquals(fullname($user2), $message1->fullname);
693
        $this->assertTrue($message1->ismessaging);
694
        $this->assertEquals('Word.', $message1->lastmessage);
695
        $this->assertNotEmpty($message1->messageid);
696
        $this->assertNull($message1->isonline);
697
        $this->assertFalse($message1->isread);
698
        $this->assertFalse($message1->isblocked);
699
        $this->assertNull($message1->unreadcount);
700
        $this->assertEquals($convid, $message1->conversationid);
701
 
702
        $this->assertEquals($user2->id, $message2->userid);
703
        $this->assertEquals($user1->id, $message2->useridfrom);
704
        $this->assertEquals(fullname($user2), $message2->fullname);
705
        $this->assertTrue($message2->ismessaging);
706
        $this->assertEquals('Yo!', $message2->lastmessage);
707
        $this->assertNotEmpty($message2->messageid);
708
        $this->assertNull($message2->isonline);
709
        $this->assertTrue($message2->isread);
710
        $this->assertFalse($message2->isblocked);
711
        $this->assertNull($message2->unreadcount);
712
        $this->assertEquals($convid, $message2->conversationid);
713
 
714
        $this->assertEquals($user3->id, $message3->userid);
715
        $this->assertEquals($user3->id, $message3->useridfrom);
716
        $this->assertEquals(fullname($user3), $message3->fullname);
717
        $this->assertTrue($message3->ismessaging);
718
        $this->assertEquals('Don\'t block me.', $message3->lastmessage);
719
        $this->assertNotEmpty($message3->messageid);
720
        $this->assertNull($message3->isonline);
721
        $this->assertFalse($message3->isread);
722
        $this->assertTrue($message3->isblocked);
723
        $this->assertNull($message3->unreadcount);
724
        $this->assertEquals($conv2id, $message3->conversationid);
725
 
726
        // This is a group conversation. For now, search_messages returns only one of the other users on the conversation. It can't
727
        // be guaranteed who will be returned in the first place, so we need to use the in_array to check all the possibilities.
728
        $this->assertTrue(in_array($message4->userid, [$user2->id, $user3->id]));
729
        $this->assertEquals($user1->id, $message4->useridfrom);
730
        $this->assertTrue($message4->ismessaging);
731
        $this->assertEquals('My hero!', $message4->lastmessage);
732
        $this->assertNotEmpty($message4->messageid);
733
        $this->assertNull($message4->isonline);
734
        $this->assertTrue($message4->isread);
735
        $this->assertNull($message4->unreadcount);
736
        $this->assertEquals($gc->id, $message4->conversationid);
737
 
738
        $this->assertEquals($user1->id, $message5->userid);
739
        $this->assertEquals($user1->id, $message5->useridfrom);
740
        $this->assertEquals(fullname($user1), $message5->fullname);
741
        $this->assertTrue($message5->ismessaging);
742
        $this->assertEquals('Test message to self!', $message5->lastmessage);
743
        $this->assertNotEmpty($message5->messageid);
744
        $this->assertFalse($message5->isonline);
745
        $this->assertTrue($message5->isread);
746
        $this->assertFalse($message5->isblocked);
747
        $this->assertNull($message5->unreadcount);
748
        $this->assertEquals($sc->id, $message5->conversationid);
749
    }
750
 
751
    /**
752
     * Test verifying that favourited conversations can be retrieved.
753
     */
11 efrain 754
    public function test_get_favourite_conversations(): void {
755
        $this->resetAfterTest();
756
 
1 efrain 757
        // Create some users.
758
        $user1 = self::getDataGenerator()->create_user();
759
        $user2 = self::getDataGenerator()->create_user();
760
        $user3 = self::getDataGenerator()->create_user();
761
        $user4 = self::getDataGenerator()->create_user();
762
 
763
        // The person doing the search.
764
        $this->setUser($user1);
765
 
766
        // Only self-conversation created.
767
        $this->assertCount(1, api::get_conversations($user1->id));
768
 
769
        // Create some conversations for user1.
770
        $time = 1;
11 efrain 771
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
772
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
773
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
774
        $messageid1 = testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 775
 
11 efrain 776
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
777
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
778
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
779
        $messageid2 = testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 780
 
11 efrain 781
        testhelper::send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
782
        testhelper::send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
783
        $messageid3 = testhelper::send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
1 efrain 784
 
785
        // Favourite the first 2 conversations for user1.
786
        $convoids = [];
787
        $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]);
788
        $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]);
789
        $user1context = \context_user::instance($user1->id);
790
        $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
791
        foreach ($convoids as $convoid) {
792
            $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
793
        }
794
 
795
        // We should have 4 conversations.
796
        // Consider first conversations is self-conversation.
797
        $this->assertCount(4, api::get_conversations($user1->id));
798
 
799
        // And 3 favourited conversations (self-conversation included).
800
        $conversations = api::get_conversations($user1->id, 0, 20, null, true);
801
        $this->assertCount(3, $conversations);
802
        $conversations = api::get_conversations(
803
            $user1->id,
804
            0,
805
            20,
806
            api::MESSAGE_CONVERSATION_TYPE_SELF,
807
            true
808
        );
809
        $this->assertCount(1, $conversations);
810
    }
811
 
812
    /**
813
     * Tests retrieving favourite conversations with a limit and offset to ensure pagination works correctly.
814
     */
11 efrain 815
    public function test_get_favourite_conversations_limit_offset(): void {
816
        $this->resetAfterTest();
817
 
1 efrain 818
        // Create some users.
819
        $user1 = self::getDataGenerator()->create_user();
820
        $user2 = self::getDataGenerator()->create_user();
821
        $user3 = self::getDataGenerator()->create_user();
822
        $user4 = self::getDataGenerator()->create_user();
823
 
824
        // The person doing the search.
825
        $this->setUser($user1);
826
 
827
        // Only self-conversation created.
828
        $this->assertCount(1, api::get_conversations($user1->id));
829
 
830
        // Create some conversations for user1.
831
        $time = 1;
11 efrain 832
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
833
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
834
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
835
        $messageid1 = testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 836
 
11 efrain 837
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
838
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
839
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
840
        $messageid2 = testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 841
 
11 efrain 842
        testhelper::send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?', 0, $time + 9);
843
        testhelper::send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.', 0, $time + 10);
844
        $messageid3 = testhelper::send_fake_message($user1, $user4, 'Dope.', 0, $time + 11);
1 efrain 845
 
846
        // Favourite the all conversations for user1.
847
        $convoids = [];
848
        $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]);
849
        $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]);
850
        $convoids[] = api::get_conversation_between_users([$user1->id, $user4->id]);
851
        $user1context = \context_user::instance($user1->id);
852
        $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
853
        foreach ($convoids as $convoid) {
854
            $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
855
        }
856
 
857
        // Consider first conversations is self-conversation.
858
        // Get all records, using offset 0 and large limit.
859
        $this->assertCount(4, api::get_conversations($user1->id, 0, 20, null, true));
860
 
861
        // Now, get 10 conversations starting at the second record. We should see 2 conversations.
862
        $this->assertCount(3, api::get_conversations($user1->id, 1, 10, null, true));
863
 
864
        // Now, try to get favourited conversations using an invalid offset.
865
        $this->assertCount(0, api::get_conversations($user1->id, 5, 10, null, true));
866
    }
867
 
868
    /**
869
     * Tests retrieving favourite conversations when a conversation contains a deleted user.
870
     */
11 efrain 871
    public function test_get_favourite_conversations_with_deleted_user(): void {
872
        $this->resetAfterTest();
873
 
1 efrain 874
        // Create some users.
875
        $user1 = self::getDataGenerator()->create_user();
876
        $user2 = self::getDataGenerator()->create_user();
877
        $user3 = self::getDataGenerator()->create_user();
878
 
879
        // Send some messages back and forth, have some different conversations with different users.
880
        $time = 1;
11 efrain 881
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
882
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
883
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
884
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 885
 
11 efrain 886
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
887
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
888
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
889
        testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 890
 
891
        // Favourite the all conversations for user1.
892
        $convoids = [];
893
        $convoids[] = api::get_conversation_between_users([$user1->id, $user2->id]);
894
        $convoids[] = api::get_conversation_between_users([$user1->id, $user3->id]);
895
        $user1context = \context_user::instance($user1->id);
896
        $service = \core_favourites\service_factory::get_service_for_user_context($user1context);
897
        foreach ($convoids as $convoid) {
898
            $service->create_favourite('core_message', 'message_conversations', $convoid, $user1context);
899
        }
900
 
901
        // Delete the second user.
902
        delete_user($user2);
903
 
904
        // Retrieve the conversations.
905
        $conversations = api::get_conversations($user1->id, 0, 20, null, true);
906
 
907
        // We should have both conversations, despite the other user being soft-deleted.
908
        // Consider first conversations is self-conversation.
909
        $this->assertCount(3, $conversations);
910
 
911
        // Confirm the conversation is from the non-deleted user.
912
        $conversation = reset($conversations);
913
        $this->assertEquals($convoids[1], $conversation->id);
914
    }
915
 
916
    /**
917
     * Test confirming that conversations can be marked as favourites.
918
     */
11 efrain 919
    public function test_set_favourite_conversation(): void {
920
        $this->resetAfterTest();
921
 
1 efrain 922
        // Create some users.
923
        $user1 = self::getDataGenerator()->create_user();
924
        $user2 = self::getDataGenerator()->create_user();
925
        $user3 = self::getDataGenerator()->create_user();
926
 
927
        // Send some messages back and forth, have some different conversations with different users.
928
        $time = 1;
11 efrain 929
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
930
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
931
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
932
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 933
 
11 efrain 934
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
935
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
936
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
937
        testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 938
 
939
        // Favourite the first conversation as user 1.
940
        $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]);
941
        $favourite = api::set_favourite_conversation($conversationid1, $user1->id);
942
 
943
        // Verify we have two favourite conversations a user 1.
944
        // Consider first conversations is self-conversation.
945
        $this->assertCount(2, api::get_conversations($user1->id, 0, 20, null, true));
946
 
947
        // Verify we have only one favourite as user2, despite being a member in that conversation.
948
        // Consider first conversations is self-conversation.
949
        $this->assertCount(1, api::get_conversations($user2->id, 0, 20, null, true));
950
 
951
        // Try to favourite the same conversation again should just return the existing favourite.
952
        $repeatresult = api::set_favourite_conversation($conversationid1, $user1->id);
953
        $this->assertEquals($favourite->id, $repeatresult->id);
954
    }
955
 
956
    /**
957
     * Test verifying that trying to mark a non-existent conversation as a favourite, results in an exception.
958
     */
11 efrain 959
    public function test_set_favourite_conversation_nonexistent_conversation(): void {
960
        $this->resetAfterTest();
961
 
1 efrain 962
        // Create some users.
963
        $user1 = self::getDataGenerator()->create_user();
964
        // Try to favourite a non-existent conversation.
965
        $this->expectException(\moodle_exception::class);
966
        api::set_favourite_conversation(0, $user1->id);
967
    }
968
 
969
    /**
970
     * Test verifying that a conversation cannot be marked as favourite unless the user is a member of that conversation.
971
     */
11 efrain 972
    public function test_set_favourite_conversation_non_member(): void {
973
        $this->resetAfterTest();
974
 
1 efrain 975
        // Create some users.
976
        $user1 = self::getDataGenerator()->create_user();
977
        $user2 = self::getDataGenerator()->create_user();
978
        $user3 = self::getDataGenerator()->create_user();
979
 
980
        // Send some messages back and forth, have some different conversations with different users.
981
        $time = 1;
11 efrain 982
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
983
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
984
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
985
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 986
 
11 efrain 987
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
988
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
989
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
990
        testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 991
 
992
        // Try to favourite the first conversation as user 3, who is not a member.
993
        $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]);
994
        $this->expectException(\moodle_exception::class);
995
        api::set_favourite_conversation($conversationid1, $user3->id);
996
    }
997
 
998
    /**
999
     * Test confirming that those conversations marked as favourites can be unfavourited.
1000
     */
11 efrain 1001
    public function test_unset_favourite_conversation(): void {
1002
        $this->resetAfterTest();
1003
 
1 efrain 1004
        // Create some users.
1005
        $user1 = self::getDataGenerator()->create_user();
1006
        $user2 = self::getDataGenerator()->create_user();
1007
        $user3 = self::getDataGenerator()->create_user();
1008
 
1009
        // Send some messages back and forth, have some different conversations with different users.
1010
        $time = 1;
11 efrain 1011
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1012
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1013
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1014
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 1015
 
11 efrain 1016
        testhelper::send_fake_message($user1, $user3, 'Booyah', 0, $time + 5);
1017
        testhelper::send_fake_message($user3, $user1, 'Whaaat?', 0, $time + 6);
1018
        testhelper::send_fake_message($user1, $user3, 'Nothing.', 0, $time + 7);
1019
        testhelper::send_fake_message($user3, $user1, 'Cool.', 0, $time + 8);
1 efrain 1020
 
1021
        // Favourite the first conversation as user 1 and the second as user 3.
1022
        $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]);
1023
        $conversationid2 = api::get_conversation_between_users([$user1->id, $user3->id]);
1024
        api::set_favourite_conversation($conversationid1, $user1->id);
1025
        api::set_favourite_conversation($conversationid2, $user3->id);
1026
 
1027
        // Verify we have two favourite conversations for both user 1 and user 3, counting self conversations.
1028
        $this->assertCount(2, api::get_conversations($user1->id, 0, 20, null, true));
1029
        $this->assertCount(2, api::get_conversations($user3->id, 0, 20, null, true));
1030
 
1031
        // Now unfavourite the conversation as user 1.
1032
        api::unset_favourite_conversation($conversationid1, $user1->id);
1033
 
1034
        // Verify we have two favourite conversations user 3 only, and one for user1, counting self conversations.
1035
        $this->assertCount(2, api::get_conversations($user3->id, 0, 20, null, true));
1036
        $this->assertCount(1, api::get_conversations($user1->id, 0, 20, null, true));
1037
 
1038
        // Try to favourite the same conversation again as user 1.
1039
        $this->expectException(\moodle_exception::class);
1040
        api::unset_favourite_conversation($conversationid1, $user1->id);
1041
    }
1042
 
1043
    /**
1044
     * Test verifying that a valid conversation cannot be unset as a favourite if it's not marked as a favourite.
1045
     */
11 efrain 1046
    public function test_unset_favourite_conversation_not_favourite(): void {
1047
        $this->resetAfterTest();
1048
 
1 efrain 1049
        // Create some users.
1050
        $user1 = self::getDataGenerator()->create_user();
1051
        $user2 = self::getDataGenerator()->create_user();
1052
 
1053
        // Send some messages back and forth, have some different conversations with different users.
1054
        $time = 1;
11 efrain 1055
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
1056
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
1057
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
1058
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 1059
 
1060
        // Now try to unfavourite the conversation as user 1.
1061
        $conversationid1 = api::get_conversation_between_users([$user1->id, $user2->id]);
1062
        $this->expectException(\moodle_exception::class);
1063
        api::unset_favourite_conversation($conversationid1, $user1->id);
1064
    }
1065
 
1066
    /**
1067
     * Test verifying that a non-existent conversation cannot be unset as a favourite.
1068
     */
11 efrain 1069
    public function test_unset_favourite_conversation_non_existent_conversation(): void {
1070
        $this->resetAfterTest();
1071
 
1 efrain 1072
        // Create some users.
1073
        $user1 = self::getDataGenerator()->create_user();
1074
 
1075
        // Now try to unfavourite the conversation as user 1.
1076
        $this->expectException(\moodle_exception::class);
1077
        api::unset_favourite_conversation(0, $user1->id);
1078
    }
1079
 
1080
    /**
1081
     * Helper to seed the database with initial state.
1082
     */
1083
    protected function create_conversation_test_data() {
1084
        // Create some users.
1085
        $user1 = self::getDataGenerator()->create_user();
1086
        $user2 = self::getDataGenerator()->create_user();
1087
        $user3 = self::getDataGenerator()->create_user();
1088
        $user4 = self::getDataGenerator()->create_user();
1089
 
1090
        $time = 1;
1091
 
1092
        // Create some conversations. We want:
1093
        // 1) At least one of each type (group, individual) of which user1 IS a member and DID send the most recent message.
1094
        // 2) At least one of each type (group, individual) of which user1 IS a member and DID NOT send the most recent message.
1095
        // 3) At least one of each type (group, individual) of which user1 IS NOT a member.
1096
        // 4) At least two group conversation having 0 messages, of which user1 IS a member (To confirm conversationid ordering).
1097
        // 5) At least one group conversation having 0 messages, of which user1 IS NOT a member.
1098
 
1099
        // Individual conversation, user1 is a member, last message from other user.
1100
        $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1101
            [$user1->id, $user2->id]);
1102
        testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message 1', $time);
1103
        testhelper::send_fake_message_to_conversation($user2, $ic1->id, 'Message 2', $time + 1);
1104
 
1105
        // Individual conversation, user1 is a member, last message from user1.
1106
        $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1107
            [$user1->id, $user3->id]);
1108
        testhelper::send_fake_message_to_conversation($user3, $ic2->id, 'Message 3', $time + 2);
1109
        testhelper::send_fake_message_to_conversation($user1, $ic2->id, 'Message 4', $time + 3);
1110
 
1111
        // Individual conversation, user1 is not a member.
1112
        $ic3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1113
            [$user2->id, $user3->id]);
1114
        testhelper::send_fake_message_to_conversation($user2, $ic3->id, 'Message 5', $time + 4);
1115
        testhelper::send_fake_message_to_conversation($user3, $ic3->id, 'Message 6', $time + 5);
1116
 
1117
        // Group conversation, user1 is not a member.
1118
        $gc1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1119
            [$user2->id, $user3->id, $user4->id], 'Project discussions');
1120
        testhelper::send_fake_message_to_conversation($user2, $gc1->id, 'Message 7', $time + 6);
1121
        testhelper::send_fake_message_to_conversation($user4, $gc1->id, 'Message 8', $time + 7);
1122
 
1123
        // Group conversation, user1 is a member, last message from another user.
1124
        $gc2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1125
            [$user1->id, $user3->id, $user4->id], 'Group chat');
1126
        testhelper::send_fake_message_to_conversation($user1, $gc2->id, 'Message 9', $time + 8);
1127
        testhelper::send_fake_message_to_conversation($user3, $gc2->id, 'Message 10', $time + 9);
1128
        testhelper::send_fake_message_to_conversation($user4, $gc2->id, 'Message 11', $time + 10);
1129
 
1130
        // Group conversation, user1 is a member, last message from user1.
1131
        $gc3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1132
            [$user1->id, $user2->id, $user3->id, $user4->id], 'Group chat again!');
1133
        testhelper::send_fake_message_to_conversation($user4, $gc3->id, 'Message 12', $time + 11);
1134
        testhelper::send_fake_message_to_conversation($user3, $gc3->id, 'Message 13', $time + 12);
1135
        testhelper::send_fake_message_to_conversation($user1, $gc3->id, 'Message 14', $time + 13);
1136
 
1137
        // Empty group conversations (x2), user1 is a member.
1138
        $gc4 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1139
            [$user1->id, $user2->id, $user3->id], 'Empty group');
1140
        $gc5 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1141
            [$user1->id, $user2->id, $user4->id], 'Another empty group');
1142
 
1143
        // Empty group conversation, user1 is NOT a member.
1144
        $gc6 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1145
            [$user2->id, $user3->id, $user4->id], 'Empty group 3');
1146
 
1147
        return [$user1, $user2, $user3, $user4, $ic1, $ic2, $ic3, $gc1, $gc2, $gc3, $gc4, $gc5, $gc6];
1148
    }
1149
 
1150
    /**
1151
     * Test verifying get_conversations when no limits, offsets, type filters or favourite restrictions are used.
1152
     */
11 efrain 1153
    public function test_get_conversations_no_restrictions(): void {
1154
        $this->resetAfterTest();
1155
 
1 efrain 1156
        global $DB;
1157
 
1158
        $user1 = self::getDataGenerator()->create_user();
1159
        // Self-conversation should exists.
1160
        $this->assertCount(1, api::get_conversations($user1->id));
1161
 
1162
        // Get a bunch of conversations, some group, some individual and in different states.
1163
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1164
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1165
 
1166
        // Get all conversations for user1.
1167
        $conversations = api::get_conversations($user1->id);
1168
 
1169
        // Verify there are 2 individual conversation, 2 group conversations, 2 empty group conversations,
1170
        // and a self-conversation.
1171
        // The conversations with the most recent messages should be listed first, followed by the empty
1172
        // conversations, with the most recently created first.
1173
        $this->assertCount(7, $conversations);
1174
        $typecounts  = array_count_values(array_column($conversations, 'type'));
1175
        $this->assertEquals(2, $typecounts[1]);
1176
        $this->assertEquals(4, $typecounts[2]);
1177
        $this->assertEquals(1, $typecounts[3]);
1178
 
1179
        // Those conversations having messages should be listed after self-conversation, ordered by most recent message time.
1180
        $this->assertEquals($gc3->id, $conversations[0]->id);
1181
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[0]->type);
1182
        $this->assertFalse($conversations[1]->isfavourite);
1183
        $this->assertCount(1, $conversations[0]->members);
1184
        $this->assertEquals(4, $conversations[0]->membercount);
1185
        $this->assertCount(1, $conversations[0]->messages);
1186
        $message = $DB->get_record('messages', ['id' => $conversations[0]->messages[0]->id]);
1187
        $expectedmessagetext = message_format_message_text($message);
1188
        $this->assertEquals($expectedmessagetext, $conversations[0]->messages[0]->text);
1189
        $this->assertEquals($user1->id, $conversations[0]->messages[0]->useridfrom);
1190
 
1191
        $this->assertEquals($gc2->id, $conversations[1]->id);
1192
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[1]->type);
1193
        $this->assertFalse($conversations[1]->isfavourite);
1194
        $this->assertCount(1, $conversations[1]->members);
1195
        $this->assertEquals(3, $conversations[1]->membercount);
1196
        $this->assertCount(1, $conversations[1]->messages);
1197
        $message = $DB->get_record('messages', ['id' => $conversations[1]->messages[0]->id]);
1198
        $expectedmessagetext = message_format_message_text($message);
1199
        $this->assertEquals($expectedmessagetext, $conversations[1]->messages[0]->text);
1200
        $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1201
 
1202
        $this->assertEquals($ic2->id, $conversations[2]->id);
1203
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[2]->type);
1204
        $this->assertFalse($conversations[2]->isfavourite);
1205
        $this->assertCount(1, $conversations[2]->members);
1206
        $this->assertEquals($user3->id, $conversations[2]->members[$user3->id]->id);
1207
        $this->assertEquals(2, $conversations[2]->membercount);
1208
        $this->assertCount(1, $conversations[2]->messages);
1209
        $message = $DB->get_record('messages', ['id' => $conversations[2]->messages[0]->id]);
1210
        $expectedmessagetext = message_format_message_text($message);
1211
        $this->assertEquals($expectedmessagetext, $conversations[2]->messages[0]->text);
1212
        $this->assertEquals($user1->id, $conversations[2]->messages[0]->useridfrom);
1213
 
1214
        $this->assertEquals($ic1->id, $conversations[3]->id);
1215
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversations[3]->type);
1216
        $this->assertFalse($conversations[3]->isfavourite);
1217
        $this->assertCount(1, $conversations[3]->members);
1218
        $this->assertEquals(2, $conversations[3]->membercount);
1219
        $this->assertCount(1, $conversations[3]->messages);
1220
        $message = $DB->get_record('messages', ['id' => $conversations[3]->messages[0]->id]);
1221
        $expectedmessagetext = message_format_message_text($message);
1222
        $this->assertEquals($expectedmessagetext, $conversations[3]->messages[0]->text);
1223
        $this->assertEquals($user2->id, $conversations[3]->messages[0]->useridfrom);
1224
 
1225
        // Of the groups without messages, we expect to see the most recently created first.
1226
        $this->assertEquals($gc5->id, $conversations[4]->id);
1227
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[4]->type);
1228
        $this->assertFalse($conversations[4]->isfavourite);
1229
        $this->assertCount(0, $conversations[4]->members); // No members returned, because no recent messages exist.
1230
        $this->assertEquals(3, $conversations[4]->membercount);
1231
        $this->assertEmpty($conversations[4]->messages);
1232
 
1233
        $this->assertEquals($gc4->id, $conversations[5]->id);
1234
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversations[5]->type);
1235
        $this->assertFalse($conversations[5]->isfavourite);
1236
        $this->assertCount(0, $conversations[5]->members);
1237
        $this->assertEquals(3, $conversations[5]->membercount);
1238
        $this->assertEmpty($conversations[5]->messages);
1239
 
1240
        // Verify format of the return structure.
1241
        foreach ($conversations as $conv) {
1242
            $this->assertObjectHasProperty('id', $conv);
1243
            $this->assertObjectHasProperty('name', $conv);
1244
            $this->assertObjectHasProperty('subname', $conv);
1245
            $this->assertObjectHasProperty('imageurl', $conv);
1246
            $this->assertObjectHasProperty('type', $conv);
1247
            $this->assertObjectHasProperty('isfavourite', $conv);
1248
            $this->assertObjectHasProperty('membercount', $conv);
1249
            $this->assertObjectHasProperty('isread', $conv);
1250
            $this->assertObjectHasProperty('unreadcount', $conv);
1251
            $this->assertObjectHasProperty('members', $conv);
1252
            foreach ($conv->members as $member) {
1253
                $this->assertObjectHasProperty('id', $member);
1254
                $this->assertObjectHasProperty('fullname', $member);
1255
                $this->assertObjectHasProperty('profileimageurl', $member);
1256
                $this->assertObjectHasProperty('profileimageurlsmall', $member);
1257
                $this->assertObjectHasProperty('isonline', $member);
1258
                $this->assertObjectHasProperty('showonlinestatus', $member);
1259
                $this->assertObjectHasProperty('isblocked', $member);
1260
                $this->assertObjectHasProperty('iscontact', $member);
1261
                $this->assertObjectHasProperty('isdeleted', $member);
1262
                $this->assertObjectHasProperty('canmessage', $member);
1263
                $this->assertObjectHasProperty('requirescontact', $member);
1264
                $this->assertObjectHasProperty('contactrequests', $member);
1265
            }
1266
            $this->assertObjectHasProperty('messages', $conv);
1267
            foreach ($conv->messages as $message) {
1268
                $this->assertObjectHasProperty('id', $message);
1269
                $this->assertObjectHasProperty('useridfrom', $message);
1270
                $this->assertObjectHasProperty('text', $message);
1271
                $this->assertObjectHasProperty('timecreated', $message);
1272
            }
1273
        }
1274
    }
1275
 
1276
    /**
1277
     * Test verifying that html format messages are supported, and that message_format_message_text() is being called appropriately.
1278
     */
11 efrain 1279
    public function test_get_conversations_message_format(): void {
1 efrain 1280
        global $DB;
11 efrain 1281
        $this->resetAfterTest();
1282
 
1 efrain 1283
        // Create some users.
1284
        $user1 = self::getDataGenerator()->create_user();
1285
        $user2 = self::getDataGenerator()->create_user();
1286
 
1287
        // Create conversation.
1288
        $conversation = api::create_conversation(
1289
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1290
            [$user1->id, $user2->id]
1291
        );
1292
 
1293
        // Send some messages back and forth.
1294
        $time = 1;
1295
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 1);
1296
        $mid = testhelper::send_fake_message_to_conversation($user1, $conversation->id, '<a href="#">A link</a>', $time + 2);
1297
 
1298
        // Verify the format of the html message.
1299
        $message = $DB->get_record('messages', ['id' => $mid]);
1300
        $expectedmessagetext = message_format_message_text($message);
1301
        $conversations = api::get_conversations($user1->id);
1302
        $messages = $conversations[0]->messages;
1303
        $this->assertEquals($expectedmessagetext, $messages[0]->text);
1304
    }
1305
 
1306
    /**
1307
     * Test verifying get_conversations identifies if a conversation is muted or not.
1308
     */
11 efrain 1309
    public function test_get_conversations_some_muted(): void {
1310
        $this->resetAfterTest();
1311
 
1 efrain 1312
        // Create some users.
1313
        $user1 = self::getDataGenerator()->create_user();
1314
        $user2 = self::getDataGenerator()->create_user();
1315
        $user3 = self::getDataGenerator()->create_user();
1316
 
1317
        $conversation1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1318
            [$user1->id, $user2->id]);
1319
        testhelper::send_fake_message_to_conversation($user1, $conversation1->id, 'Message 1');
1320
        testhelper::send_fake_message_to_conversation($user2, $conversation1->id, 'Message 2');
1321
        api::mute_conversation($user1->id, $conversation1->id);
1322
 
1323
        $conversation2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1324
            [$user1->id, $user3->id]);
1325
        testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Message 1');
1326
        testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Message 2');
1327
 
1328
        $conversation3 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1329
            [$user1->id, $user2->id]);
1330
        api::mute_conversation($user1->id, $conversation3->id);
1331
 
1332
        $conversation4 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP,
1333
            [$user1->id, $user3->id]);
1334
 
1335
        $conversations = api::get_conversations($user1->id);
1336
 
1337
        usort($conversations, function($first, $second){
1338
            return $first->id <=> $second->id;
1339
        });
1340
 
1341
        // Consider first conversations is self-conversation.
1342
        $selfconversation = array_shift($conversations);
1343
        $conv1 = array_shift($conversations);
1344
        $conv2 = array_shift($conversations);
1345
        $conv3 = array_shift($conversations);
1346
        $conv4 = array_shift($conversations);
1347
 
1348
        $this->assertTrue($conv1->ismuted);
1349
        $this->assertFalse($conv2->ismuted);
1350
        $this->assertTrue($conv3->ismuted);
1351
        $this->assertFalse($conv4->ismuted);
1352
    }
1353
 
1354
    /**
1355
     * Tests retrieving conversations with a limit and offset to ensure pagination works correctly.
1356
     */
11 efrain 1357
    public function test_get_conversations_limit_offset(): void {
1358
        $this->resetAfterTest();
1359
 
1 efrain 1360
        // Get a bunch of conversations, some group, some individual and in different states.
1361
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1362
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1363
 
1364
        // Get all conversations for user1, limited to 1 result.
1365
        $conversations = api::get_conversations($user1->id, 0, 1);
1366
 
1367
        // Verify the first conversation.
1368
        $this->assertCount(1, $conversations);
1369
        $conversation = array_shift($conversations);
1370
        $this->assertEquals($conversation->id, $gc3->id);
1371
 
1372
        // Verify the next conversation.
1373
        $conversations = api::get_conversations($user1->id, 1, 1);
1374
        $this->assertCount(1, $conversations);
1375
        $this->assertEquals($gc2->id, $conversations[0]->id);
1376
 
1377
        // Verify the next conversation.
1378
        $conversations = api::get_conversations($user1->id, 2, 1);
1379
        $this->assertCount(1, $conversations);
1380
        $this->assertEquals($ic2->id, $conversations[0]->id);
1381
 
1382
        // Skip one and get both empty conversations.
1383
        $conversations = api::get_conversations($user1->id, 4, 2);
1384
        $this->assertCount(2, $conversations);
1385
        $this->assertEquals($gc5->id, $conversations[0]->id);
1386
        $this->assertEmpty($conversations[0]->messages);
1387
        $this->assertEquals($gc4->id, $conversations[1]->id);
1388
        $this->assertEmpty($conversations[1]->messages);
1389
 
1390
        // Ask for an offset that doesn't exist and verify no conversations are returned.
1391
        $conversations = api::get_conversations($user1->id, 10, 1);
1392
        $this->assertCount(0, $conversations);
1393
    }
1394
 
1395
    /**
1396
     * Test verifying the type filtering behaviour of the
1397
     */
11 efrain 1398
    public function test_get_conversations_type_filter(): void {
1399
        $this->resetAfterTest();
1400
 
1 efrain 1401
        // Get a bunch of conversations, some group, some individual and in different states.
1402
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1403
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1404
 
1405
        // Verify we can ask for only individual conversations.
1406
        $conversations = api::get_conversations($user1->id, 0, 20,
1407
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1408
        $this->assertCount(2, $conversations);
1409
 
1410
        // Verify we can ask for only group conversations.
1411
        $conversations = api::get_conversations($user1->id, 0, 20,
1412
            api::MESSAGE_CONVERSATION_TYPE_GROUP);
1413
        $this->assertCount(4, $conversations);
1414
 
1415
        // Verify an exception is thrown if an unrecognized type is specified.
1416
        $this->expectException(\moodle_exception::class);
1417
        $conversations = api::get_conversations($user1->id, 0, 20, 0);
1418
    }
1419
 
1420
    /**
1421
     * Tests retrieving conversations when a 'self' conversation exists.
1422
     */
11 efrain 1423
    public function test_get_conversations_self_conversations(): void {
1 efrain 1424
        global $DB;
11 efrain 1425
        $this->resetAfterTest();
1 efrain 1426
 
11 efrain 1427
 
1 efrain 1428
        // Create a conversation between one user and themself.
1429
        $user1 = self::getDataGenerator()->create_user();
1430
        $user2 = self::getDataGenerator()->create_user();
1431
        $user3 = self::getDataGenerator()->create_user();
1432
        $user4 = self::getDataGenerator()->create_user();
1433
 
1434
        // Create some individual conversations.
1435
        $ic1 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1436
            [$user1->id, $user2->id]);
1437
        $ic2 = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1438
            [$user1->id, $user3->id]);
1439
        testhelper::send_fake_message_to_conversation($user1, $ic1->id, 'Message from user1 to user2');
1440
 
1441
        // Get some self-conversations.
1442
        $sc1 = api::get_self_conversation($user1->id);
1443
        $sc4 = api::get_self_conversation($user4->id);
1444
        testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Test message to self 1!');
1445
 
1446
        // Verify we are in a 'self' conversation state.
1447
        $members = $DB->get_records('message_conversation_members', ['conversationid' => $sc1->id]);
1448
        $this->assertCount(1, $members);
1449
        $member = array_pop($members);
1450
        $this->assertEquals($user1->id, $member->userid);
1451
 
1452
        // Verify the self-conversations are returned by the method.
1453
        $conversations = api::get_conversations($user1->id, 0, 20, api::MESSAGE_CONVERSATION_TYPE_SELF);
1454
        $this->assertCount(1, $conversations);
1455
        $conversation = array_pop($conversations);
1456
        $this->assertEquals($conversation->id, $sc1->id);
1457
 
1458
        $conversations = api::get_conversations($user4->id);
1459
        // The self-conversation.
1460
        $this->assertCount(1, $conversations);
1461
 
1462
        // Get only private conversations for user1 (empty conversations, like $ic2, are not returned).
1463
        $conversations = api::get_conversations($user1->id, 0, 20,
1464
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1465
        $this->assertCount(1, $conversations);
1466
 
1467
        // Merge self with private conversations for user1.
1468
        $conversations = api::get_conversations($user1->id, 0, 20,
1469
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true);
1470
        $this->assertCount(2, $conversations);
1471
 
1472
        // Get only private conversations for user2.
1473
        $conversations = api::get_conversations($user2->id, 0, 20,
1474
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL);
1475
        $this->assertCount(1, $conversations);
1476
 
1477
        // Merge self with private conversations for user2.
1478
        $conversations = api::get_conversations($user2->id, 0, 20,
1479
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, null, true);
1480
        $this->assertCount(2, $conversations);
1481
    }
1482
 
1483
    /**
1484
     * Tests retrieving conversations when a conversation contains a deleted user.
1485
     */
11 efrain 1486
    public function test_get_conversations_with_deleted_user(): void {
1487
        $this->resetAfterTest();
1488
 
1 efrain 1489
        // Get a bunch of conversations, some group, some individual and in different states.
1490
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1491
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1492
 
1493
        // Delete the second user and retrieve the conversations.
1494
        // We should have 6 still, as conversations with soft-deleted users are still returned.
1495
        // Group conversations are also present, albeit with less members.
1496
        delete_user($user2);
1497
        // This is to confirm an exception is not thrown when a user AND the user context is deleted.
1498
        // We no longer delete the user context, but historically we did.
1499
        \context_helper::delete_instance(CONTEXT_USER, $user2->id);
1500
        $conversations = api::get_conversations($user1->id);
1501
        // Consider there's a self-conversation (the last one).
1502
        $this->assertCount(7, $conversations);
1503
        $this->assertEquals($gc3->id, $conversations[0]->id);
1504
        $this->assertcount(1, $conversations[0]->members);
1505
        $this->assertEquals($gc2->id, $conversations[1]->id);
1506
        $this->assertcount(1, $conversations[1]->members);
1507
        $this->assertEquals($ic2->id, $conversations[2]->id);
1508
        $this->assertEquals($ic1->id, $conversations[3]->id);
1509
        $this->assertEquals($gc5->id, $conversations[4]->id);
1510
        $this->assertEquals($gc4->id, $conversations[5]->id);
1511
 
1512
        // Delete a user from a group conversation where that user had sent the most recent message.
1513
        // This user will still be present in the members array, as will the message in the messages array.
1514
        delete_user($user4);
1515
        $conversations = api::get_conversations($user1->id);
1516
 
1517
        // Consider there's a self-conversation (the last one).
1518
        $this->assertCount(7, $conversations);
1519
        $this->assertEquals($gc2->id, $conversations[1]->id);
1520
        $this->assertcount(1, $conversations[1]->members);
1521
        $this->assertEquals($user4->id, $conversations[1]->members[$user4->id]->id);
1522
        $this->assertcount(1, $conversations[1]->messages);
1523
        $this->assertEquals($user4->id, $conversations[1]->messages[0]->useridfrom);
1524
 
1525
        // Delete the third user and retrieve the conversations.
1526
        // We should have 6 still, as conversations with soft-deleted users are still returned.
1527
        // Group conversations are also present, albeit with less members.
1528
        delete_user($user3);
1529
        $conversations = api::get_conversations($user1->id);
1530
        // Consider there's a self-conversation (the last one).
1531
        $this->assertCount(7, $conversations);
1532
        $this->assertEquals($gc3->id, $conversations[0]->id);
1533
        $this->assertcount(1, $conversations[0]->members);
1534
        $this->assertEquals($gc2->id, $conversations[1]->id);
1535
        $this->assertcount(1, $conversations[1]->members);
1536
        $this->assertEquals($ic2->id, $conversations[2]->id);
1537
        $this->assertEquals($ic1->id, $conversations[3]->id);
1538
        $this->assertEquals($gc5->id, $conversations[4]->id);
1539
        $this->assertEquals($gc4->id, $conversations[5]->id);
1540
    }
1541
 
1542
    /**
1543
     * Test confirming the behaviour of get_conversations() when users delete all messages.
1544
     */
11 efrain 1545
    public function test_get_conversations_deleted_messages(): void {
1546
        $this->resetAfterTest();
1547
 
1 efrain 1548
        // Get a bunch of conversations, some group, some individual and in different states.
1549
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1550
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1551
 
1552
        $conversations = api::get_conversations($user1->id);
1553
        // Consider first conversations is self-conversation.
1554
        $this->assertCount(7, $conversations);
1555
 
1556
        // Delete all messages from a group conversation the user is in - it should be returned.
1557
        $this->assertTrue(api::is_user_in_conversation($user1->id, $gc2->id));
1558
        $convmessages = api::get_conversation_messages($user1->id, $gc2->id);
1559
        $messages = $convmessages['messages'];
1560
        foreach ($messages as $message) {
1561
            api::delete_message($user1->id, $message->id);
1562
        }
1563
        $conversations = api::get_conversations($user1->id);
1564
        // Consider first conversations is self-conversation.
1565
        $this->assertCount(7, $conversations);
1566
        $this->assertContainsEquals($gc2->id, array_column($conversations, 'id'));
1567
 
1568
        // Delete all messages from an individual conversation the user is in - it should not be returned.
1569
        $this->assertTrue(api::is_user_in_conversation($user1->id, $ic1->id));
1570
        $convmessages = api::get_conversation_messages($user1->id, $ic1->id);
1571
        $messages = $convmessages['messages'];
1572
        foreach ($messages as $message) {
1573
            api::delete_message($user1->id, $message->id);
1574
        }
1575
        $conversations = api::get_conversations($user1->id);
1576
        // Consider first conversations is self-conversation.
1577
        $this->assertCount(6, $conversations);
1578
        $this->assertNotContainsEquals($ic1->id, array_column($conversations, 'id'));
1579
    }
1580
 
1581
    /**
1582
     * Test verifying the behaviour of get_conversations() when fetching favourite conversations with only a single
1583
     * favourite.
1584
     */
11 efrain 1585
    public function test_get_conversations_favourite_conversations_single(): void {
1586
        $this->resetAfterTest();
1587
 
1 efrain 1588
        // Get a bunch of conversations, some group, some individual and in different states.
1589
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1590
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1591
 
1592
        // Mark a single conversation as favourites.
1593
        api::set_favourite_conversation($ic2->id, $user1->id);
1594
 
1595
        // Get the conversation, first with no restrictions, confirming the favourite status of the conversations.
1596
        $conversations = api::get_conversations($user1->id);
1597
        // Consider there is a self-conversation.
1598
        $selfconversation = api::get_self_conversation($user1->id);
1599
        $this->assertCount(7, $conversations);
1600
        foreach ($conversations as $conv) {
1601
            if (in_array($conv->id, [$ic2->id, $selfconversation->id])) {
1602
                $this->assertTrue($conv->isfavourite);
1603
            } else {
1604
                $this->assertFalse($conv->isfavourite);
1605
            }
1606
        }
1607
 
1608
        // Now, get ONLY favourite conversations (including self-conversation).
1609
        $conversations = api::get_conversations($user1->id, 0, 20, null, true);
1610
        $this->assertCount(2, $conversations);
1611
        foreach ($conversations as $conv) {
1612
            if ($conv->type != api::MESSAGE_CONVERSATION_TYPE_SELF) {
1613
                $this->assertTrue($conv->isfavourite);
1614
                $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conv->type);
1615
                $this->assertEquals($ic2->id, $conv->id);
1616
            }
1617
        }
1618
 
1619
        // Now, try ONLY favourites of type 'group'.
1620
        $conversations = api::get_conversations($user1->id, 0, 20,
1621
            api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1622
        $this->assertEmpty($conversations);
1623
 
1624
        // And NO favourite conversations.
1625
        $conversations = api::get_conversations($user1->id, 0, 20, null, false);
1626
        $this->assertCount(5, $conversations);
1627
        foreach ($conversations as $conv) {
1628
            $this->assertFalse($conv->isfavourite);
1629
            $this->assertNotEquals($ic2, $conv->id);
1630
        }
1631
    }
1632
 
1633
    /**
1634
     * Test verifying the behaviour of get_conversations() when fetching favourite conversations.
1635
     */
11 efrain 1636
    public function test_get_conversations_favourite_conversations(): void {
1637
        $this->resetAfterTest();
1638
 
1 efrain 1639
        // Get a bunch of conversations, some group, some individual and in different states.
1640
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
1641
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
1642
 
1643
        // Try to get ONLY favourite conversations, when only self-conversation exist.
1644
        $this->assertCount(1, api::get_conversations($user1->id, 0, 20, null, true));
1645
 
1646
        // Unstar self-conversation.
1647
        $selfconversation = api::get_self_conversation($user1->id);
1648
        api::unset_favourite_conversation($selfconversation->id, $user1->id);
1649
 
1650
        // Try to get ONLY favourite conversations, when no favourites exist.
1651
        $this->assertEquals([], api::get_conversations($user1->id, 0, 20, null, true));
1652
 
1653
        // Try to get NO favourite conversations, when no favourites exist.
1654
        $this->assertCount(7, api::get_conversations($user1->id, 0, 20, null, false));
1655
 
1656
        // Mark a few conversations as favourites.
1657
        api::set_favourite_conversation($ic1->id, $user1->id);
1658
        api::set_favourite_conversation($gc2->id, $user1->id);
1659
        api::set_favourite_conversation($gc5->id, $user1->id);
1660
        $favouriteids = [$ic1->id, $gc2->id, $gc5->id];
1661
 
1662
        // Get the conversations, first with no restrictions, confirming the favourite status of the conversations.
1663
        $conversations = api::get_conversations($user1->id);
1664
        $this->assertCount(7, $conversations);
1665
        foreach ($conversations as $conv) {
1666
            if (in_array($conv->id, $favouriteids)) {
1667
                $this->assertTrue($conv->isfavourite);
1668
            } else {
1669
                $this->assertFalse($conv->isfavourite);
1670
            }
1671
        }
1672
 
1673
        // Now, get ONLY favourite conversations.
1674
        $conversations = api::get_conversations($user1->id, 0, 20, null, true);
1675
        $this->assertCount(3, $conversations);
1676
        foreach ($conversations as $conv) {
1677
            $this->assertTrue($conv->isfavourite);
1678
            $this->assertNotFalse(array_search($conv->id, $favouriteids));
1679
        }
1680
 
1681
        // Now, try ONLY favourites of type 'group'.
1682
        $conversations = api::get_conversations($user1->id, 0, 20,
1683
            api::MESSAGE_CONVERSATION_TYPE_GROUP, true);
1684
        $this->assertCount(2, $conversations);
1685
        foreach ($conversations as $conv) {
1686
            $this->assertTrue($conv->isfavourite);
1687
            $this->assertNotFalse(array_search($conv->id, [$gc2->id, $gc5->id]));
1688
        }
1689
 
1690
        // And NO favourite conversations.
1691
        $conversations = api::get_conversations($user1->id, 0, 20, null, false);
1692
        $this->assertCount(4, $conversations);
1693
        foreach ($conversations as $conv) {
1694
            $this->assertFalse($conv->isfavourite);
1695
            $this->assertFalse(array_search($conv->id, $favouriteids));
1696
        }
1697
    }
1698
 
1699
    /**
1700
     * Test verifying get_conversations when there are users in a group and/or individual conversation. The reason this
1701
     * test is performed is because we do not need as much data for group conversations (saving DB calls), so we want
1702
     * to confirm this happens.
1703
     */
11 efrain 1704
    public function test_get_conversations_user_in_group_and_individual_chat(): void {
1 efrain 1705
        $this->resetAfterTest();
1706
 
11 efrain 1707
        $this->resetAfterTest();
1708
 
1 efrain 1709
        $user1 = self::getDataGenerator()->create_user();
1710
        $user2 = self::getDataGenerator()->create_user();
1711
        $user3 = self::getDataGenerator()->create_user();
1712
 
1713
        $conversation = api::create_conversation(
1714
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
1715
            [
1716
                $user1->id,
1717
                $user2->id
1718
            ],
1719
            'Individual conversation'
1720
        );
1721
 
1722
        testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1723
 
1724
        $conversation = api::create_conversation(
1725
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
1726
            [
1727
                $user1->id,
1728
                $user2->id,
1729
            ],
1730
            'Group conversation'
1731
        );
1732
 
1733
        testhelper::send_fake_message_to_conversation($user1, $conversation->id);
1734
 
1735
        api::create_contact_request($user1->id, $user2->id);
1736
        api::create_contact_request($user1->id, $user3->id);
1737
 
1738
        $conversations = api::get_conversations($user2->id);
1739
 
1740
        $groupconversation = array_shift($conversations);
1741
        $individualconversation = array_shift($conversations);
1742
 
1743
        $this->assertEquals('Group conversation', $groupconversation->name);
1744
        $this->assertEquals('Individual conversation', $individualconversation->name);
1745
 
1746
        $this->assertCount(1, $groupconversation->members);
1747
        $this->assertCount(1, $individualconversation->members);
1748
 
1749
        $groupmember = reset($groupconversation->members);
1750
        $this->assertNull($groupmember->requirescontact);
1751
        $this->assertNull($groupmember->canmessage);
1752
        $this->assertEmpty($groupmember->contactrequests);
1753
 
1754
        $individualmember = reset($individualconversation->members);
1755
        $this->assertNotNull($individualmember->requirescontact);
1756
        $this->assertNotNull($individualmember->canmessage);
1757
        $this->assertNotEmpty($individualmember->contactrequests);
1758
    }
1759
 
1760
    /**
1761
     * Test verifying that group linked conversations are returned and contain a subname matching the course name.
1762
     */
11 efrain 1763
    public function test_get_conversations_group_linked(): void {
1 efrain 1764
        global $CFG, $DB;
11 efrain 1765
        $this->resetAfterTest();
1 efrain 1766
 
11 efrain 1767
 
1 efrain 1768
        // Create some users.
1769
        $user1 = self::getDataGenerator()->create_user();
1770
        $user2 = self::getDataGenerator()->create_user();
1771
        $user3 = self::getDataGenerator()->create_user();
1772
 
1773
        $course1 = $this->getDataGenerator()->create_course();
1774
 
1775
        // Create a group with a linked conversation and a valid image.
1776
        $this->setAdminUser();
1777
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
1778
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
1779
        $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
1780
        $group1 = $this->getDataGenerator()->create_group([
1781
            'courseid' => $course1->id,
1782
            'enablemessaging' => 1,
1783
            'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
1784
        ]);
1785
 
1786
        // Add users to group1.
1787
        $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1788
        $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
1789
 
1790
        // Verify the group with the image works as expected.
1791
        $conversations = api::get_conversations($user1->id);
1792
        $this->assertEquals(2, $conversations[0]->membercount);
1793
        $this->assertEquals($course1->shortname, $conversations[0]->subname);
1794
        $groupimageurl = get_group_picture_url($group1, $group1->courseid, true);
1795
        $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
1796
 
1797
        // Create a group with a linked conversation and without any image.
1798
        $group2 = $this->getDataGenerator()->create_group([
1799
            'courseid' => $course1->id,
1800
            'enablemessaging' => 1,
1801
        ]);
1802
 
1803
        // Add users to group2.
1804
        $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1805
        $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
1806
 
1807
        // Verify the group without any image works as expected too.
1808
        $conversations = api::get_conversations($user3->id);
1809
        // Consider first conversations is self-conversation.
1810
        $this->assertEquals(2, $conversations[0]->membercount);
1811
        $this->assertEquals($course1->shortname, $conversations[0]->subname);
1812
        $this->assertEquals('https://www.example.com/moodle/theme/image.php/boost/core/1/g/g1', $conversations[0]->imageurl);
1813
 
1814
        // Now, disable the conversation linked to the group and verify it's no longer returned.
1815
        $DB->set_field('message_conversations', 'enabled', 0, ['id' => $conversations[0]->id]);
1816
        $conversations = api::get_conversations($user3->id);
1817
        $this->assertCount(1, $conversations);
1818
    }
1819
 
1820
   /**
1821
    * The data provider for get_conversations_mixed.
1822
    *
1823
    * This provides sets of data to for testing.
1824
    * @return array
1825
    */
1826
   public function get_conversations_mixed_provider() {
1827
       return array(
1828
            'Test that conversations with messages contacts is correctly ordered.' => array(
1829
                'users' => array(
1830
                    'user1',
1831
                    'user2',
1832
                    'user3',
1833
                ),
1834
                'contacts' => array(
1835
                ),
1836
                'messages' => array(
1837
                    array(
1838
                        'from'          => 'user1',
1839
                        'to'            => 'user2',
1840
                        'state'         => 'unread',
1841
                        'subject'       => 'S1',
1842
                    ),
1843
                    array(
1844
                        'from'          => 'user2',
1845
                        'to'            => 'user1',
1846
                        'state'         => 'unread',
1847
                        'subject'       => 'S2',
1848
                    ),
1849
                    array(
1850
                        'from'          => 'user1',
1851
                        'to'            => 'user2',
1852
                        'state'         => 'unread',
1853
                        'timecreated'   => 0,
1854
                        'subject'       => 'S3',
1855
                    ),
1856
                    array(
1857
                        'from'          => 'user1',
1858
                        'to'            => 'user3',
1859
                        'state'         => 'read',
1860
                        'timemodifier'  => 1,
1861
                        'subject'       => 'S4',
1862
                    ),
1863
                    array(
1864
                        'from'          => 'user3',
1865
                        'to'            => 'user1',
1866
                        'state'         => 'read',
1867
                        'timemodifier'  => 1,
1868
                        'subject'       => 'S5',
1869
                    ),
1870
                    array(
1871
                        'from'          => 'user1',
1872
                        'to'            => 'user3',
1873
                        'state'         => 'read',
1874
                        'timecreated'   => 0,
1875
                        'subject'       => 'S6',
1876
                    ),
1877
                ),
1878
                'expectations' => array(
1879
                    'user1' => array(
1880
                        // User1 has conversed most recently with user3. The most recent message is M5.
1881
                        array(
1882
                            'messageposition'   => 0,
1883
                            'with'              => 'user3',
1884
                            'subject'           => '<p>S5</p>',
1885
                            'unreadcount'       => 0,
1886
                        ),
1887
                        // User1 has also conversed with user2. The most recent message is S2.
1888
                        array(
1889
                            'messageposition'   => 1,
1890
                            'with'              => 'user2',
1891
                            'subject'           => '<p>S2</p>',
1892
                            'unreadcount'       => 1,
1893
                        ),
1894
                    ),
1895
                    'user2' => array(
1896
                        // User2 has only conversed with user1. Their most recent shared message was S2.
1897
                        array(
1898
                            'messageposition'   => 0,
1899
                            'with'              => 'user1',
1900
                            'subject'           => '<p>S2</p>',
1901
                            'unreadcount'       => 2,
1902
                        ),
1903
                    ),
1904
                    'user3' => array(
1905
                        // User3 has only conversed with user1. Their most recent shared message was S5.
1906
                        array(
1907
                            'messageposition'   => 0,
1908
                            'with'              => 'user1',
1909
                            'subject'           => '<p>S5</p>',
1910
                            'unreadcount'       => 0,
1911
                        ),
1912
                    ),
1913
                ),
1914
            ),
1915
            'Test conversations with a single user, where some messages are read and some are not.' => array(
1916
                'users' => array(
1917
                    'user1',
1918
                    'user2',
1919
                ),
1920
                'contacts' => array(
1921
                ),
1922
                'messages' => array(
1923
                    array(
1924
                        'from'          => 'user1',
1925
                        'to'            => 'user2',
1926
                        'state'         => 'read',
1927
                        'subject'       => 'S1',
1928
                    ),
1929
                    array(
1930
                        'from'          => 'user2',
1931
                        'to'            => 'user1',
1932
                        'state'         => 'read',
1933
                        'subject'       => 'S2',
1934
                    ),
1935
                    array(
1936
                        'from'          => 'user1',
1937
                        'to'            => 'user2',
1938
                        'state'         => 'unread',
1939
                        'timemodifier'  => 1,
1940
                        'subject'       => 'S3',
1941
                    ),
1942
                    array(
1943
                        'from'          => 'user1',
1944
                        'to'            => 'user2',
1945
                        'state'         => 'unread',
1946
                        'timemodifier'  => 1,
1947
                        'subject'       => 'S4',
1948
                    ),
1949
                ),
1950
                'expectations' => array(
1951
                    // The most recent message between user1 and user2 was S4.
1952
                    'user1' => array(
1953
                        array(
1954
                            'messageposition'   => 0,
1955
                            'with'              => 'user2',
1956
                            'subject'           => '<p>S4</p>',
1957
                            'unreadcount'       => 0,
1958
                        ),
1959
                    ),
1960
                    'user2' => array(
1961
                        // The most recent message between user1 and user2 was S4.
1962
                        array(
1963
                            'messageposition'   => 0,
1964
                            'with'              => 'user1',
1965
                            'subject'           => '<p>S4</p>',
1966
                            'unreadcount'       => 2,
1967
                        ),
1968
                    ),
1969
                ),
1970
            ),
1971
            'Test conversations with a single user, where some messages are read and some are not, and messages ' .
1972
            'are out of order' => array(
1973
            // This can happen through a combination of factors including multi-master DB replication with messages
1974
            // read somehow (e.g. API).
1975
                'users' => array(
1976
                    'user1',
1977
                    'user2',
1978
                ),
1979
                'contacts' => array(
1980
                ),
1981
                'messages' => array(
1982
                    array(
1983
                        'from'          => 'user1',
1984
                        'to'            => 'user2',
1985
                        'state'         => 'read',
1986
                        'subject'       => 'S1',
1987
                        'timemodifier'  => 1,
1988
                    ),
1989
                    array(
1990
                        'from'          => 'user2',
1991
                        'to'            => 'user1',
1992
                        'state'         => 'read',
1993
                        'subject'       => 'S2',
1994
                        'timemodifier'  => 2,
1995
                    ),
1996
                    array(
1997
                        'from'          => 'user1',
1998
                        'to'            => 'user2',
1999
                        'state'         => 'unread',
2000
                        'subject'       => 'S3',
2001
                    ),
2002
                    array(
2003
                        'from'          => 'user1',
2004
                        'to'            => 'user2',
2005
                        'state'         => 'unread',
2006
                        'subject'       => 'S4',
2007
                    ),
2008
                ),
2009
                'expectations' => array(
2010
                    // The most recent message between user1 and user2 was S2, even though later IDs have not been read.
2011
                    'user1' => array(
2012
                        array(
2013
                            'messageposition'   => 0,
2014
                            'with'              => 'user2',
2015
                            'subject'           => '<p>S2</p>',
2016
                            'unreadcount'       => 0,
2017
                        ),
2018
                    ),
2019
                    'user2' => array(
2020
                        array(
2021
                            'messageposition'   => 0,
2022
                            'with'              => 'user1',
2023
                            'subject'           => '<p>S2</p>',
2024
                            'unreadcount'       => 2
2025
                        ),
2026
                    ),
2027
                ),
2028
            ),
2029
            'Test unread message count is correct for both users' => array(
2030
                'users' => array(
2031
                    'user1',
2032
                    'user2',
2033
                ),
2034
                'contacts' => array(
2035
                ),
2036
                'messages' => array(
2037
                    array(
2038
                        'from'          => 'user1',
2039
                        'to'            => 'user2',
2040
                        'state'         => 'read',
2041
                        'subject'       => 'S1',
2042
                        'timemodifier'  => 1,
2043
                    ),
2044
                    array(
2045
                        'from'          => 'user2',
2046
                        'to'            => 'user1',
2047
                        'state'         => 'read',
2048
                        'subject'       => 'S2',
2049
                        'timemodifier'  => 2,
2050
                    ),
2051
                    array(
2052
                        'from'          => 'user1',
2053
                        'to'            => 'user2',
2054
                        'state'         => 'read',
2055
                        'subject'       => 'S3',
2056
                        'timemodifier'  => 3,
2057
                    ),
2058
                    array(
2059
                        'from'          => 'user1',
2060
                        'to'            => 'user2',
2061
                        'state'         => 'read',
2062
                        'subject'       => 'S4',
2063
                        'timemodifier'  => 4,
2064
                    ),
2065
                    array(
2066
                        'from'          => 'user1',
2067
                        'to'            => 'user2',
2068
                        'state'         => 'unread',
2069
                        'subject'       => 'S5',
2070
                        'timemodifier'  => 5,
2071
                    ),
2072
                    array(
2073
                        'from'          => 'user2',
2074
                        'to'            => 'user1',
2075
                        'state'         => 'unread',
2076
                        'subject'       => 'S6',
2077
                        'timemodifier'  => 6,
2078
                    ),
2079
                    array(
2080
                        'from'          => 'user1',
2081
                        'to'            => 'user2',
2082
                        'state'         => 'unread',
2083
                        'subject'       => 'S7',
2084
                        'timemodifier'  => 7,
2085
                    ),
2086
                    array(
2087
                        'from'          => 'user1',
2088
                        'to'            => 'user2',
2089
                        'state'         => 'unread',
2090
                        'subject'       => 'S8',
2091
                        'timemodifier'  => 8,
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',
2100
                            'subject'           => '<p>S8</p>',
2101
                            'unreadcount'       => 1,
2102
                        ),
2103
                    ),
2104
                    'user2' => array(
2105
                        array(
2106
                            'messageposition'   => 0,
2107
                            'with'              => 'user1',
2108
                            'subject'           => '<p>S8</p>',
2109
                            'unreadcount'       => 3,
2110
                        ),
2111
                    ),
2112
                ),
2113
            ),
2114
        );
2115
    }
2116
 
2117
    /**
2118
     * Test that creation can't create the same conversation twice for 1:1 conversations.
2119
     */
11 efrain 2120
    public function test_create_conversation_duplicate_conversations(): void {
1 efrain 2121
        global $DB;
11 efrain 2122
        $this->resetAfterTest();
2123
 
1 efrain 2124
        $user1 = $this::getDataGenerator()->create_user();
2125
 
2126
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]);
2127
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_SELF, [$user1->id]);
2128
 
2129
        $convhash = helper::get_conversation_hash([$user1->id]);
2130
        $countconversations = $DB->count_records('message_conversations', ['convhash' => $convhash]);
2131
        $this->assertEquals(1, $countconversations);
2132
        $this->assertNotEmpty($conversation = api::get_self_conversation($user1->id));
2133
    }
2134
 
2135
    /**
2136
     * Test get_conversations with a mixture of messages.
2137
     *
2138
     * @dataProvider get_conversations_mixed_provider
2139
     * @param array $usersdata The list of users to create for this test.
2140
     * @param array $messagesdata The list of messages to create.
2141
     * @param array $expectations The list of expected outcomes.
2142
     */
11 efrain 2143
    public function test_get_conversations_mixed($usersdata, $contacts, $messagesdata, $expectations): void {
1 efrain 2144
        global $DB;
11 efrain 2145
        $this->resetAfterTest();
1 efrain 2146
 
11 efrain 2147
 
2148
        $this->redirectMessages();
2149
 
1 efrain 2150
        // Create all of the users.
2151
        $users = array();
2152
        foreach ($usersdata as $username) {
2153
            $users[$username] = $this->getDataGenerator()->create_user(array('username' => $username));
2154
        }
2155
 
2156
        foreach ($contacts as $username => $contact) {
2157
            foreach ($contact as $contactname => $blocked) {
2158
                $record = new \stdClass();
2159
                $record->userid     = $users[$username]->id;
2160
                $record->contactid  = $users[$contactname]->id;
2161
                $record->blocked    = $blocked;
2162
                $record->id = $DB->insert_record('message_contacts', $record);
2163
            }
2164
        }
2165
 
2166
        $defaulttimecreated = time();
2167
        foreach ($messagesdata as $messagedata) {
2168
            $from       = $users[$messagedata['from']];
2169
            $to         = $users[$messagedata['to']];
2170
            $subject    = $messagedata['subject'];
2171
 
2172
            if (isset($messagedata['state']) && $messagedata['state'] == 'unread') {
11 efrain 2173
                $messageid = testhelper::send_fake_message($from, $to, $subject);
1 efrain 2174
            } else {
2175
                // If there is no state, or the state is not 'unread', assume the message is read.
2176
                $messageid = message_post_message($from, $to, $subject, FORMAT_PLAIN);
2177
            }
2178
 
2179
            $updatemessage = new \stdClass();
2180
            $updatemessage->id = $messageid;
2181
            if (isset($messagedata['timecreated'])) {
2182
                $updatemessage->timecreated = $messagedata['timecreated'];
2183
            } else if (isset($messagedata['timemodifier'])) {
2184
                $updatemessage->timecreated = $defaulttimecreated + $messagedata['timemodifier'];
2185
            } else {
2186
                $updatemessage->timecreated = $defaulttimecreated;
2187
            }
2188
 
2189
            $DB->update_record('messages', $updatemessage);
2190
        }
2191
 
2192
        foreach ($expectations as $username => $data) {
2193
            // Get the recent conversations for the specified user.
2194
            $user = $users[$username];
2195
            $conversations = array_values(api::get_conversations($user->id));
2196
            foreach ($data as $expectation) {
2197
                $otheruser = $users[$expectation['with']];
2198
                $conversation = $conversations[$expectation['messageposition']];
2199
                $this->assertEquals($otheruser->id, $conversation->members[$otheruser->id]->id);
2200
                $this->assertEquals($expectation['subject'], $conversation->messages[0]->text);
2201
                $this->assertEquals($expectation['unreadcount'], $conversation->unreadcount);
2202
            }
2203
        }
2204
    }
2205
 
2206
    /**
2207
     * Tests retrieving user contacts.
2208
     */
11 efrain 2209
    public function test_get_user_contacts(): void {
2210
        $this->resetAfterTest();
2211
 
1 efrain 2212
        // Create some users.
2213
        $user1 = self::getDataGenerator()->create_user();
2214
 
2215
        // Set as the user.
2216
        $this->setUser($user1);
2217
 
2218
        $user2 = new \stdClass();
2219
        $user2->firstname = 'User';
2220
        $user2->lastname = 'A';
2221
        $user2 = self::getDataGenerator()->create_user($user2);
2222
 
2223
        $user3 = new \stdClass();
2224
        $user3->firstname = 'User';
2225
        $user3->lastname = 'B';
2226
        $user3 = self::getDataGenerator()->create_user($user3);
2227
 
2228
        $user4 = new \stdClass();
2229
        $user4->firstname = 'User';
2230
        $user4->lastname = 'C';
2231
        $user4 = self::getDataGenerator()->create_user($user4);
2232
 
2233
        $user5 = new \stdClass();
2234
        $user5->firstname = 'User';
2235
        $user5->lastname = 'D';
2236
        $user5 = self::getDataGenerator()->create_user($user5);
2237
 
2238
        // Add some users as contacts.
2239
        api::add_contact($user1->id, $user2->id);
2240
        api::add_contact($user1->id, $user3->id);
2241
        api::add_contact($user1->id, $user4->id);
2242
 
2243
        // Retrieve the contacts.
2244
        $contacts = api::get_user_contacts($user1->id);
2245
 
2246
        // Confirm the data is correct.
2247
        $this->assertEquals(3, count($contacts));
2248
 
2249
        ksort($contacts);
2250
 
2251
        $contact1 = array_shift($contacts);
2252
        $contact2 = array_shift($contacts);
2253
        $contact3 = array_shift($contacts);
2254
 
2255
        $this->assertEquals($user2->id, $contact1->id);
2256
        $this->assertEquals(fullname($user2), $contact1->fullname);
2257
        $this->assertTrue($contact1->iscontact);
2258
 
2259
        $this->assertEquals($user3->id, $contact2->id);
2260
        $this->assertEquals(fullname($user3), $contact2->fullname);
2261
        $this->assertTrue($contact2->iscontact);
2262
 
2263
        $this->assertEquals($user4->id, $contact3->id);
2264
        $this->assertEquals(fullname($user4), $contact3->fullname);
2265
        $this->assertTrue($contact3->iscontact);
2266
    }
2267
 
2268
    /**
2269
     * Tests retrieving conversation messages.
2270
     */
11 efrain 2271
    public function test_get_conversation_messages(): void {
2272
        $this->resetAfterTest();
2273
 
1 efrain 2274
        // Create some users.
2275
        $user1 = self::getDataGenerator()->create_user();
2276
        $user2 = self::getDataGenerator()->create_user();
2277
 
2278
        // Create conversation.
2279
        $conversation = api::create_conversation(
2280
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2281
            [$user1->id, $user2->id]
2282
        );
2283
 
2284
        // The person doing the search.
2285
        $this->setUser($user1);
2286
 
2287
        // Send some messages back and forth.
2288
        $time = 1;
2289
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2290
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2291
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2292
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2293
 
2294
        // Retrieve the messages.
2295
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id);
2296
 
2297
        // Confirm the conversation id is correct.
2298
        $this->assertEquals($conversation->id, $convmessages['id']);
2299
 
2300
        // Confirm the message data is correct.
2301
        $messages = $convmessages['messages'];
2302
        $this->assertEquals(4, count($messages));
2303
        $message1 = $messages[0];
2304
        $message2 = $messages[1];
2305
        $message3 = $messages[2];
2306
        $message4 = $messages[3];
2307
 
2308
        $this->assertEquals($user1->id, $message1->useridfrom);
2309
        $this->assertStringContainsString('Yo!', $message1->text);
2310
 
2311
        $this->assertEquals($user2->id, $message2->useridfrom);
2312
        $this->assertStringContainsString('Sup mang?', $message2->text);
2313
 
2314
        $this->assertEquals($user1->id, $message3->useridfrom);
2315
        $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text);
2316
 
2317
        $this->assertEquals($user1->id, $message4->useridfrom);
2318
        $this->assertStringContainsString('Word.', $message4->text);
2319
 
2320
        // Confirm the members data is correct.
2321
        $members = $convmessages['members'];
2322
        $this->assertEquals(2, count($members));
2323
    }
2324
 
2325
    /**
2326
     * Tests retrieving group conversation messages.
2327
     */
11 efrain 2328
    public function test_get_group_conversation_messages(): void {
2329
        $this->resetAfterTest();
2330
 
1 efrain 2331
        // Create some users.
2332
        $user1 = self::getDataGenerator()->create_user();
2333
        $user2 = self::getDataGenerator()->create_user();
2334
        $user3 = self::getDataGenerator()->create_user();
2335
        $user4 = self::getDataGenerator()->create_user();
2336
 
2337
        // Create group conversation.
2338
        $conversation = api::create_conversation(
2339
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2340
            [$user1->id, $user2->id, $user3->id, $user4->id]
2341
        );
2342
 
2343
        // The person doing the search.
2344
        $this->setUser($user1);
2345
 
2346
        // Send some messages back and forth.
2347
        $time = 1;
2348
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2349
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2350
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2351
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2352
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Yeah!', $time + 5);
2353
 
2354
        // Retrieve the messages.
2355
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id);
2356
 
2357
        // Confirm the conversation id is correct.
2358
        $this->assertEquals($conversation->id, $convmessages['id']);
2359
 
2360
        // Confirm the message data is correct.
2361
        $messages = $convmessages['messages'];
2362
        $this->assertEquals(5, count($messages));
2363
 
2364
        $message1 = $messages[0];
2365
        $message2 = $messages[1];
2366
        $message3 = $messages[2];
2367
        $message4 = $messages[3];
2368
        $message5 = $messages[4];
2369
 
2370
        $this->assertEquals($user1->id, $message1->useridfrom);
2371
        $this->assertStringContainsString('Yo!', $message1->text);
2372
 
2373
        $this->assertEquals($user2->id, $message2->useridfrom);
2374
        $this->assertStringContainsString('Sup mang?', $message2->text);
2375
 
2376
        $this->assertEquals($user3->id, $message3->useridfrom);
2377
        $this->assertStringContainsString('Writing PHPUnit tests!', $message3->text);
2378
 
2379
        $this->assertEquals($user1->id, $message4->useridfrom);
2380
        $this->assertStringContainsString('Word.', $message4->text);
2381
 
2382
        $this->assertEquals($user2->id, $message5->useridfrom);
2383
        $this->assertStringContainsString('Yeah!', $message5->text);
2384
 
2385
        // Confirm the members data is correct.
2386
        $members = $convmessages['members'];
2387
        $this->assertEquals(3, count($members));
2388
    }
2389
 
2390
    /**
2391
     * Test verifying the sorting param for get_conversation_messages is respected().
2392
     */
11 efrain 2393
    public function test_get_conversation_messages_sorting(): void {
2394
        $this->resetAfterTest();
2395
 
1 efrain 2396
        // Create some users.
2397
        $user1 = self::getDataGenerator()->create_user();
2398
        $user2 = self::getDataGenerator()->create_user();
2399
        $user3 = self::getDataGenerator()->create_user();
2400
 
2401
        // Create conversations - 1 group and 1 individual.
2402
        $conversation = api::create_conversation(
2403
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
2404
            [$user1->id, $user2->id]
2405
        );
2406
        $conversation2 = api::create_conversation(
2407
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2408
            [$user1->id, $user2->id, $user3->id]
2409
        );
2410
 
2411
        // Send some messages back and forth.
2412
        $time = 1;
2413
        $m1id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2414
        $m2id = testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2415
        $m3id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2416
        $m4id = testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Word.', $time + 4);
2417
 
2418
        $gm1id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Yo!', $time + 1);
2419
        $gm2id = testhelper::send_fake_message_to_conversation($user2, $conversation2->id, 'Sup mang?', $time + 2);
2420
        $gm3id = testhelper::send_fake_message_to_conversation($user3, $conversation2->id, 'Writing PHPUnit tests!', $time + 3);
2421
        $gm4id = testhelper::send_fake_message_to_conversation($user1, $conversation2->id, 'Word.', $time + 4);
2422
 
2423
        // The person doing the search.
2424
        $this->setUser($user1);
2425
 
2426
        // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2427
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id);
2428
        $messages = $convmessages['messages'];
2429
        $this->assertEquals($m1id, $messages[0]->id);
2430
        $this->assertEquals($m2id, $messages[1]->id);
2431
        $this->assertEquals($m3id, $messages[2]->id);
2432
        $this->assertEquals($m4id, $messages[3]->id);
2433
 
2434
        // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2435
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated DESC');
2436
        $messages = $convmessages['messages'];
2437
        $this->assertEquals($m1id, $messages[3]->id);
2438
        $this->assertEquals($m2id, $messages[2]->id);
2439
        $this->assertEquals($m3id, $messages[1]->id);
2440
        $this->assertEquals($m4id, $messages[0]->id);
2441
 
2442
        // Retrieve the messages using default sort ('timecreated ASC') and verify ordering.
2443
        $convmessages = api::get_conversation_messages($user1->id, $conversation2->id);
2444
        $messages = $convmessages['messages'];
2445
        $this->assertEquals($gm1id, $messages[0]->id);
2446
        $this->assertEquals($gm2id, $messages[1]->id);
2447
        $this->assertEquals($gm3id, $messages[2]->id);
2448
        $this->assertEquals($gm4id, $messages[3]->id);
2449
 
2450
        // Retrieve the messages without specifying DESC sort ordering, and verify ordering.
2451
        $convmessages = api::get_conversation_messages($user1->id, $conversation2->id, 0, 0, 'timecreated DESC');
2452
        $messages = $convmessages['messages'];
2453
        $this->assertEquals($gm1id, $messages[3]->id);
2454
        $this->assertEquals($gm2id, $messages[2]->id);
2455
        $this->assertEquals($gm3id, $messages[1]->id);
2456
        $this->assertEquals($gm4id, $messages[0]->id);
2457
    }
2458
 
2459
    /**
2460
     * Test retrieving conversation messages by providing a minimum timecreated value.
2461
     */
11 efrain 2462
    public function test_get_conversation_messages_time_from_only(): void {
2463
        $this->resetAfterTest();
2464
 
1 efrain 2465
        // Create some users.
2466
        $user1 = self::getDataGenerator()->create_user();
2467
        $user2 = self::getDataGenerator()->create_user();
2468
        $user3 = self::getDataGenerator()->create_user();
2469
        $user4 = self::getDataGenerator()->create_user();
2470
 
2471
        // Create group conversation.
2472
        $conversation = api::create_conversation(
2473
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2474
            [$user1->id, $user2->id, $user3->id, $user4->id]
2475
        );
2476
 
2477
        // The person doing the search.
2478
        $this->setUser($user1);
2479
 
2480
        // Send some messages back and forth.
2481
        $time = 1;
2482
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2483
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2484
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2485
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2486
 
2487
        // Retrieve the messages from $time, which should be all of them.
2488
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC', $time);
2489
 
2490
        // Confirm the conversation id is correct.
2491
        $this->assertEquals($conversation->id, $convmessages['id']);
2492
 
2493
        // Confirm the message data is correct.
2494
        $messages = $convmessages['messages'];
2495
        $this->assertEquals(4, count($messages));
2496
 
2497
        $message1 = $messages[0];
2498
        $message2 = $messages[1];
2499
        $message3 = $messages[2];
2500
        $message4 = $messages[3];
2501
 
2502
        $this->assertStringContainsString('Message 1', $message1->text);
2503
        $this->assertStringContainsString('Message 2', $message2->text);
2504
        $this->assertStringContainsString('Message 3', $message3->text);
2505
        $this->assertStringContainsString('Message 4', $message4->text);
2506
 
2507
        // Confirm the members data is correct.
2508
        $members = $convmessages['members'];
2509
        $this->assertEquals(3, count($members));
2510
 
2511
        // Retrieve the messages from $time + 3, which should only be the 2 last messages.
2512
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2513
            'timecreated ASC', $time + 3);
2514
 
2515
        // Confirm the conversation id is correct.
2516
        $this->assertEquals($conversation->id, $convmessages['id']);
2517
 
2518
        // Confirm the message data is correct.
2519
        $messages = $convmessages['messages'];
2520
        $this->assertEquals(2, count($messages));
2521
 
2522
        $message1 = $messages[0];
2523
        $message2 = $messages[1];
2524
 
2525
        $this->assertStringContainsString('Message 3', $message1->text);
2526
        $this->assertStringContainsString('Message 4', $message2->text);
2527
 
2528
        // Confirm the members data is correct.
2529
        $members = $convmessages['members'];
2530
        $this->assertEquals(2, count($members));
2531
    }
2532
 
2533
    /**
2534
     * Test retrieving conversation messages by providing a maximum timecreated value.
2535
     */
11 efrain 2536
    public function test_get_conversation_messages_time_to_only(): void {
2537
        $this->resetAfterTest();
2538
 
1 efrain 2539
        // Create some users.
2540
        $user1 = self::getDataGenerator()->create_user();
2541
        $user2 = self::getDataGenerator()->create_user();
2542
        $user3 = self::getDataGenerator()->create_user();
2543
        $user4 = self::getDataGenerator()->create_user();
2544
 
2545
        // Create group conversation.
2546
        $conversation = api::create_conversation(
2547
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2548
            [$user1->id, $user2->id, $user3->id, $user4->id]
2549
        );
2550
 
2551
        // The person doing the search.
2552
        $this->setUser($user1);
2553
 
2554
        // Send some messages back and forth.
2555
        $time = 1;
2556
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2557
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2558
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2559
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2560
 
2561
        // Retrieve the messages up until $time + 4, which should be all of them.
2562
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2563
            0, $time + 4);
2564
 
2565
        // Confirm the conversation id is correct.
2566
        $this->assertEquals($conversation->id, $convmessages['id']);
2567
 
2568
        // Confirm the message data is correct.
2569
        $messages = $convmessages['messages'];
2570
        $this->assertEquals(4, count($messages));
2571
 
2572
        $message1 = $messages[0];
2573
        $message2 = $messages[1];
2574
        $message3 = $messages[2];
2575
        $message4 = $messages[3];
2576
 
2577
        $this->assertStringContainsString('Message 1', $message1->text);
2578
        $this->assertStringContainsString('Message 2', $message2->text);
2579
        $this->assertStringContainsString('Message 3', $message3->text);
2580
        $this->assertStringContainsString('Message 4', $message4->text);
2581
 
2582
        // Confirm the members data is correct.
2583
        $members = $convmessages['members'];
2584
        $this->assertEquals(3, count($members));
2585
 
2586
        // Retrieve the messages up until $time + 2, which should be the first two.
2587
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, 'timecreated ASC',
2588
            0, $time + 2);
2589
 
2590
        // Confirm the conversation id is correct.
2591
        $this->assertEquals($conversation->id, $convmessages['id']);
2592
 
2593
        // Confirm the message data is correct.
2594
        $messages = $convmessages['messages'];
2595
        $this->assertEquals(2, count($messages));
2596
 
2597
        $message1 = $messages[0];
2598
        $message2 = $messages[1];
2599
 
2600
        $this->assertStringContainsString('Message 1', $message1->text);
2601
        $this->assertStringContainsString('Message 2', $message2->text);
2602
 
2603
        // Confirm the members data is correct.
2604
        $members = $convmessages['members'];
2605
        $this->assertEquals(2, count($members));
2606
    }
2607
 
2608
    /**
2609
     * Test retrieving conversation messages by providing a minimum and maximum timecreated value.
2610
     */
11 efrain 2611
    public function test_get_conversation_messages_time_from_and_to(): void {
2612
        $this->resetAfterTest();
2613
 
1 efrain 2614
        // Create some users.
2615
        $user1 = self::getDataGenerator()->create_user();
2616
        $user2 = self::getDataGenerator()->create_user();
2617
        $user3 = self::getDataGenerator()->create_user();
2618
        $user4 = self::getDataGenerator()->create_user();
2619
 
2620
        // Create group conversation.
2621
        $conversation = api::create_conversation(
2622
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2623
            [$user1->id, $user2->id, $user3->id, $user4->id]
2624
        );
2625
 
2626
        // The person doing the search.
2627
        $this->setUser($user1);
2628
 
2629
        // Send some messages back and forth.
2630
        $time = 1;
2631
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2632
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2633
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2634
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2635
 
2636
        // Retrieve the messages from $time + 2 up until $time + 3, which should be 2nd and 3rd message.
2637
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0,
2638
            'timecreated ASC', $time + 2, $time + 3);
2639
 
2640
        // Confirm the conversation id is correct.
2641
        $this->assertEquals($conversation->id, $convmessages['id']);
2642
 
2643
        // Confirm the message data is correct.
2644
        $messages = $convmessages['messages'];
2645
        $this->assertEquals(2, count($messages));
2646
 
2647
        $message1 = $messages[0];
2648
        $message2 = $messages[1];
2649
 
2650
        $this->assertStringContainsString('Message 2', $message1->text);
2651
        $this->assertStringContainsString('Message 3', $message2->text);
2652
 
2653
        // Confirm the members data is correct.
2654
        $members = $convmessages['members'];
2655
        $this->assertEquals(2, count($members));
2656
    }
2657
 
2658
 
2659
    /**
2660
     * Test retrieving conversation messages by providing a limitfrom value.
2661
     */
11 efrain 2662
    public function test_get_conversation_messages_limitfrom_only(): void {
2663
        $this->resetAfterTest();
2664
 
1 efrain 2665
        // Create some users.
2666
        $user1 = self::getDataGenerator()->create_user();
2667
        $user2 = self::getDataGenerator()->create_user();
2668
        $user3 = self::getDataGenerator()->create_user();
2669
        $user4 = self::getDataGenerator()->create_user();
2670
 
2671
        // Create group conversation.
2672
        $conversation = api::create_conversation(
2673
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2674
            [$user1->id, $user2->id, $user3->id, $user4->id]
2675
        );
2676
 
2677
        // The person doing the search.
2678
        $this->setUser($user1);
2679
 
2680
        // Send some messages back and forth.
2681
        $time = 1;
2682
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2683
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2684
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2685
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2686
 
2687
        // Retrieve the messages from $time, which should be all of them.
2688
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 2);
2689
 
2690
        // Confirm the conversation id is correct.
2691
        $messages = $convmessages['messages'];
2692
        $this->assertEquals($conversation->id, $convmessages['id']);
2693
 
2694
        // Confirm the message data is correct.
2695
        $this->assertEquals(2, count($messages));
2696
 
2697
        $message1 = $messages[0];
2698
        $message2 = $messages[1];
2699
 
2700
        $this->assertStringContainsString('Message 3', $message1->text);
2701
        $this->assertStringContainsString('Message 4', $message2->text);
2702
 
2703
        // Confirm the members data is correct.
2704
        $members = $convmessages['members'];
2705
        $this->assertEquals(2, count($members));
2706
    }
2707
 
2708
    /**
2709
     * Test retrieving conversation messages by providing a limitnum value.
2710
     */
11 efrain 2711
    public function test_get_conversation_messages_limitnum(): void {
2712
        $this->resetAfterTest();
2713
 
1 efrain 2714
        // Create some users.
2715
        $user1 = self::getDataGenerator()->create_user();
2716
        $user2 = self::getDataGenerator()->create_user();
2717
        $user3 = self::getDataGenerator()->create_user();
2718
        $user4 = self::getDataGenerator()->create_user();
2719
 
2720
        // Create group conversation.
2721
        $conversation = api::create_conversation(
2722
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2723
            [$user1->id, $user2->id, $user3->id, $user4->id]
2724
        );
2725
 
2726
        // The person doing the search.
2727
        $this->setUser($user1);
2728
 
2729
        // Send some messages back and forth.
2730
        $time = 1;
2731
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
2732
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
2733
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
2734
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
2735
 
2736
        // Retrieve the messages from $time, which should be all of them.
2737
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 2, 1);
2738
 
2739
        // Confirm the conversation id is correct.
2740
        $messages = $convmessages['messages'];
2741
        $this->assertEquals($conversation->id, $convmessages['id']);
2742
 
2743
        // Confirm the message data is correct.
2744
        $messages = $convmessages['messages'];
2745
        $this->assertEquals(1, count($messages));
2746
 
2747
        $message1 = $messages[0];
2748
 
2749
        $this->assertStringContainsString('Message 3', $message1->text);
2750
 
2751
        // Confirm the members data is correct.
2752
        $members = $convmessages['members'];
2753
        $this->assertEquals(1, count($members));
2754
    }
2755
 
2756
    /**
2757
     * Tests retrieving most recent conversation message.
2758
     */
11 efrain 2759
    public function test_get_most_recent_conversation_message(): void {
2760
        $this->resetAfterTest();
2761
 
1 efrain 2762
        // Create some users.
2763
        $user1 = self::getDataGenerator()->create_user();
2764
        $user2 = self::getDataGenerator()->create_user();
2765
        $user3 = self::getDataGenerator()->create_user();
2766
 
2767
        // Create group conversation.
2768
        $conversation = api::create_conversation(
2769
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
2770
            [$user1->id, $user2->id, $user3->id]
2771
        );
2772
 
2773
        // The person getting the most recent conversation message.
2774
        $this->setUser($user1);
2775
 
2776
        // Send some messages back and forth.
2777
        $time = 1;
2778
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Yo!', $time + 1);
2779
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Sup mang?', $time + 2);
2780
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Writing PHPUnit tests!', $time + 3);
2781
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Word.', $time + 4);
2782
 
2783
        // Retrieve the most recent messages.
2784
        $message = api::get_most_recent_conversation_message($conversation->id, $user1->id);
2785
 
2786
        // Check the results are correct.
2787
        $this->assertEquals($user2->id, $message->useridfrom);
2788
        $this->assertStringContainsString('Word.', $message->text);
2789
    }
2790
 
2791
    /**
2792
     * Tests checking if a user can mark all messages as read.
2793
     */
11 efrain 2794
    public function test_can_mark_all_messages_as_read(): void {
2795
        $this->resetAfterTest();
2796
 
1 efrain 2797
        // Set as the admin.
2798
        $this->setAdminUser();
2799
 
2800
        // Create some users.
2801
        $user1 = self::getDataGenerator()->create_user();
2802
        $user2 = self::getDataGenerator()->create_user();
2803
        $user3 = self::getDataGenerator()->create_user();
2804
 
2805
        // Send some messages back and forth.
2806
        $time = 1;
11 efrain 2807
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2808
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2809
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2810
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 2811
 
2812
        $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]);
2813
 
2814
        // The admin can do anything.
2815
        $this->assertTrue(api::can_mark_all_messages_as_read($user1->id, $conversationid));
2816
 
2817
        // Set as the user 1.
2818
        $this->setUser($user1);
2819
 
2820
        // The user can mark the messages as he is in the conversation.
2821
        $this->assertTrue(api::can_mark_all_messages_as_read($user1->id, $conversationid));
2822
 
2823
        // User 1 can not mark the messages read for user 2.
2824
        $this->assertFalse(api::can_mark_all_messages_as_read($user2->id, $conversationid));
2825
 
2826
        // This user is not a part of the conversation.
2827
        $this->assertFalse(api::can_mark_all_messages_as_read($user3->id, $conversationid));
2828
    }
2829
 
2830
    /**
2831
     * Tests checking if a user can delete a conversation.
2832
     */
11 efrain 2833
    public function test_can_delete_conversation(): void {
2834
        $this->resetAfterTest();
2835
 
1 efrain 2836
        // Set as the admin.
2837
        $this->setAdminUser();
2838
 
2839
        // Create some users.
2840
        $user1 = self::getDataGenerator()->create_user();
2841
        $user2 = self::getDataGenerator()->create_user();
2842
 
2843
        // Send some messages back and forth.
2844
        $time = 1;
11 efrain 2845
        testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2846
        testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2847
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2848
        testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 2849
 
2850
        $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]);
2851
 
2852
        // The admin can do anything.
2853
        $this->assertTrue(api::can_delete_conversation($user1->id, $conversationid));
2854
 
2855
        // Set as the user 1.
2856
        $this->setUser($user1);
2857
 
2858
        // They can delete their own messages.
2859
        $this->assertTrue(api::can_delete_conversation($user1->id, $conversationid));
2860
 
2861
        // They can't delete someone elses.
2862
        $this->assertFalse(api::can_delete_conversation($user2->id, $conversationid));
2863
    }
2864
 
2865
    /**
2866
     * Tests deleting a conversation by conversation id.
2867
     */
11 efrain 2868
    public function test_delete_conversation_by_id(): void {
1 efrain 2869
        global $DB;
11 efrain 2870
        $this->resetAfterTest();
1 efrain 2871
 
11 efrain 2872
 
1 efrain 2873
        // Create some users.
2874
        $user1 = self::getDataGenerator()->create_user();
2875
        $user2 = self::getDataGenerator()->create_user();
2876
 
2877
        // The person doing the search.
2878
        $this->setUser($user1);
2879
 
2880
        // Get self-conversation.
2881
        $sc1 = api::get_self_conversation($user1->id);
2882
        $sc2 = api::get_self_conversation($user2->id);
2883
 
2884
        // Send some messages back and forth.
2885
        $time = 1;
11 efrain 2886
        $m1id = testhelper::send_fake_message($user1, $user2, 'Yo!', 0, $time + 1);
2887
        $m2id = testhelper::send_fake_message($user2, $user1, 'Sup mang?', 0, $time + 2);
2888
        $m3id = testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!', 0, $time + 3);
2889
        $m4id = testhelper::send_fake_message($user2, $user1, 'Word.', 0, $time + 4);
1 efrain 2890
        $m5id = testhelper::send_fake_message_to_conversation($user1, $sc1->id, 'Hi to myself!', $time + 5);
2891
        $m6id = testhelper::send_fake_message_to_conversation($user2, $sc2->id, 'I am talking with myself', $time + 6);
2892
 
2893
        $conversationid = api::get_conversation_between_users([$user1->id, $user2->id]);
2894
 
2895
        // Delete the individual conversation between user1 and user2 (only for user1).
2896
        api::delete_conversation_by_id($user1->id, $conversationid);
2897
 
2898
        $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2899
        $this->assertCount(4, $muas);
2900
        // Sort by id.
2901
        ksort($muas);
2902
 
2903
        $mua1 = array_shift($muas);
2904
        $mua2 = array_shift($muas);
2905
        $mua3 = array_shift($muas);
2906
        $mua4 = array_shift($muas);
2907
 
2908
        $this->assertEquals($user1->id, $mua1->userid);
2909
        $this->assertEquals($m1id, $mua1->messageid);
2910
        $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua1->action);
2911
 
2912
        $this->assertEquals($user1->id, $mua2->userid);
2913
        $this->assertEquals($m2id, $mua2->messageid);
2914
        $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua2->action);
2915
 
2916
        $this->assertEquals($user1->id, $mua3->userid);
2917
        $this->assertEquals($m3id, $mua3->messageid);
2918
        $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua3->action);
2919
 
2920
        $this->assertEquals($user1->id, $mua4->userid);
2921
        $this->assertEquals($m4id, $mua4->messageid);
2922
        $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua4->action);
2923
 
2924
        // Delete the self-conversation as user 1.
2925
        api::delete_conversation_by_id($user1->id, $sc1->id);
2926
 
2927
        $muas = $DB->get_records('message_user_actions', array(), 'timecreated ASC');
2928
        $this->assertCount(5, $muas);
2929
 
2930
        // Sort by id.
2931
        ksort($muas);
2932
 
2933
        $mua1 = array_shift($muas);
2934
        $mua2 = array_shift($muas);
2935
        $mua3 = array_shift($muas);
2936
        $mua4 = array_shift($muas);
2937
        $mua5 = array_shift($muas);
2938
 
2939
        // Check only messages in self-conversion for user1 are deleted (self-conversation for user2 shouldn't be removed).
2940
        $this->assertEquals($user1->id, $mua5->userid);
2941
        $this->assertEquals($m5id, $mua5->messageid);
2942
        $this->assertEquals(api::MESSAGE_ACTION_DELETED, $mua5->action);
2943
    }
2944
 
2945
    /**
2946
     * Tests counting unread conversations.
2947
     */
11 efrain 2948
    public function test_count_unread_conversations(): void {
1 efrain 2949
        $this->resetAfterTest(true);
2950
 
2951
        // Create some users.
2952
        $user1 = self::getDataGenerator()->create_user();
2953
        $user2 = self::getDataGenerator()->create_user();
2954
        $user3 = self::getDataGenerator()->create_user();
2955
        $user4 = self::getDataGenerator()->create_user();
2956
 
2957
        // The person wanting the conversation count.
2958
        $this->setUser($user1);
2959
 
2960
        // Send some messages back and forth, have some different conversations with different users.
11 efrain 2961
        testhelper::send_fake_message($user1, $user2, 'Yo!');
2962
        testhelper::send_fake_message($user2, $user1, 'Sup mang?');
2963
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
2964
        testhelper::send_fake_message($user2, $user1, 'Word.');
1 efrain 2965
 
11 efrain 2966
        testhelper::send_fake_message($user1, $user3, 'Booyah');
2967
        testhelper::send_fake_message($user3, $user1, 'Whaaat?');
2968
        testhelper::send_fake_message($user1, $user3, 'Nothing.');
2969
        testhelper::send_fake_message($user3, $user1, 'Cool.');
1 efrain 2970
 
11 efrain 2971
        testhelper::send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
2972
        testhelper::send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
2973
        testhelper::send_fake_message($user1, $user4, 'Dope.');
1 efrain 2974
 
2975
        // Check the amount for the current user.
2976
        $this->assertEquals(3, api::count_unread_conversations());
2977
 
2978
        // Check the amount for the second user.
2979
        $this->assertEquals(1, api::count_unread_conversations($user2));
2980
    }
2981
 
2982
    /**
2983
     * Tests counting unread conversations where one conversation is disabled.
2984
     */
11 efrain 2985
    public function test_count_unread_conversations_disabled(): void {
1 efrain 2986
        $this->resetAfterTest(true);
2987
 
2988
        // Create some users.
2989
        $user1 = self::getDataGenerator()->create_user();
2990
        $user2 = self::getDataGenerator()->create_user();
2991
        $user3 = self::getDataGenerator()->create_user();
2992
        $user4 = self::getDataGenerator()->create_user();
2993
 
2994
        // The person wanting the conversation count.
2995
        $this->setUser($user1);
2996
 
2997
        // Send some messages back and forth, have some different conversations with different users.
11 efrain 2998
        testhelper::send_fake_message($user1, $user2, 'Yo!');
2999
        testhelper::send_fake_message($user2, $user1, 'Sup mang?');
3000
        testhelper::send_fake_message($user1, $user2, 'Writing PHPUnit tests!');
3001
        testhelper::send_fake_message($user2, $user1, 'Word.');
1 efrain 3002
 
11 efrain 3003
        testhelper::send_fake_message($user1, $user3, 'Booyah');
3004
        testhelper::send_fake_message($user3, $user1, 'Whaaat?');
3005
        testhelper::send_fake_message($user1, $user3, 'Nothing.');
3006
        testhelper::send_fake_message($user3, $user1, 'Cool.');
1 efrain 3007
 
11 efrain 3008
        testhelper::send_fake_message($user1, $user4, 'Hey mate, you see the new messaging UI in Moodle?');
3009
        testhelper::send_fake_message($user4, $user1, 'Yah brah, it\'s pretty rad.');
3010
        testhelper::send_fake_message($user1, $user4, 'Dope.');
1 efrain 3011
 
3012
        // Let's disable the last conversation.
3013
        $conversationid = api::get_conversation_between_users([$user1->id, $user4->id]);
3014
        api::disable_conversation($conversationid);
3015
 
3016
        // Check that the disabled conversation was not included.
3017
        $this->assertEquals(2, api::count_unread_conversations());
3018
    }
3019
 
3020
    /**
3021
     * Tests deleting a conversation.
3022
     */
11 efrain 3023
    public function test_get_all_message_preferences(): void {
3024
        $this->resetAfterTest();
3025
 
1 efrain 3026
        $user = self::getDataGenerator()->create_user();
3027
        $this->setUser($user);
3028
 
3029
        // Set a couple of preferences to test.
3030
        set_user_preference('message_provider_mod_assign_assign_notification_enabled', 'popup', $user);
3031
        set_user_preference('message_provider_mod_feedback_submission_enabled', 'email', $user);
3032
 
3033
        $processors = get_message_processors();
3034
        $providers = message_get_providers_for_user($user->id);
3035
        $prefs = api::get_all_message_preferences($processors, $providers, $user);
3036
 
3037
        $this->assertEquals(1, $prefs->mod_assign_assign_notification_enabled['popup']);
3038
        $this->assertEquals(1, $prefs->mod_feedback_submission_enabled['email']);
3039
    }
3040
 
3041
    /**
3042
     * Tests the user can send a message.
3043
     */
11 efrain 3044
    public function test_can_send_message(): void {
3045
        $this->resetAfterTest();
3046
 
1 efrain 3047
        // Create some users.
3048
        $user1 = self::getDataGenerator()->create_user();
3049
        $user2 = self::getDataGenerator()->create_user();
3050
 
3051
        // Set as the first user.
3052
        $this->setUser($user1);
3053
 
3054
        // With the default privacy setting, users can't message them.
3055
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3056
 
3057
        // Enrol users to the same course.
3058
        $course = $this->getDataGenerator()->create_course();
3059
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3060
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3061
        // After enrolling users to the course, they should be able to message them with the default privacy setting.
3062
        $this->assertTrue(api::can_send_message($user2->id, $user1->id));
3063
    }
3064
 
3065
    /**
3066
     * Tests the user can't send a message without proper capability.
3067
     */
11 efrain 3068
    public function test_can_send_message_without_sendmessage_cap(): void {
1 efrain 3069
        global $DB;
11 efrain 3070
        $this->resetAfterTest();
1 efrain 3071
 
11 efrain 3072
 
1 efrain 3073
        // Create some users.
3074
        $user1 = self::getDataGenerator()->create_user();
3075
        $user2 = self::getDataGenerator()->create_user();
3076
 
3077
        // Set as the user 1.
3078
        $this->setUser($user1);
3079
 
3080
        // Remove the capability to send a message.
3081
        $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3082
        unassign_capability('moodle/site:sendmessage', $roleids['user'],
3083
            \context_system::instance());
3084
 
3085
        // Check that we can not post a message without the capability.
3086
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3087
    }
3088
 
3089
    /**
3090
     * Tests the user can send a message when they are contact.
3091
     */
11 efrain 3092
    public function test_can_send_message_when_contact(): void {
3093
        $this->resetAfterTest();
3094
 
1 efrain 3095
        // Create some users.
3096
        $user1 = self::getDataGenerator()->create_user();
3097
        $user2 = self::getDataGenerator()->create_user();
3098
 
3099
        // Set as the first user.
3100
        $this->setUser($user1);
3101
 
3102
        // Check that we can not send user2 a message.
3103
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3104
 
3105
        // Add users as contacts.
3106
        api::add_contact($user1->id, $user2->id);
3107
 
3108
        // Check that the return result is now true.
3109
        $this->assertTrue(api::can_send_message($user2->id, $user1->id));
3110
    }
3111
 
3112
    /**
3113
     * Tests the user can't send a message if they are not a contact and the user
3114
     * has requested messages only from contacts.
3115
     */
11 efrain 3116
    public function test_can_send_message_when_not_contact(): void {
3117
        $this->resetAfterTest();
3118
 
1 efrain 3119
        // Create some users.
3120
        $user1 = self::getDataGenerator()->create_user();
3121
        $user2 = self::getDataGenerator()->create_user();
3122
 
3123
        // Set as the first user.
3124
        $this->setUser($user1);
3125
 
3126
        // Set the second user's preference to not receive messages from non-contacts.
3127
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3128
 
3129
        // Check that we can not send user 2 a message.
3130
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3131
    }
3132
 
3133
    /**
3134
     * Tests the user can't send a message if they are blocked.
3135
     */
11 efrain 3136
    public function test_can_send_message_when_blocked(): void {
3137
        $this->resetAfterTest();
3138
 
1 efrain 3139
        // Create some users.
3140
        $user1 = self::getDataGenerator()->create_user();
3141
        $user2 = self::getDataGenerator()->create_user();
3142
 
3143
        // Set the user.
3144
        $this->setUser($user1);
3145
 
3146
        // Block the second user.
3147
        api::block_user($user1->id, $user2->id);
3148
 
3149
        // Check that the second user can no longer send the first user a message.
3150
        $this->assertFalse(api::can_send_message($user1->id, $user2->id));
3151
    }
3152
 
3153
    /**
3154
     * Tests the user can send a message when site-wide messaging setting is enabled,
3155
     * even if they are not a contact and are not members of the same course.
3156
     */
11 efrain 3157
    public function test_can_send_message_site_messaging_setting(): void {
3158
        $this->resetAfterTest();
3159
 
1 efrain 3160
        // Create some users.
3161
        $user1 = self::getDataGenerator()->create_user();
3162
        $user2 = self::getDataGenerator()->create_user();
3163
 
3164
        // Set as the first user.
3165
        $this->setUser($user1);
3166
 
3167
        // By default, user only can be messaged by contacts and members of any of his/her courses.
3168
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3169
 
3170
        // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3171
        set_config('messagingallusers', true);
3172
 
3173
        // Set the second user's preference to receive messages from everybody.
3174
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user2->id);
3175
 
3176
        // Check that we can send user2 a message.
3177
        $this->assertTrue(api::can_send_message($user2->id, $user1->id));
3178
 
3179
        // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3180
        // and members sharing a course with her.
3181
        set_config('messagingallusers', false);
3182
 
3183
        // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3184
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3185
 
3186
        // Enrol users to the same course.
3187
        $course = $this->getDataGenerator()->create_course();
3188
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3189
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3190
        // Check that we can send user2 a message because they are sharing a course.
3191
        $this->assertTrue(api::can_send_message($user2->id, $user1->id));
3192
 
3193
        // Set the second user's preference to receive messages only from contacts.
3194
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3195
        // Check that now the user2 can't be contacted because user1 is not their contact.
3196
        $this->assertFalse(api::can_send_message($user2->id, $user1->id));
3197
 
3198
        // Make contacts user1 and user2.
3199
        api::add_contact($user2->id, $user1->id);
3200
        // Check that we can send user2 a message because they are contacts.
3201
        $this->assertTrue(api::can_send_message($user2->id, $user1->id));
3202
    }
3203
 
3204
    /**
3205
     * Tests the user with the messageanyuser capability can send a message.
3206
     */
11 efrain 3207
    public function test_can_send_message_with_messageanyuser_cap(): void {
1 efrain 3208
        global $DB;
11 efrain 3209
        $this->resetAfterTest();
1 efrain 3210
 
11 efrain 3211
 
1 efrain 3212
        // Create some users.
3213
        $teacher1 = self::getDataGenerator()->create_user();
3214
        $student1 = self::getDataGenerator()->create_user();
3215
        $student2 = self::getDataGenerator()->create_user();
3216
 
3217
        // Create users not enrolled in any course.
3218
        $user1 = self::getDataGenerator()->create_user();
3219
 
3220
        // Create a course.
3221
        $course1 = $this->getDataGenerator()->create_course();
3222
 
3223
        // Enrol the users in the course.
3224
        $this->getDataGenerator()->enrol_user($teacher1->id, $course1->id, 'editingteacher');
3225
        $this->getDataGenerator()->enrol_user($student1->id, $course1->id, 'student');
3226
        $this->getDataGenerator()->enrol_user($student2->id, $course1->id, 'student');
3227
 
3228
        // Set some student preferences to not receive messages from non-contacts.
3229
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $student1->id);
3230
 
3231
        // Check that we can send student1 a message because teacher has the messageanyuser cap by default.
3232
        $this->assertTrue(api::can_send_message($student1->id, $teacher1->id));
3233
 
3234
        // Check that the teacher can't contact user1 because it's not his teacher.
3235
        $this->assertFalse(api::can_send_message($user1->id, $teacher1->id));
3236
 
3237
        // Remove the messageanyuser capability from the course1 for teachers.
3238
        $coursecontext = \context_course::instance($course1->id);
3239
        $teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher']);
3240
        assign_capability('moodle/site:messageanyuser', CAP_PROHIBIT, $teacherrole->id, $coursecontext->id);
3241
        $coursecontext->mark_dirty();
3242
 
3243
        // Check that we can't send user1 a message because they are not contacts.
3244
        $this->assertFalse(api::can_send_message($student1->id, $teacher1->id));
3245
 
3246
        // However, teacher can message student2 because they are sharing a course.
3247
        $this->assertTrue(api::can_send_message($student2->id, $teacher1->id));
3248
    }
3249
 
3250
    /**
3251
     * Tests the user when blocked will not be able to send messages if they are blocked.
3252
     */
11 efrain 3253
    public function test_can_send_message_even_if_blocked(): void {
1 efrain 3254
        $this->resetAfterTest();
3255
 
3256
        $user1 = self::getDataGenerator()->create_user();
3257
        $user2 = self::getDataGenerator()->create_user();
3258
 
3259
        $this->assertFalse(api::can_send_message($user2->id, $user1->id, true));
3260
    }
3261
 
3262
    /**
3263
     * Tests the user will be able to send a message even if they are blocked as the user
3264
     * has the capability 'moodle/site:messageanyuser'.
3265
     */
11 efrain 3266
    public function test_can_send_message_even_if_blocked_with_message_any_user_cap(): void {
1 efrain 3267
        global $DB;
3268
 
3269
        $this->resetAfterTest();
3270
 
3271
        $user1 = self::getDataGenerator()->create_user();
3272
        $user2 = self::getDataGenerator()->create_user();
3273
 
3274
        $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user'));
3275
        assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduserrole->id, \context_system::instance(), true);
3276
 
3277
        $this->assertTrue(api::can_send_message($user2->id, $user1->id, true));
3278
    }
3279
 
3280
    /**
3281
     * Tests the user will be able to send a message even if they are blocked as the user
3282
     * has the capability 'moodle/site:readallmessages'.
3283
     */
11 efrain 3284
    public function test_can_send_message_even_if_blocked_with_read_all_message_cap(): void {
1 efrain 3285
        global $DB;
3286
 
3287
        $this->resetAfterTest();
3288
 
3289
        $user1 = self::getDataGenerator()->create_user();
3290
        $user2 = self::getDataGenerator()->create_user();
3291
 
3292
        $authenticateduserrole = $DB->get_record('role', array('shortname' => 'user'));
3293
        assign_capability('moodle/site:readallmessages', CAP_ALLOW, $authenticateduserrole->id, \context_system::instance(), true);
3294
 
3295
        $this->assertTrue(api::can_send_message($user2->id, $user1->id, true));
3296
    }
3297
 
3298
    /**
3299
     * Tests the user can not always send a message if they are blocked just because they share a course.
3300
     */
11 efrain 3301
    public function test_can_send_message_even_if_blocked_shared_course(): void {
1 efrain 3302
        $this->resetAfterTest();
3303
 
3304
        // Create some users.
3305
        $user1 = self::getDataGenerator()->create_user();
3306
        $user2 = self::getDataGenerator()->create_user();
3307
 
3308
        $course = self::getDataGenerator()->create_course();
3309
 
3310
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3311
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3312
 
3313
        $this->assertFalse(api::can_send_message($user2->id, $user1->id, true));
3314
    }
3315
 
3316
    /**
3317
     * Tests the user can always send a message even if they are blocked because they share a course and
3318
     * have the capability 'moodle/site:messageanyuser' at the course context.
3319
     */
11 efrain 3320
    public function test_can_send_message_even_if_blocked_shared_course_with_message_any_user_cap(): void {
1 efrain 3321
        global $DB;
3322
 
3323
        $this->resetAfterTest();
3324
 
3325
        $editingteacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
3326
 
3327
        $teacher = self::getDataGenerator()->create_user();
3328
        $student = self::getDataGenerator()->create_user();
3329
 
3330
        $course = self::getDataGenerator()->create_course();
3331
 
3332
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $editingteacherrole->id);
3333
        $this->getDataGenerator()->enrol_user($student->id, $course->id);
3334
 
3335
        assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $editingteacherrole->id,
3336
            \context_course::instance($course->id), true);
3337
 
3338
        // Check that the second user can no longer send the first user a message.
3339
        $this->assertTrue(api::can_send_message($student->id, $teacher->id, true));
3340
    }
3341
 
3342
    /**
3343
     * Verify the expected behaviour of the can_send_message_to_conversation() method for authenticated users with default settings.
3344
     */
11 efrain 3345
    public function test_can_send_message_to_conversation_basic(): void {
3346
        $this->resetAfterTest();
3347
 
1 efrain 3348
        // Create some users.
3349
        $user1 = self::getDataGenerator()->create_user();
3350
        $user2 = self::getDataGenerator()->create_user();
3351
        $user3 = self::getDataGenerator()->create_user();
3352
 
3353
        // Create an individual conversation between user1 and user2.
3354
        $ic1 = api::create_conversation(
3355
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3356
            [
3357
                $user1->id,
3358
                $user2->id
3359
            ]
3360
        );
3361
 
3362
        // Create a group conversation between and users 1, 2 and 3.
3363
        $gc1 = api::create_conversation(
3364
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3365
            [
3366
                $user1->id,
3367
                $user2->id,
3368
                $user3->id
3369
            ]
3370
        );
3371
 
3372
        // Get a self-conversation for user1.
3373
        $sc1 = api::get_self_conversation($user1->id);
3374
 
3375
        // For group conversations, there are no user privacy checks, so only membership in the conversation is needed.
3376
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3377
 
3378
        // For self conversations, there are no user privacy checks, so only membership in the conversation is needed.
3379
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $sc1->id));
3380
 
3381
        // For individual conversations, the default privacy setting of 'only contacts and course members' applies.
3382
        // Users are not in the same course, nor are they contacts, so messages cannot be sent.
3383
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3384
 
3385
        // Enrol the users into the same course.
3386
        $course = $this->getDataGenerator()->create_course();
3387
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3388
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3389
 
3390
        // After enrolling users to the course, they should be able to message them with the default privacy setting.
3391
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3392
    }
3393
 
3394
    /**
3395
     * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the sendmessage capability.
3396
     */
11 efrain 3397
    public function test_can_send_message_to_conversation_sendmessage_cap(): void {
1 efrain 3398
        global $DB;
11 efrain 3399
        $this->resetAfterTest();
1 efrain 3400
 
11 efrain 3401
 
1 efrain 3402
        $user1 = self::getDataGenerator()->create_user();
3403
        $user2 = self::getDataGenerator()->create_user();
3404
        $user3 = self::getDataGenerator()->create_user();
3405
 
3406
        // Enrol the users into the same course.
3407
        $course = $this->getDataGenerator()->create_course();
3408
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3409
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3410
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3411
 
3412
        // Create an individual conversation between user1 and user2.
3413
        $ic1 = api::create_conversation(
3414
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3415
            [
3416
                $user1->id,
3417
                $user2->id
3418
            ]
3419
        );
3420
 
3421
        // Group conversation between and users 1, 2 and 3.
3422
        $gc1 = api::create_conversation(
3423
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3424
            [
3425
                $user1->id,
3426
                $user2->id,
3427
                $user3->id
3428
            ]
3429
        );
3430
 
3431
        // Default settings - user1 can send a message to both conversations.
3432
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3433
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3434
 
3435
        // Remove the capability to send a message.
3436
        $roleids = $DB->get_records_menu('role', null, '', 'shortname, id');
3437
        unassign_capability('moodle/site:sendmessage', $roleids['user'], \context_system::instance());
3438
 
3439
        // Verify that a user cannot send a message to either an individual or a group conversation.
3440
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3441
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $gc1->id));
3442
    }
3443
 
3444
    /**
3445
     * Verify the behaviour of can_send_message_to_conversation() for authenticated users without the messageanyuser capability.
3446
     */
11 efrain 3447
    public function test_can_send_message_to_conversation_messageanyuser_cap(): void {
1 efrain 3448
        global $DB;
11 efrain 3449
        $this->resetAfterTest();
1 efrain 3450
 
11 efrain 3451
 
1 efrain 3452
        $user1 = self::getDataGenerator()->create_user();
3453
        $user2 = self::getDataGenerator()->create_user();
3454
        $user3 = self::getDataGenerator()->create_user();
3455
 
3456
        // Enrol the users into the same course.
3457
        $course = $this->getDataGenerator()->create_course();
3458
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3459
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3460
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3461
 
3462
        // Create an individual conversation between user1 and user2.
3463
        $ic1 = api::create_conversation(
3464
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3465
            [
3466
                $user1->id,
3467
                $user2->id
3468
            ]
3469
        );
3470
 
3471
        // Group conversation between and users 1, 2 and 3.
3472
        $gc1 = api::create_conversation(
3473
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3474
            [
3475
                $user1->id,
3476
                $user2->id,
3477
                $user3->id
3478
            ]
3479
        );
3480
 
3481
        // Update the message preference for user2, so they can only be messaged by contacts.
3482
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3483
 
3484
        // Verify that the user cannot be contacted in the individual conversation and that groups are unaffected.
3485
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3486
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3487
 
3488
        // Assign the 'messageanyuser' capability to user1 at system context.
3489
        $systemcontext = \context_system::instance();
3490
        $authenticateduser = $DB->get_record('role', ['shortname' => 'user']);
3491
        assign_capability('moodle/site:messageanyuser', CAP_ALLOW, $authenticateduser->id, $systemcontext->id);
3492
 
3493
        // Check that user1 can now message user2 due to the capability, and that group conversations is again unaffected.
3494
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3495
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3496
    }
3497
 
3498
    /**
3499
     * Test verifying that users cannot send messages to conversations they are not a part of.
3500
     */
11 efrain 3501
    public function test_can_send_message_to_conversation_non_member(): void {
3502
        $this->resetAfterTest();
3503
 
1 efrain 3504
        // Create some users.
3505
        $user1 = self::getDataGenerator()->create_user();
3506
        $user2 = self::getDataGenerator()->create_user();
3507
        $user3 = self::getDataGenerator()->create_user();
3508
        $user4 = self::getDataGenerator()->create_user();
3509
 
3510
        // Enrol the users into the same course.
3511
        $course = $this->getDataGenerator()->create_course();
3512
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3513
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3514
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3515
        $this->getDataGenerator()->enrol_user($user4->id, $course->id);
3516
 
3517
        // Create an individual conversation between user1 and user2.
3518
        $ic1 = api::create_conversation(
3519
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3520
            [
3521
                $user1->id,
3522
                $user2->id
3523
            ]
3524
        );
3525
 
3526
        // Create a group conversation between and users 1, 2 and 3.
3527
        $gc1 = api::create_conversation(
3528
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3529
            [
3530
                $user1->id,
3531
                $user2->id,
3532
                $user3->id
3533
            ]
3534
        );
3535
 
3536
        // Get a self-conversation for user1.
3537
        $sc1 = api::get_self_conversation($user1->id);
3538
 
3539
        // Verify, non members cannot send a message.
3540
        $this->assertFalse(api::can_send_message_to_conversation($user4->id, $gc1->id));
3541
        $this->assertFalse(api::can_send_message_to_conversation($user4->id, $ic1->id));
3542
        $this->assertFalse(api::can_send_message_to_conversation($user4->id, $sc1->id));
3543
    }
3544
 
3545
    /**
3546
     * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts only.
3547
     */
11 efrain 3548
    public function test_can_send_message_to_conversation_privacy_contacts_only(): void {
3549
        $this->resetAfterTest();
3550
 
1 efrain 3551
        // Create some users.
3552
        $user1 = self::getDataGenerator()->create_user();
3553
        $user2 = self::getDataGenerator()->create_user();
3554
        $user3 = self::getDataGenerator()->create_user();
3555
 
3556
        // Create an individual conversation between user1 and user2.
3557
        $ic1 = api::create_conversation(
3558
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3559
            [
3560
                $user1->id,
3561
                $user2->id
3562
            ]
3563
        );
3564
 
3565
        // Create a group conversation between and users 1, 2 and 3.
3566
        $gc1 = api::create_conversation(
3567
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3568
            [
3569
                $user1->id,
3570
                $user2->id,
3571
                $user3->id
3572
            ]
3573
        );
3574
 
3575
        // Set the message privacy preference to 'contacts only' for user 2.
3576
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3577
 
3578
        // Verify that user1 cannot send a message to the individual conversation, but that the group conversation is unaffected.
3579
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3580
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3581
 
3582
        // Now, simulate a contact request (and approval) between user1 and user2.
3583
        api::create_contact_request($user1->id, $user2->id);
3584
        api::confirm_contact_request($user1->id, $user2->id);
3585
 
3586
        // Verify user1 can now message user2 again via their individual conversation.
3587
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3588
    }
3589
 
3590
    /**
3591
     * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to contacts / course members.
3592
     */
11 efrain 3593
    public function test_can_send_message_to_conversation_privacy_contacts_course(): void {
3594
        $this->resetAfterTest();
3595
 
1 efrain 3596
        // Create some users.
3597
        $user1 = self::getDataGenerator()->create_user();
3598
        $user2 = self::getDataGenerator()->create_user();
3599
        $user3 = self::getDataGenerator()->create_user();
3600
 
3601
        // Set the message privacy preference to 'contacts + course members' for user 2.
3602
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_COURSEMEMBER, $user2->id);
3603
 
3604
        // Create an individual conversation between user1 and user2.
3605
        $ic1 = api::create_conversation(
3606
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3607
            [
3608
                $user1->id,
3609
                $user2->id
3610
            ]
3611
        );
3612
 
3613
        // Create a group conversation between and users 1, 2 and 3.
3614
        $gc1 = api::create_conversation(
3615
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3616
            [
3617
                $user1->id,
3618
                $user2->id,
3619
                $user3->id
3620
            ]
3621
        );
3622
 
3623
        // Verify that users in a group conversation can message one another (i.e. privacy controls ignored).
3624
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3625
 
3626
        // Verify that user1 can not message user2 unless they are either contacts, or share a course.
3627
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3628
 
3629
        // Enrol the users into the same course.
3630
        $course = $this->getDataGenerator()->create_course();
3631
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3632
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3633
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3634
 
3635
        // Verify that user1 can send a message to user2, based on the shared course, without being a contact.
3636
        $this->assertFalse(api::is_contact($user1->id, $user2->id));
3637
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3638
    }
3639
 
3640
    /**
3641
     * Test verifying the behaviour of the can_send_message_to_conversation method when privacy is set to any user.
3642
     */
11 efrain 3643
    public function test_can_send_message_to_conversation_privacy_sitewide(): void {
3644
        $this->resetAfterTest();
3645
 
1 efrain 3646
        // Create some users.
3647
        $user1 = self::getDataGenerator()->create_user();
3648
        $user2 = self::getDataGenerator()->create_user();
3649
        $user3 = self::getDataGenerator()->create_user();
3650
 
3651
        // Create an individual conversation between user1 and user2.
3652
        $ic1 = api::create_conversation(
3653
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3654
            [
3655
                $user1->id,
3656
                $user2->id
3657
            ]
3658
        );
3659
 
3660
        // Create a group conversation between and users 1, 2 and 3.
3661
        $gc1 = api::create_conversation(
3662
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3663
            [
3664
                $user1->id,
3665
                $user2->id,
3666
                $user3->id
3667
            ]
3668
        );
3669
 
3670
        // By default, the messaging privacy dictates that users can only be contacted by contacts, and members of their courses.
3671
        // Verify also, that groups are not restricted in this way.
3672
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3673
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3674
 
3675
        // Enable site-wide messagging privacy setting.
3676
        // This enables a privacy option for users, allowing them to choose to be contactable by anybody on the site.
3677
        set_config('messagingallusers', true);
3678
 
3679
        // Set the second user's preference to receive messages from everybody.
3680
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user2->id);
3681
 
3682
        // Check that user1 can send user2 a message, and that the group conversation is unaffected.
3683
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $ic1->id));
3684
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3685
 
3686
        // Disable site-wide messagging privacy setting. The user will be able to receive messages from contacts
3687
        // and members sharing a course with her.
3688
        set_config('messagingallusers', false);
3689
 
3690
        // As site-wide messaging setting is disabled, the value for user2 will be changed to MESSAGE_PRIVACY_COURSEMEMBER.
3691
        // Verify also that the group conversation is unaffected.
3692
        $this->assertFalse(api::can_send_message_to_conversation($user1->id, $ic1->id));
3693
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3694
    }
3695
 
3696
    /**
3697
     * Test verifying the behaviour of the can_send_message_to_conversation method when a user is blocked.
3698
     */
11 efrain 3699
    public function test_can_send_message_to_conversation_when_blocked(): void {
3700
        $this->resetAfterTest();
3701
 
1 efrain 3702
        $user1 = self::getDataGenerator()->create_user();
3703
        $user2 = self::getDataGenerator()->create_user();
3704
        $user3 = self::getDataGenerator()->create_user();
3705
 
3706
        // Create an individual conversation between user1 and user2.
3707
        $ic1 = api::create_conversation(
3708
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
3709
            [
3710
                $user1->id,
3711
                $user2->id
3712
            ]
3713
        );
3714
 
3715
        // Create a group conversation between and users 1, 2 and 3.
3716
        $gc1 = api::create_conversation(
3717
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
3718
            [
3719
                $user1->id,
3720
                $user2->id,
3721
                $user3->id
3722
            ]
3723
        );
3724
 
3725
        // Enrol the users into the same course.
3726
        $course = $this->getDataGenerator()->create_course();
3727
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
3728
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
3729
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
3730
 
3731
        // Block the second user.
3732
        api::block_user($user1->id, $user2->id);
3733
 
3734
        // Check that user2 can not send user1 a message in their individual conversation.
3735
        $this->assertFalse(api::can_send_message_to_conversation($user2->id, $ic1->id));
3736
 
3737
        // Verify that group conversations are unaffected.
3738
        $this->assertTrue(api::can_send_message_to_conversation($user1->id, $gc1->id));
3739
        $this->assertTrue(api::can_send_message_to_conversation($user2->id, $gc1->id));
3740
    }
3741
 
3742
    /**
3743
     * Tests get_user_privacy_messaging_preference method.
3744
     */
11 efrain 3745
    public function test_get_user_privacy_messaging_preference(): void {
3746
        $this->resetAfterTest();
3747
 
1 efrain 3748
        // Create some users.
3749
        $user1 = self::getDataGenerator()->create_user();
3750
        $user2 = self::getDataGenerator()->create_user();
3751
        $user3 = self::getDataGenerator()->create_user();
3752
 
3753
        // Enable site-wide messagging privacy setting. The user will be able to receive messages from everybody.
3754
        set_config('messagingallusers', true);
3755
 
3756
        // Set some user preferences.
3757
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_SITE, $user1->id);
3758
        set_user_preference('message_blocknoncontacts', api::MESSAGE_PRIVACY_ONLYCONTACTS, $user2->id);
3759
 
3760
        // Check the returned value for each user.
3761
        $this->assertEquals(
3762
            api::MESSAGE_PRIVACY_SITE,
3763
            api::get_user_privacy_messaging_preference($user1->id)
3764
        );
3765
        $this->assertEquals(
3766
            api::MESSAGE_PRIVACY_ONLYCONTACTS,
3767
            api::get_user_privacy_messaging_preference($user2->id)
3768
        );
3769
        $this->assertEquals(
3770
            api::MESSAGE_PRIVACY_SITE,
3771
            api::get_user_privacy_messaging_preference($user3->id)
3772
        );
3773
 
3774
        // Disable site-wide messagging privacy setting. The user will be able to receive messages from members of their course.
3775
        set_config('messagingallusers', false);
3776
 
3777
        // Check the returned value for each user.
3778
        $this->assertEquals(
3779
            api::MESSAGE_PRIVACY_COURSEMEMBER,
3780
            api::get_user_privacy_messaging_preference($user1->id)
3781
        );
3782
        $this->assertEquals(
3783
            api::MESSAGE_PRIVACY_ONLYCONTACTS,
3784
            api::get_user_privacy_messaging_preference($user2->id)
3785
        );
3786
        $this->assertEquals(
3787
            api::MESSAGE_PRIVACY_COURSEMEMBER,
3788
            api::get_user_privacy_messaging_preference($user3->id)
3789
        );
3790
    }
3791
 
3792
    /*
3793
     * Tes get_message_processor api.
3794
     */
11 efrain 3795
    public function test_get_message_processor(): void {
3796
        $this->resetAfterTest();
3797
 
1 efrain 3798
        $processors = get_message_processors(true);
3799
        if (empty($processors)) {
3800
            $this->markTestSkipped("No message processors found");
3801
        }
3802
 
3803
        $name = key($processors);
3804
        $processor = current($processors);
3805
        $testprocessor = api::get_message_processor($name);
3806
        $this->assertEquals($processor->name, $testprocessor->name);
3807
        $this->assertEquals($processor->enabled, $testprocessor->enabled);
3808
        $this->assertEquals($processor->available, $testprocessor->available);
3809
        $this->assertEquals($processor->configured, $testprocessor->configured);
3810
 
3811
        // Disable processor and test.
3812
        api::update_processor_status($testprocessor, 0);
3813
        $testprocessor = api::get_message_processor($name, true);
3814
        $this->assertEmpty($testprocessor);
3815
        $testprocessor = api::get_message_processor($name);
3816
        $this->assertEquals($processor->name, $testprocessor->name);
3817
        $this->assertEquals(0, $testprocessor->enabled);
3818
 
3819
        // Enable again and test.
3820
        api::update_processor_status($testprocessor, 1);
3821
        $testprocessor = api::get_message_processor($name, true);
3822
        $this->assertEquals($processor->name, $testprocessor->name);
3823
        $this->assertEquals(1, $testprocessor->enabled);
3824
        $testprocessor = api::get_message_processor($name);
3825
        $this->assertEquals($processor->name, $testprocessor->name);
3826
        $this->assertEquals(1, $testprocessor->enabled);
3827
    }
3828
 
3829
    /**
3830
     * Test method update_processor_status.
3831
     */
11 efrain 3832
    public function test_update_processor_status(): void {
3833
        $this->resetAfterTest();
3834
 
1 efrain 3835
        $processors = get_message_processors();
3836
        if (empty($processors)) {
3837
            $this->markTestSkipped("No message processors found");
3838
        }
3839
        $name = key($processors);
3840
        $testprocessor = current($processors);
3841
 
3842
        // Enable.
3843
        api::update_processor_status($testprocessor, 1);
3844
        $testprocessor = api::get_message_processor($name);
3845
        $this->assertEquals(1, $testprocessor->enabled);
3846
 
3847
        // Disable.
3848
        api::update_processor_status($testprocessor, 0);
3849
        $testprocessor = api::get_message_processor($name);
3850
        $this->assertEquals(0, $testprocessor->enabled);
3851
 
3852
        // Enable again.
3853
        api::update_processor_status($testprocessor, 1);
3854
        $testprocessor = api::get_message_processor($name);
3855
        $this->assertEquals(1, $testprocessor->enabled);
3856
    }
3857
 
3858
    /**
3859
     * Test method is_user_enabled.
3860
     */
3861
    public function is_user_enabled() {
3862
        $processors = get_message_processors();
3863
        if (empty($processors)) {
3864
            $this->markTestSkipped("No message processors found");
3865
        }
3866
        $name = key($processors);
3867
        $testprocessor = current($processors);
3868
 
3869
        // Enable.
3870
        api::update_processor_status($testprocessor, 1);
3871
        $status = api::is_processor_enabled($name);
3872
        $this->assertEquals(1, $status);
3873
 
3874
        // Disable.
3875
        api::update_processor_status($testprocessor, 0);
3876
        $status = api::is_processor_enabled($name);
3877
        $this->assertEquals(0, $status);
3878
 
3879
        // Enable again.
3880
        api::update_processor_status($testprocessor, 1);
3881
        $status = api::is_processor_enabled($name);
3882
        $this->assertEquals(1, $status);
3883
    }
3884
 
3885
    /**
3886
     * Test returning blocked users.
3887
     */
11 efrain 3888
    public function test_get_blocked_users(): void {
1 efrain 3889
        global $USER;
11 efrain 3890
        $this->resetAfterTest();
1 efrain 3891
 
11 efrain 3892
 
1 efrain 3893
        // Set this user as the admin.
3894
        $this->setAdminUser();
3895
 
3896
        // Create a user to add to the admin's contact list.
3897
        $user1 = $this->getDataGenerator()->create_user();
3898
        $user2 = $this->getDataGenerator()->create_user();
3899
 
3900
        // Add users to the admin's contact list.
3901
        api::block_user($USER->id, $user2->id);
3902
 
3903
        $this->assertCount(1, api::get_blocked_users($USER->id));
3904
 
3905
        // Block other user.
3906
        api::block_user($USER->id, $user1->id);
3907
        $this->assertCount(2, api::get_blocked_users($USER->id));
3908
 
3909
        // Test deleting users.
3910
        delete_user($user1);
3911
        $this->assertCount(1, api::get_blocked_users($USER->id));
3912
    }
3913
 
3914
    /**
3915
     * Test marking a message as read.
3916
     */
11 efrain 3917
    public function test_mark_message_as_read(): void {
1 efrain 3918
        global $DB;
11 efrain 3919
        $this->resetAfterTest();
1 efrain 3920
 
3921
        $user1 = self::getDataGenerator()->create_user();
3922
        $user2 = self::getDataGenerator()->create_user();
3923
 
11 efrain 3924
        testhelper::send_fake_message($user1, $user2);
3925
        $m2id = testhelper::send_fake_message($user1, $user2);
3926
        testhelper::send_fake_message($user2, $user1);
3927
        $m4id = testhelper::send_fake_message($user2, $user1);
1 efrain 3928
 
3929
        $m2 = $DB->get_record('messages', ['id' => $m2id]);
3930
        $m4 = $DB->get_record('messages', ['id' => $m4id]);
3931
        api::mark_message_as_read($user2->id, $m2, 11);
3932
        api::mark_message_as_read($user1->id, $m4, 12);
3933
 
3934
        // Confirm there are two user actions.
3935
        $muas = $DB->get_records('message_user_actions', [], 'timecreated ASC');
3936
        $this->assertEquals(2, count($muas));
3937
 
3938
        // Confirm they are correct.
3939
        $mua1 = array_shift($muas);
3940
        $mua2 = array_shift($muas);
3941
 
3942
        // Confirm first action.
3943
        $this->assertEquals($user2->id, $mua1->userid);
3944
        $this->assertEquals($m2id, $mua1->messageid);
3945
        $this->assertEquals(api::MESSAGE_ACTION_READ, $mua1->action);
3946
        $this->assertEquals(11, $mua1->timecreated);
3947
 
3948
        // Confirm second action.
3949
        $this->assertEquals($user1->id, $mua2->userid);
3950
        $this->assertEquals($m4id, $mua2->messageid);
3951
        $this->assertEquals(api::MESSAGE_ACTION_READ, $mua2->action);
3952
        $this->assertEquals(12, $mua2->timecreated);
3953
    }
3954
 
3955
    /**
3956
     * Test marking a notification as read.
3957
     */
11 efrain 3958
    public function test_mark_notification_as_read(): void {
1 efrain 3959
        global $DB;
11 efrain 3960
        $this->resetAfterTest();
1 efrain 3961
 
3962
        $user1 = self::getDataGenerator()->create_user();
3963
        $user2 = self::getDataGenerator()->create_user();
3964
 
11 efrain 3965
        testhelper::send_fake_message($user1, $user2, 'Notification 1', 1);
3966
        $n2id = testhelper::send_fake_message($user1, $user2, 'Notification 2', 1);
3967
        testhelper::send_fake_message($user2, $user1, 'Notification 3', 1);
3968
        $n4id = testhelper::send_fake_message($user2, $user1, 'Notification 4', 1);
1 efrain 3969
 
3970
        $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3971
        $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3972
 
3973
        api::mark_notification_as_read($n2, 11);
3974
        api::mark_notification_as_read($n4, 12);
3975
 
3976
        // Retrieve the notifications.
3977
        $n2 = $DB->get_record('notifications', ['id' => $n2id]);
3978
        $n4 = $DB->get_record('notifications', ['id' => $n4id]);
3979
 
3980
        // Confirm they have been marked as read.
3981
        $this->assertEquals(11, $n2->timeread);
3982
        $this->assertEquals(12, $n4->timeread);
3983
    }
3984
 
3985
    /**
3986
     * Test a conversation is not returned if there is none.
3987
     */
11 efrain 3988
    public function test_get_conversation_between_users_no_conversation(): void {
3989
        $this->resetAfterTest();
3990
 
1 efrain 3991
        $user1 = self::getDataGenerator()->create_user();
3992
        $user2 = self::getDataGenerator()->create_user();
3993
 
3994
        $this->assertFalse(api::get_conversation_between_users([$user1->id, $user2->id]));
3995
    }
3996
 
3997
    /**
3998
     * Test count_conversation_members for non existing conversation.
3999
     */
11 efrain 4000
    public function test_count_conversation_members_no_existing_conversation(): void {
4001
        $this->resetAfterTest();
4002
 
4003
        $this->assertEquals(
4004
            0,
4005
            api::count_conversation_members(0)
4006
        );
1 efrain 4007
    }
4008
 
4009
    /**
4010
     * Test count_conversation_members for existing conversation.
4011
     */
11 efrain 4012
    public function test_count_conversation_members_existing_conversation(): void {
4013
        $this->resetAfterTest();
4014
 
1 efrain 4015
        $user1 = self::getDataGenerator()->create_user();
4016
        $user2 = self::getDataGenerator()->create_user();
4017
 
4018
        $conversation = api::create_conversation(
4019
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4020
            [
4021
                $user1->id,
4022
                $user2->id
4023
            ]
4024
        );
4025
        $conversationid = $conversation->id;
4026
 
4027
        $this->assertEquals(2,
4028
            api::count_conversation_members($conversationid));
4029
    }
4030
 
4031
    /**
4032
     * Test add_members_to_conversation for an individual conversation.
4033
     */
11 efrain 4034
    public function test_add_members_to_individual_conversation(): void {
4035
        $this->resetAfterTest();
4036
 
1 efrain 4037
        $user1 = self::getDataGenerator()->create_user();
4038
        $user2 = self::getDataGenerator()->create_user();
4039
        $user3 = self::getDataGenerator()->create_user();
4040
 
4041
        $conversation = api::create_conversation(
4042
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4043
            [
4044
                $user1->id,
4045
                $user2->id
4046
            ]
4047
        );
4048
        $conversationid = $conversation->id;
4049
 
4050
        $this->expectException('moodle_exception');
4051
        api::add_members_to_conversation([$user3->id], $conversationid);
4052
    }
4053
 
4054
    /**
4055
     * Test add_members_to_conversation for existing conversation.
4056
     */
11 efrain 4057
    public function test_add_members_to_existing_conversation(): void {
4058
        $this->resetAfterTest();
4059
 
1 efrain 4060
        $user1 = self::getDataGenerator()->create_user();
4061
        $user2 = self::getDataGenerator()->create_user();
4062
        $user3 = self::getDataGenerator()->create_user();
4063
 
4064
        $conversation = api::create_conversation(
4065
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4066
            [
4067
                $user1->id,
4068
                $user2->id
4069
            ]
4070
        );
4071
        $conversationid = $conversation->id;
4072
 
4073
        $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid));
4074
        $this->assertEquals(3,
4075
            api::count_conversation_members($conversationid));
4076
    }
4077
 
4078
    /**
4079
     * Test add_members_to_conversation for non existing conversation.
4080
     */
11 efrain 4081
    public function test_add_members_to_no_existing_conversation(): void {
4082
        $this->resetAfterTest();
4083
 
1 efrain 4084
        $user1 = self::getDataGenerator()->create_user();
4085
 
4086
        // Throw dml_missing_record_exception for non existing conversation.
4087
        $this->expectException('dml_missing_record_exception');
4088
        api::add_members_to_conversation([$user1->id], 0);
4089
    }
4090
 
4091
    /**
4092
     * Test add_member_to_conversation for non existing user.
4093
     */
11 efrain 4094
    public function test_add_members_to_no_existing_user(): void {
4095
        $this->resetAfterTest();
4096
 
1 efrain 4097
        $user1 = self::getDataGenerator()->create_user();
4098
        $user2 = self::getDataGenerator()->create_user();
4099
 
4100
        $conversation = api::create_conversation(
4101
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4102
            [
4103
                $user1->id,
4104
                $user2->id
4105
            ]
4106
        );
4107
        $conversationid = $conversation->id;
4108
 
4109
        // Don't throw an error for non existing user, but don't add it as a member.
4110
        $this->assertNull(api::add_members_to_conversation([0], $conversationid));
4111
        $this->assertEquals(2,
4112
            api::count_conversation_members($conversationid));
4113
    }
4114
 
4115
    /**
4116
     * Test add_members_to_conversation for current conversation member.
4117
     */
11 efrain 4118
    public function test_add_members_to_current_conversation_member(): void {
4119
        $this->resetAfterTest();
4120
 
1 efrain 4121
        $user1 = self::getDataGenerator()->create_user();
4122
        $user2 = self::getDataGenerator()->create_user();
4123
 
4124
        $conversation = api::create_conversation(
4125
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4126
            [
4127
                $user1->id,
4128
                $user2->id
4129
            ]
4130
        );
4131
        $conversationid = $conversation->id;
4132
 
4133
        // Don't add as a member a user that is already conversation member.
4134
        $this->assertNull(api::add_members_to_conversation([$user1->id], $conversationid));
4135
        $this->assertEquals(2,
4136
            api::count_conversation_members($conversationid));
4137
    }
4138
 
4139
    /**
4140
     * Test add_members_to_conversation for multiple users.
4141
     */
11 efrain 4142
    public function test_add_members_for_multiple_users(): void {
4143
        $this->resetAfterTest();
4144
 
1 efrain 4145
        $user1 = self::getDataGenerator()->create_user();
4146
        $user2 = self::getDataGenerator()->create_user();
4147
        $user3 = self::getDataGenerator()->create_user();
4148
        $user4 = self::getDataGenerator()->create_user();
4149
 
4150
        $conversation = api::create_conversation(
4151
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4152
            [
4153
                $user1->id,
4154
                $user2->id
4155
            ]
4156
        );
4157
        $conversationid = $conversation->id;
4158
 
4159
        $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
4160
        $this->assertEquals(4,
4161
            api::count_conversation_members($conversationid));
4162
    }
4163
 
4164
    /**
4165
     * Test add_members_to_conversation for multiple users, included non existing and current conversation members
4166
     */
11 efrain 4167
    public function test_add_members_for_multiple_not_valid_users(): void {
4168
        $this->resetAfterTest();
4169
 
1 efrain 4170
        $user1 = self::getDataGenerator()->create_user();
4171
        $user2 = self::getDataGenerator()->create_user();
4172
        $user3 = self::getDataGenerator()->create_user();
4173
 
4174
        $conversation = api::create_conversation(
4175
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4176
            [
4177
                $user1->id,
4178
                $user2->id
4179
            ]
4180
        );
4181
        $conversationid = $conversation->id;
4182
 
4183
        // Don't throw errors, but don't add as members users don't exist or are already conversation members.
4184
        $this->assertNull(api::add_members_to_conversation([$user3->id, $user1->id, 0], $conversationid));
4185
        $this->assertEquals(3,
4186
            api::count_conversation_members($conversationid));
4187
    }
4188
 
4189
    /**
4190
     * Test remove_members_from_conversation for individual conversation.
4191
     */
11 efrain 4192
    public function test_remove_members_from_individual_conversation(): void {
4193
        $this->resetAfterTest();
4194
 
1 efrain 4195
        $user1 = self::getDataGenerator()->create_user();
4196
        $user2 = self::getDataGenerator()->create_user();
4197
 
4198
        $conversation = api::create_conversation(
4199
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4200
            [
4201
                $user1->id,
4202
                $user2->id
4203
            ]
4204
        );
4205
        $conversationid = $conversation->id;
4206
 
4207
        $this->expectException('moodle_exception');
4208
        api::remove_members_from_conversation([$user1->id], $conversationid);
4209
    }
4210
 
4211
    /**
4212
     * Test remove_members_from_conversation for existing conversation.
4213
     */
11 efrain 4214
    public function test_remove_members_from_existing_conversation(): void {
4215
        $this->resetAfterTest();
4216
 
1 efrain 4217
        $user1 = self::getDataGenerator()->create_user();
4218
        $user2 = self::getDataGenerator()->create_user();
4219
 
4220
        $conversation = api::create_conversation(
4221
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4222
            [
4223
                $user1->id,
4224
                $user2->id
4225
            ]
4226
        );
4227
        $conversationid = $conversation->id;
4228
 
4229
        $this->assertNull(api::remove_members_from_conversation([$user1->id], $conversationid));
4230
        $this->assertEquals(1,
4231
            api::count_conversation_members($conversationid));
4232
    }
4233
 
4234
    /**
4235
     * Test remove_members_from_conversation for non existing conversation.
4236
     */
11 efrain 4237
    public function test_remove_members_from_no_existing_conversation(): void {
4238
        $this->resetAfterTest();
4239
 
1 efrain 4240
        $user1 = self::getDataGenerator()->create_user();
4241
 
4242
        // Throw dml_missing_record_exception for non existing conversation.
4243
        $this->expectException('dml_missing_record_exception');
4244
        api::remove_members_from_conversation([$user1->id], 0);
4245
    }
4246
 
4247
    /**
4248
     * Test remove_members_from_conversation for non existing user.
4249
     */
11 efrain 4250
    public function test_remove_members_for_no_existing_user(): void {
4251
        $this->resetAfterTest();
4252
 
1 efrain 4253
        $user1 = self::getDataGenerator()->create_user();
4254
        $user2 = self::getDataGenerator()->create_user();
4255
 
4256
        $conversation = api::create_conversation(
4257
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4258
            [
4259
                $user1->id,
4260
                $user2->id
4261
            ]
4262
        );
4263
        $conversationid = $conversation->id;
4264
 
4265
        $this->assertNull(api::remove_members_from_conversation([0], $conversationid));
4266
        $this->assertEquals(2,
4267
            api::count_conversation_members($conversationid));
4268
    }
4269
 
4270
    /**
4271
     * Test remove_members_from_conversation for multiple users.
4272
     */
11 efrain 4273
    public function test_remove_members_for_multiple_users(): void {
4274
        $this->resetAfterTest();
4275
 
1 efrain 4276
        $user1 = self::getDataGenerator()->create_user();
4277
        $user2 = self::getDataGenerator()->create_user();
4278
        $user3 = self::getDataGenerator()->create_user();
4279
        $user4 = self::getDataGenerator()->create_user();
4280
 
4281
        $conversation = api::create_conversation(
4282
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4283
            [
4284
                $user1->id,
4285
                $user2->id
4286
            ]
4287
        );
4288
        $conversationid = $conversation->id;
4289
 
4290
        $this->assertNull(api::add_members_to_conversation([$user3->id, $user4->id], $conversationid));
4291
        $this->assertNull(api::remove_members_from_conversation([$user3->id, $user4->id], $conversationid));
4292
        $this->assertEquals(2,
4293
            api::count_conversation_members($conversationid));
4294
    }
4295
 
4296
    /**
4297
     * Test remove_members_from_conversation for multiple non valid users.
4298
     */
11 efrain 4299
    public function test_remove_members_for_multiple_no_valid_users(): void {
4300
        $this->resetAfterTest();
4301
 
1 efrain 4302
        $user1 = self::getDataGenerator()->create_user();
4303
        $user2 = self::getDataGenerator()->create_user();
4304
        $user3 = self::getDataGenerator()->create_user();
4305
        $user4 = self::getDataGenerator()->create_user();
4306
 
4307
        $conversation = api::create_conversation(
4308
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4309
            [
4310
                $user1->id,
4311
                $user2->id
4312
            ]
4313
        );
4314
        $conversationid = $conversation->id;
4315
 
4316
        $this->assertNull(api::add_members_to_conversation([$user3->id], $conversationid));
4317
        $this->assertNull(
4318
            api::remove_members_from_conversation([$user2->id, $user3->id, $user4->id, 0], $conversationid)
4319
        );
4320
        $this->assertEquals(1,
4321
            api::count_conversation_members($conversationid));
4322
    }
4323
 
4324
    /**
4325
     * Test count_conversation_members for empty conversation.
4326
     */
11 efrain 4327
    public function test_count_conversation_members_empty_conversation(): void {
4328
        $this->resetAfterTest();
4329
 
1 efrain 4330
        $user1 = self::getDataGenerator()->create_user();
4331
        $user2 = self::getDataGenerator()->create_user();
4332
 
4333
        $conversation = api::create_conversation(
4334
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4335
            [
4336
                $user1->id,
4337
                $user2->id
4338
            ]
4339
        );
4340
        $conversationid = $conversation->id;
4341
 
4342
        $this->assertNull(api::remove_members_from_conversation([$user1->id, $user2->id], $conversationid));
4343
 
4344
        $this->assertEquals(0,
4345
            api::count_conversation_members($conversationid));
4346
    }
4347
 
4348
    /**
4349
     * Test can create a contact request.
4350
     */
11 efrain 4351
    public function test_can_create_contact_request(): void {
1 efrain 4352
        global $CFG;
11 efrain 4353
        $this->resetAfterTest();
1 efrain 4354
 
4355
        $user1 = self::getDataGenerator()->create_user();
4356
        $user2 = self::getDataGenerator()->create_user();
4357
 
4358
        // Disable messaging.
4359
        $CFG->messaging = 0;
4360
        $this->assertFalse(api::can_create_contact($user1->id, $user2->id));
4361
 
4362
        // Re-enable messaging.
4363
        $CFG->messaging = 1;
4364
 
4365
        // Allow users to message anyone site-wide.
4366
        $CFG->messagingallusers = 1;
4367
        $this->assertTrue(api::can_create_contact($user1->id, $user2->id));
4368
 
4369
        // Disallow users from messaging anyone site-wide.
4370
        $CFG->messagingallusers = 0;
4371
        $this->assertFalse(api::can_create_contact($user1->id, $user2->id));
4372
 
4373
        // Put the users in the same course so a contact request should be possible.
4374
        $course = self::getDataGenerator()->create_course();
4375
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
4376
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
4377
        $this->assertTrue(api::can_create_contact($user1->id, $user2->id));
4378
    }
4379
 
4380
    /**
4381
     * Test creating a contact request.
4382
     */
11 efrain 4383
    public function test_create_contact_request(): void {
1 efrain 4384
        global $DB;
11 efrain 4385
        $this->resetAfterTest();
1 efrain 4386
 
4387
        $user1 = self::getDataGenerator()->create_user();
4388
        $user2 = self::getDataGenerator()->create_user();
4389
 
4390
        $sink = $this->redirectMessages();
4391
        $request = api::create_contact_request($user1->id, $user2->id);
4392
        $messages = $sink->get_messages();
4393
        $sink->close();
4394
        // Test customdata.
4395
        $customdata = json_decode($messages[0]->customdata);
4396
        $this->assertObjectHasProperty('notificationiconurl', $customdata);
4397
        $this->assertObjectHasProperty('actionbuttons', $customdata);
4398
        $this->assertCount(2, (array) $customdata->actionbuttons);
4399
 
4400
        $this->assertEquals($user1->id, $request->userid);
4401
        $this->assertEquals($user2->id, $request->requesteduserid);
4402
    }
4403
 
4404
    /**
4405
     * Test confirming a contact request.
4406
     */
11 efrain 4407
    public function test_confirm_contact_request(): void {
1 efrain 4408
        global $DB;
11 efrain 4409
        $this->resetAfterTest();
1 efrain 4410
 
4411
        $user1 = self::getDataGenerator()->create_user();
4412
        $user2 = self::getDataGenerator()->create_user();
4413
 
4414
        api::create_contact_request($user1->id, $user2->id);
4415
 
4416
        api::confirm_contact_request($user1->id, $user2->id);
4417
 
4418
        $this->assertEquals(0, $DB->count_records('message_contact_requests'));
4419
 
4420
        $contact = $DB->get_records('message_contacts');
4421
 
4422
        $this->assertCount(1, $contact);
4423
 
4424
        $contact = reset($contact);
4425
 
4426
        $this->assertEquals($user1->id, $contact->userid);
4427
        $this->assertEquals($user2->id, $contact->contactid);
4428
    }
4429
 
4430
    /**
4431
     * Test declining a contact request.
4432
     */
11 efrain 4433
    public function test_decline_contact_request(): void {
1 efrain 4434
        global $DB;
11 efrain 4435
        $this->resetAfterTest();
1 efrain 4436
 
4437
        $user1 = self::getDataGenerator()->create_user();
4438
        $user2 = self::getDataGenerator()->create_user();
4439
 
4440
        api::create_contact_request($user1->id, $user2->id);
4441
 
4442
        api::decline_contact_request($user1->id, $user2->id);
4443
 
4444
        $this->assertEquals(0, $DB->count_records('message_contact_requests'));
4445
        $this->assertEquals(0, $DB->count_records('message_contacts'));
4446
    }
4447
 
4448
    /**
4449
     * Test retrieving contact requests.
4450
     */
11 efrain 4451
    public function test_get_contact_requests(): void {
1 efrain 4452
        global $PAGE;
11 efrain 4453
        $this->resetAfterTest();
1 efrain 4454
 
4455
        $user1 = self::getDataGenerator()->create_user();
4456
        $user2 = self::getDataGenerator()->create_user();
4457
        $user3 = self::getDataGenerator()->create_user();
4458
 
4459
        // Block one user, their request should not show up.
4460
        api::block_user($user1->id, $user3->id);
4461
 
4462
        api::create_contact_request($user2->id, $user1->id);
4463
        api::create_contact_request($user3->id, $user1->id);
4464
 
4465
        $requests = api::get_contact_requests($user1->id);
4466
 
4467
        $this->assertCount(1, $requests);
4468
 
4469
        $request = reset($requests);
4470
        $userpicture = new \user_picture($user2);
4471
        $profileimageurl = $userpicture->get_url($PAGE)->out(false);
4472
 
4473
        $this->assertEquals($user2->id, $request->id);
4474
        $this->assertEquals(fullname($user2), $request->fullname);
4475
        $this->assertObjectHasProperty('profileimageurl', $request);
4476
        $this->assertObjectHasProperty('profileimageurlsmall', $request);
4477
        $this->assertObjectHasProperty('isonline', $request);
4478
        $this->assertObjectHasProperty('showonlinestatus', $request);
4479
        $this->assertObjectHasProperty('isblocked', $request);
4480
        $this->assertObjectHasProperty('iscontact', $request);
4481
    }
4482
 
4483
    /**
4484
     * Test the get_contact_requests() function when the user has blocked the sender of the request.
4485
     */
11 efrain 4486
    public function test_get_contact_requests_blocked_sender(): void {
4487
        $this->resetAfterTest();
1 efrain 4488
        $user1 = self::getDataGenerator()->create_user();
4489
        $user2 = self::getDataGenerator()->create_user();
4490
 
4491
        // User1 blocks User2.
4492
        api::block_user($user1->id, $user2->id);
4493
 
4494
        // User2 tries to add User1 as a contact.
4495
        api::create_contact_request($user2->id, $user1->id);
4496
 
4497
        // Verify we don't see the contact request from the blocked user User2 in the requests for User1.
4498
        $requests = api::get_contact_requests($user1->id);
4499
        $this->assertEmpty($requests);
4500
    }
4501
 
4502
    /**
4503
     * Test getting contact requests when there are none.
4504
     */
11 efrain 4505
    public function test_get_contact_requests_no_requests(): void {
1 efrain 4506
        $this->resetAfterTest();
4507
 
4508
        $user1 = self::getDataGenerator()->create_user();
4509
 
4510
        $requests = api::get_contact_requests($user1->id);
4511
 
4512
        $this->assertEmpty($requests);
4513
    }
4514
 
4515
    /**
4516
     * Test getting contact requests with limits.
4517
     */
11 efrain 4518
    public function test_get_contact_requests_with_limits(): void {
1 efrain 4519
        $this->resetAfterTest();
4520
 
4521
        $user1 = self::getDataGenerator()->create_user();
4522
        $user2 = self::getDataGenerator()->create_user();
4523
        $user3 = self::getDataGenerator()->create_user();
4524
 
4525
        api::create_contact_request($user2->id, $user1->id);
4526
        api::create_contact_request($user3->id, $user1->id);
4527
 
4528
        $requests = api::get_contact_requests($user1->id, 0, 1);
4529
 
4530
        $this->assertCount(1, $requests);
4531
    }
4532
 
4533
    /**
4534
     * Test adding contacts.
4535
     */
11 efrain 4536
    public function test_add_contact(): void {
1 efrain 4537
        global $DB;
11 efrain 4538
        $this->resetAfterTest();
1 efrain 4539
 
4540
        $user1 = self::getDataGenerator()->create_user();
4541
        $user2 = self::getDataGenerator()->create_user();
4542
 
4543
        api::add_contact($user1->id, $user2->id);
4544
 
4545
        $contact = $DB->get_records('message_contacts');
4546
 
4547
        $this->assertCount(1, $contact);
4548
 
4549
        $contact = reset($contact);
4550
 
4551
        $this->assertEquals($user1->id, $contact->userid);
4552
        $this->assertEquals($user2->id, $contact->contactid);
4553
    }
4554
 
4555
    /**
4556
     * Test removing contacts.
4557
     */
11 efrain 4558
    public function test_remove_contact(): void {
1 efrain 4559
        global $DB;
11 efrain 4560
        $this->resetAfterTest();
1 efrain 4561
 
4562
        $user1 = self::getDataGenerator()->create_user();
4563
        $user2 = self::getDataGenerator()->create_user();
4564
 
4565
        api::add_contact($user1->id, $user2->id);
4566
        api::remove_contact($user1->id, $user2->id);
4567
 
4568
        $this->assertEquals(0, $DB->count_records('message_contacts'));
4569
    }
4570
 
4571
    /**
4572
     * Test blocking users.
4573
     */
11 efrain 4574
    public function test_block_user(): void {
1 efrain 4575
        global $DB;
11 efrain 4576
        $this->resetAfterTest();
1 efrain 4577
 
4578
        $user1 = self::getDataGenerator()->create_user();
4579
        $user2 = self::getDataGenerator()->create_user();
4580
 
4581
        api::block_user($user1->id, $user2->id);
4582
 
4583
        $blockedusers = $DB->get_records('message_users_blocked');
4584
 
4585
        $this->assertCount(1, $blockedusers);
4586
 
4587
        $blockeduser = reset($blockedusers);
4588
 
4589
        $this->assertEquals($user1->id, $blockeduser->userid);
4590
        $this->assertEquals($user2->id, $blockeduser->blockeduserid);
4591
    }
4592
 
4593
    /**
4594
     * Test unblocking users.
4595
     */
11 efrain 4596
    public function test_unblock_user(): void {
1 efrain 4597
        global $DB;
11 efrain 4598
        $this->resetAfterTest();
1 efrain 4599
 
4600
        $user1 = self::getDataGenerator()->create_user();
4601
        $user2 = self::getDataGenerator()->create_user();
4602
 
4603
        api::block_user($user1->id, $user2->id);
4604
        api::unblock_user($user1->id, $user2->id);
4605
 
4606
        $this->assertEquals(0, $DB->count_records('message_users_blocked'));
4607
    }
4608
 
4609
    /**
4610
     * Test muting a conversation.
4611
     */
11 efrain 4612
    public function test_mute_conversation(): void {
1 efrain 4613
        global $DB;
11 efrain 4614
        $this->resetAfterTest();
1 efrain 4615
 
4616
        $user1 = self::getDataGenerator()->create_user();
4617
        $user2 = self::getDataGenerator()->create_user();
4618
 
4619
        $conversation = api::create_conversation(
4620
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4621
            [
4622
                $user1->id,
4623
                $user2->id
4624
            ]
4625
        );
4626
        $conversationid = $conversation->id;
4627
 
4628
        api::mute_conversation($user1->id, $conversationid);
4629
 
4630
        $mutedconversation = $DB->get_records('message_conversation_actions');
4631
 
4632
        $this->assertCount(1, $mutedconversation);
4633
 
4634
        $mutedconversation = reset($mutedconversation);
4635
 
4636
        $this->assertEquals($user1->id, $mutedconversation->userid);
4637
        $this->assertEquals($conversationid, $mutedconversation->conversationid);
4638
        $this->assertEquals(api::CONVERSATION_ACTION_MUTED, $mutedconversation->action);
4639
    }
4640
 
4641
    /**
4642
     * Test unmuting a conversation.
4643
     */
11 efrain 4644
    public function test_unmute_conversation(): void {
1 efrain 4645
        global $DB;
11 efrain 4646
        $this->resetAfterTest();
1 efrain 4647
 
4648
        $user1 = self::getDataGenerator()->create_user();
4649
        $user2 = self::getDataGenerator()->create_user();
4650
 
4651
        $conversation = api::create_conversation(
4652
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4653
            [
4654
                $user1->id,
4655
                $user2->id
4656
            ]
4657
        );
4658
        $conversationid = $conversation->id;
4659
 
4660
        api::mute_conversation($user1->id, $conversationid);
4661
        api::unmute_conversation($user1->id, $conversationid);
4662
 
4663
        $this->assertEquals(0, $DB->count_records('message_conversation_actions'));
4664
    }
4665
 
4666
    /**
4667
     * Test if a conversation is muted.
4668
     */
11 efrain 4669
    public function test_is_conversation_muted(): void {
4670
        $this->resetAfterTest();
4671
 
1 efrain 4672
        $user1 = self::getDataGenerator()->create_user();
4673
        $user2 = self::getDataGenerator()->create_user();
4674
 
4675
        $conversation = api::create_conversation(
4676
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4677
            [
4678
                $user1->id,
4679
                $user2->id
4680
            ]
4681
        );
4682
        $conversationid = $conversation->id;
4683
 
4684
        $this->assertFalse(api::is_conversation_muted($user1->id, $conversationid));
4685
 
4686
        api::mute_conversation($user1->id, $conversationid);
4687
 
4688
        $this->assertTrue(api::is_conversation_muted($user1->id, $conversationid));
4689
    }
4690
 
4691
    /**
4692
     * Test is contact check.
4693
     */
11 efrain 4694
    public function test_is_contact(): void {
4695
        $this->resetAfterTest();
4696
 
1 efrain 4697
        $user1 = self::getDataGenerator()->create_user();
4698
        $user2 = self::getDataGenerator()->create_user();
4699
        $user3 = self::getDataGenerator()->create_user();
4700
 
4701
        api::add_contact($user1->id, $user2->id);
4702
 
4703
        $this->assertTrue(api::is_contact($user1->id, $user2->id));
4704
        $this->assertTrue(api::is_contact($user2->id, $user1->id));
4705
        $this->assertFalse(api::is_contact($user2->id, $user3->id));
4706
    }
4707
 
4708
    /**
4709
     * Test get contact.
4710
     */
11 efrain 4711
    public function test_get_contact(): void {
4712
        $this->resetAfterTest();
4713
 
1 efrain 4714
        $user1 = self::getDataGenerator()->create_user();
4715
        $user2 = self::getDataGenerator()->create_user();
4716
 
4717
        api::add_contact($user1->id, $user2->id);
4718
 
4719
        $contact = api::get_contact($user1->id, $user2->id);
4720
 
4721
        $this->assertEquals($user1->id, $contact->userid);
4722
        $this->assertEquals($user2->id, $contact->contactid);
4723
    }
4724
 
4725
    /**
4726
     * Test is blocked checked.
4727
     */
11 efrain 4728
    public function test_is_blocked(): void {
4729
        $this->resetAfterTest();
4730
 
1 efrain 4731
        $user1 = self::getDataGenerator()->create_user();
4732
        $user2 = self::getDataGenerator()->create_user();
4733
 
4734
        $this->assertFalse(api::is_blocked($user1->id, $user2->id));
4735
        $this->assertFalse(api::is_blocked($user2->id, $user1->id));
4736
 
4737
        api::block_user($user1->id, $user2->id);
4738
 
4739
        $this->assertTrue(api::is_blocked($user1->id, $user2->id));
4740
        $this->assertFalse(api::is_blocked($user2->id, $user1->id));
4741
    }
4742
 
4743
    /**
4744
     * Test the contact request exist check.
4745
     */
11 efrain 4746
    public function test_does_contact_request_exist(): void {
4747
        $this->resetAfterTest();
4748
 
1 efrain 4749
        $user1 = self::getDataGenerator()->create_user();
4750
        $user2 = self::getDataGenerator()->create_user();
4751
 
4752
        $this->assertFalse(api::does_contact_request_exist($user1->id, $user2->id));
4753
        $this->assertFalse(api::does_contact_request_exist($user2->id, $user1->id));
4754
 
4755
        api::create_contact_request($user1->id, $user2->id);
4756
 
4757
        $this->assertTrue(api::does_contact_request_exist($user1->id, $user2->id));
4758
        $this->assertTrue(api::does_contact_request_exist($user2->id, $user1->id));
4759
    }
4760
 
4761
    /**
4762
     * Test the get_received_contact_requests_count() function.
4763
     */
11 efrain 4764
    public function test_get_received_contact_requests_count(): void {
4765
        $this->resetAfterTest();
4766
 
1 efrain 4767
        $user1 = self::getDataGenerator()->create_user();
4768
        $user2 = self::getDataGenerator()->create_user();
4769
        $user3 = self::getDataGenerator()->create_user();
4770
        $user4 = self::getDataGenerator()->create_user();
4771
 
4772
        $this->assertEquals(0, api::get_received_contact_requests_count($user1->id));
4773
 
4774
        api::create_contact_request($user2->id, $user1->id);
4775
 
4776
        $this->assertEquals(1, api::get_received_contact_requests_count($user1->id));
4777
 
4778
        api::create_contact_request($user3->id, $user1->id);
4779
 
4780
        $this->assertEquals(2, api::get_received_contact_requests_count($user1->id));
4781
 
4782
        api::create_contact_request($user1->id, $user4->id);
4783
        // Function should ignore sent requests.
4784
        $this->assertEquals(2, api::get_received_contact_requests_count($user1->id));
4785
    }
4786
 
4787
    /**
4788
     * Test the get_received_contact_requests_count() function when the user has blocked the sender of the request.
4789
     */
11 efrain 4790
    public function test_get_received_contact_requests_count_blocked_sender(): void {
4791
        $this->resetAfterTest();
4792
 
1 efrain 4793
        $user1 = self::getDataGenerator()->create_user();
4794
        $user2 = self::getDataGenerator()->create_user();
4795
 
4796
        // User1 blocks User2.
4797
        api::block_user($user1->id, $user2->id);
4798
 
4799
        // User2 tries to add User1 as a contact.
4800
        api::create_contact_request($user2->id, $user1->id);
4801
 
4802
        // Verify we don't see the contact request from the blocked user User2 in the count for User1.
4803
        $this->assertEquals(0, api::get_received_contact_requests_count($user1->id));
4804
    }
4805
 
4806
    /**
4807
     * Test the get_contact_requests_between_users() function.
4808
     */
11 efrain 4809
    public function test_get_contact_requests_between_users(): void {
4810
        $this->resetAfterTest();
4811
 
1 efrain 4812
        $user1 = self::getDataGenerator()->create_user();
4813
        $user2 = self::getDataGenerator()->create_user();
4814
        $user3 = self::getDataGenerator()->create_user();
4815
        $user4 = self::getDataGenerator()->create_user();
4816
 
4817
        $this->assertEquals([], api::get_contact_requests_between_users($user1->id, $user2->id));
4818
 
4819
        $request1 = api::create_contact_request($user2->id, $user1->id);
4820
        $results = api::get_contact_requests_between_users($user1->id, $user2->id);
4821
        $results = array_values($results);
4822
 
4823
        $this->assertCount(1, $results);
4824
        $result = $results[0];
4825
        $this->assertEquals($request1->id, $result->id);
4826
 
4827
        $request2 = api::create_contact_request($user1->id, $user2->id);
4828
        $results = api::get_contact_requests_between_users($user1->id, $user2->id);
4829
        $results = array_values($results);
4830
 
4831
        $this->assertCount(2, $results);
4832
        $actual = [(int) $results[0]->id, (int) $results[1]->id];
4833
        $expected = [(int) $request1->id, (int) $request2->id];
4834
 
4835
        sort($actual);
4836
        sort($expected);
4837
 
4838
        $this->assertEquals($expected, $actual);
4839
 
4840
        // Request from a different user.
4841
        api::create_contact_request($user3->id, $user1->id);
4842
 
4843
        $results = api::get_contact_requests_between_users($user1->id, $user2->id);
4844
        $results = array_values($results);
4845
 
4846
        $this->assertCount(2, $results);
4847
        $actual = [(int) $results[0]->id, (int) $results[1]->id];
4848
        $expected = [(int) $request1->id, (int) $request2->id];
4849
 
4850
        sort($actual);
4851
        sort($expected);
4852
 
4853
        $this->assertEquals($expected, $actual);
4854
    }
4855
 
4856
    /**
4857
     * Test the user in conversation check.
4858
     */
11 efrain 4859
    public function test_is_user_in_conversation(): void {
4860
        $this->resetAfterTest();
4861
 
1 efrain 4862
        $user1 = self::getDataGenerator()->create_user();
4863
        $user2 = self::getDataGenerator()->create_user();
4864
 
4865
        $conversation = api::create_conversation(
4866
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4867
            [
4868
                $user1->id,
4869
                $user2->id
4870
            ]
4871
        );
4872
        $conversationid = $conversation->id;
4873
 
4874
        $this->assertTrue(api::is_user_in_conversation($user1->id, $conversationid));
4875
    }
4876
 
4877
    /**
4878
     * Test the user in conversation check when they are not.
4879
     */
11 efrain 4880
    public function test_is_user_in_conversation_when_not(): void {
4881
        $this->resetAfterTest();
4882
 
1 efrain 4883
        $user1 = self::getDataGenerator()->create_user();
4884
        $user2 = self::getDataGenerator()->create_user();
4885
        $user3 = self::getDataGenerator()->create_user();
4886
 
4887
        $conversation = api::create_conversation(
4888
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4889
            [
4890
                $user1->id,
4891
                $user2->id
4892
            ]
4893
        );
4894
        $conversationid = $conversation->id;
4895
 
4896
        $this->assertFalse(api::is_user_in_conversation($user3->id, $conversationid));
4897
    }
4898
 
4899
    /**
4900
     * Test can create a group conversation.
4901
     */
11 efrain 4902
    public function test_can_create_group_conversation(): void {
1 efrain 4903
        global $CFG;
11 efrain 4904
        $this->resetAfterTest();
1 efrain 4905
 
4906
        $student = self::getDataGenerator()->create_user();
4907
        $teacher = self::getDataGenerator()->create_user();
4908
        $course = self::getDataGenerator()->create_course();
4909
 
4910
        $coursecontext = \context_course::instance($course->id);
4911
 
4912
        $this->getDataGenerator()->enrol_user($student->id, $course->id);
4913
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
4914
 
4915
        // Disable messaging.
4916
        $CFG->messaging = 0;
4917
        $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext));
4918
 
4919
        // Re-enable messaging.
4920
        $CFG->messaging = 1;
4921
 
4922
        // Student shouldn't be able to.
4923
        $this->assertFalse(api::can_create_group_conversation($student->id, $coursecontext));
4924
 
4925
        // Teacher should.
4926
        $this->assertTrue(api::can_create_group_conversation($teacher->id, $coursecontext));
4927
    }
4928
 
4929
    /**
4930
     * Test creating an individual conversation.
4931
     */
11 efrain 4932
    public function test_create_conversation_individual(): void {
4933
        $this->resetAfterTest();
4934
 
1 efrain 4935
        $user1 = self::getDataGenerator()->create_user();
4936
        $user2 = self::getDataGenerator()->create_user();
4937
 
4938
        $conversation = api::create_conversation(
4939
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
4940
            [
4941
                $user1->id,
4942
                $user2->id
4943
            ],
4944
            'A conversation name'
4945
        );
4946
 
4947
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, $conversation->type);
4948
        $this->assertEquals('A conversation name', $conversation->name);
4949
        $this->assertEquals(helper::get_conversation_hash([$user1->id, $user2->id]), $conversation->convhash);
4950
 
4951
        $this->assertCount(2, $conversation->members);
4952
 
4953
        $member1 = array_shift($conversation->members);
4954
        $member2 = array_shift($conversation->members);
4955
 
4956
        $this->assertEquals($user1->id, $member1->userid);
4957
        $this->assertEquals($conversation->id, $member1->conversationid);
4958
 
4959
        $this->assertEquals($user2->id, $member2->userid);
4960
        $this->assertEquals($conversation->id, $member2->conversationid);
4961
    }
4962
 
4963
    /**
4964
     * Test creating a group conversation.
4965
     */
11 efrain 4966
    public function test_create_conversation_group(): void {
4967
        $this->resetAfterTest();
4968
 
1 efrain 4969
        $user1 = self::getDataGenerator()->create_user();
4970
        $user2 = self::getDataGenerator()->create_user();
4971
        $user3 = self::getDataGenerator()->create_user();
4972
 
4973
        $conversation = api::create_conversation(
4974
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
4975
            [
4976
                $user1->id,
4977
                $user2->id,
4978
                $user3->id
4979
            ],
4980
            'A conversation name'
4981
        );
4982
 
4983
        $this->assertEquals(api::MESSAGE_CONVERSATION_TYPE_GROUP, $conversation->type);
4984
        $this->assertEquals('A conversation name', $conversation->name);
4985
        $this->assertNull($conversation->convhash);
4986
 
4987
        $this->assertCount(3, $conversation->members);
4988
 
4989
        $member1 = array_shift($conversation->members);
4990
        $member2 = array_shift($conversation->members);
4991
        $member3 = array_shift($conversation->members);
4992
 
4993
        $this->assertEquals($user1->id, $member1->userid);
4994
        $this->assertEquals($conversation->id, $member1->conversationid);
4995
 
4996
        $this->assertEquals($user2->id, $member2->userid);
4997
        $this->assertEquals($conversation->id, $member2->conversationid);
4998
 
4999
        $this->assertEquals($user3->id, $member3->userid);
5000
        $this->assertEquals($conversation->id, $member3->conversationid);
5001
    }
5002
 
5003
    /**
5004
     * Test creating an invalid conversation.
5005
     */
11 efrain 5006
    public function test_create_conversation_invalid(): void {
1 efrain 5007
        $this->expectException('moodle_exception');
5008
        api::create_conversation(3, [1, 2, 3]);
5009
    }
5010
 
5011
    /**
5012
     * Test creating an individual conversation with too many members.
5013
     */
11 efrain 5014
    public function test_create_conversation_individual_too_many_members(): void {
1 efrain 5015
        $this->expectException('moodle_exception');
5016
        api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL, [1, 2, 3]);
5017
    }
5018
 
5019
    /**
5020
     * Test create message conversation with area.
5021
     */
11 efrain 5022
    public function test_create_conversation_with_area(): void {
5023
        $this->resetAfterTest();
5024
 
1 efrain 5025
        $contextid = 111;
5026
        $itemid = 222;
5027
        $name = 'Name of conversation';
5028
        $conversation = api::create_conversation(
5029
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5030
            [],
5031
            $name,
5032
            api::MESSAGE_CONVERSATION_DISABLED,
5033
            'core_group',
5034
            'groups',
5035
            $itemid,
5036
            $contextid
5037
        );
5038
 
5039
        $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
5040
        $this->assertEquals('core_group', $conversation->component);
5041
        $this->assertEquals('groups', $conversation->itemtype);
5042
        $this->assertEquals($itemid, $conversation->itemid);
5043
        $this->assertEquals($contextid, $conversation->contextid);
5044
    }
5045
 
5046
    /**
5047
     * Test get_conversation_by_area.
5048
     */
11 efrain 5049
    public function test_get_conversation_by_area(): void {
5050
        $this->resetAfterTest();
5051
 
1 efrain 5052
        $contextid = 111;
5053
        $itemid = 222;
5054
        $name = 'Name of conversation';
5055
        $createconversation = api::create_conversation(
5056
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5057
            [],
5058
            $name,
5059
            api::MESSAGE_CONVERSATION_DISABLED,
5060
            'core_group',
5061
            'groups',
5062
            $itemid,
5063
            $contextid
5064
        );
5065
        $conversation = api::get_conversation_by_area('core_group', 'groups', $itemid, $contextid);
5066
 
5067
        $this->assertEquals($createconversation->id, $conversation->id);
5068
        $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
5069
        $this->assertEquals('core_group', $conversation->component);
5070
        $this->assertEquals('groups', $conversation->itemtype);
5071
        $this->assertEquals($itemid, $conversation->itemid);
5072
        $this->assertEquals($contextid, $conversation->contextid);
5073
    }
5074
 
5075
    /**
5076
     * Test enable_conversation.
5077
     */
11 efrain 5078
    public function test_enable_conversation(): void {
1 efrain 5079
        global $DB;
11 efrain 5080
        $this->resetAfterTest();
1 efrain 5081
 
5082
        $name = 'Name of conversation';
5083
 
5084
        $conversation = api::create_conversation(
5085
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5086
            [],
5087
            $name,
5088
            api::MESSAGE_CONVERSATION_DISABLED
5089
        );
5090
 
5091
        $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversation->enabled);
5092
        api::enable_conversation($conversation->id);
5093
        $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]);
5094
        $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversationenabled);
5095
    }
5096
 
5097
    /**
5098
     * Test disable_conversation.
5099
     */
11 efrain 5100
    public function test_disable_conversation(): void {
1 efrain 5101
        global $DB;
11 efrain 5102
        $this->resetAfterTest();
1 efrain 5103
 
11 efrain 5104
 
1 efrain 5105
        $name = 'Name of conversation';
5106
 
5107
        $conversation = api::create_conversation(
5108
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5109
            [],
5110
            $name,
5111
            api::MESSAGE_CONVERSATION_ENABLED
5112
        );
5113
 
5114
        $this->assertEquals(api::MESSAGE_CONVERSATION_ENABLED, $conversation->enabled);
5115
        api::disable_conversation($conversation->id);
5116
        $conversationenabled = $DB->get_field('message_conversations', 'enabled', ['id' => $conversation->id]);
5117
        $this->assertEquals(api::MESSAGE_CONVERSATION_DISABLED, $conversationenabled);
5118
    }
5119
 
5120
    /**
5121
     * Test update_conversation_name.
5122
     */
11 efrain 5123
    public function test_update_conversation_name(): void {
1 efrain 5124
        global $DB;
11 efrain 5125
        $this->resetAfterTest();
1 efrain 5126
 
5127
        $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_GROUP, []);
5128
 
5129
        $newname = 'New name of conversation';
5130
        api::update_conversation_name($conversation->id, $newname);
5131
 
5132
        $this->assertEquals(
5133
                $newname,
5134
                $DB->get_field('message_conversations', 'name', ['id' => $conversation->id])
5135
        );
5136
    }
5137
 
5138
    /**
5139
     * Test returning members in a conversation with no contact requests.
5140
     */
11 efrain 5141
    public function test_get_conversation_members(): void {
5142
        $this->resetAfterTest();
5143
 
1 efrain 5144
        $lastaccess = new \stdClass();
5145
        $lastaccess->lastaccess = time();
5146
 
5147
        $user1 = self::getDataGenerator()->create_user($lastaccess);
5148
        $user2 = self::getDataGenerator()->create_user();
5149
        $user3 = self::getDataGenerator()->create_user();
5150
 
5151
        // This user will not be in the conversation, but a contact request will exist for them.
5152
        $user4 = self::getDataGenerator()->create_user();
5153
 
5154
        // Add some contact requests.
5155
        api::create_contact_request($user1->id, $user3->id);
5156
        api::create_contact_request($user1->id, $user4->id);
5157
        api::create_contact_request($user2->id, $user3->id);
5158
 
5159
        // User 1 and 2 are already contacts.
5160
        api::add_contact($user1->id, $user2->id);
5161
 
5162
        // User 1 has blocked user 3.
5163
        api::block_user($user1->id, $user3->id);
5164
        $conversation = api::create_conversation(
5165
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5166
            [
5167
                $user1->id,
5168
                $user2->id,
5169
                $user3->id
5170
            ]
5171
        );
5172
        $conversationid = $conversation->id;
5173
        $members = api::get_conversation_members($user1->id, $conversationid, false);
5174
 
5175
        // Sort them by id.
5176
        ksort($members);
5177
        $this->assertCount(3, $members);
5178
        $member1 = array_shift($members);
5179
        $member2 = array_shift($members);
5180
        $member3 = array_shift($members);
5181
 
5182
        // Confirm the standard fields are OK.
5183
        $this->assertEquals($user1->id, $member1->id);
5184
        $this->assertEquals(fullname($user1), $member1->fullname);
5185
        $this->assertEquals(true, $member1->isonline);
5186
        $this->assertEquals(true, $member1->showonlinestatus);
5187
        $this->assertEquals(false, $member1->iscontact);
5188
        $this->assertEquals(false, $member1->isblocked);
5189
        $this->assertObjectHasProperty('contactrequests', $member1);
5190
        $this->assertEmpty($member1->contactrequests);
5191
 
5192
        $this->assertEquals($user2->id, $member2->id);
5193
        $this->assertEquals(fullname($user2), $member2->fullname);
5194
        $this->assertEquals(false, $member2->isonline);
5195
        $this->assertEquals(true, $member2->showonlinestatus);
5196
        $this->assertEquals(true, $member2->iscontact);
5197
        $this->assertEquals(false, $member2->isblocked);
5198
        $this->assertObjectHasProperty('contactrequests', $member2);
5199
        $this->assertEmpty($member2->contactrequests);
5200
 
5201
        $this->assertEquals($user3->id, $member3->id);
5202
        $this->assertEquals(fullname($user3), $member3->fullname);
5203
        $this->assertEquals(false, $member3->isonline);
5204
        $this->assertEquals(true, $member3->showonlinestatus);
5205
        $this->assertEquals(false, $member3->iscontact);
5206
        $this->assertEquals(true, $member3->isblocked);
5207
        $this->assertObjectHasProperty('contactrequests', $member3);
5208
        $this->assertEmpty($member3->contactrequests);
5209
    }
5210
 
5211
    /**
5212
     * Test returning members in a conversation with contact requests.
5213
     */
11 efrain 5214
    public function test_get_conversation_members_with_contact_requests(): void {
5215
        $this->resetAfterTest();
5216
 
1 efrain 5217
        $lastaccess = new \stdClass();
5218
        $lastaccess->lastaccess = time();
5219
 
5220
        $user1 = self::getDataGenerator()->create_user($lastaccess);
5221
        $user2 = self::getDataGenerator()->create_user();
5222
        $user3 = self::getDataGenerator()->create_user();
5223
 
5224
        // This user will not be in the conversation, but a contact request will exist for them.
5225
        $user4 = self::getDataGenerator()->create_user();
5226
        // Add some contact requests.
5227
        api::create_contact_request($user1->id, $user2->id);
5228
        api::create_contact_request($user1->id, $user3->id);
5229
        api::create_contact_request($user1->id, $user4->id);
5230
        api::create_contact_request($user2->id, $user3->id);
5231
 
5232
        // User 1 and 2 are already contacts.
5233
        api::add_contact($user1->id, $user2->id);
5234
        // User 1 has blocked user 3.
5235
        api::block_user($user1->id, $user3->id);
5236
 
5237
        $conversation = api::create_conversation(
5238
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
5239
            [
5240
                $user1->id,
5241
                $user2->id,
5242
                $user3->id
5243
            ]
5244
        );
5245
        $conversationid = $conversation->id;
5246
 
5247
        $members = api::get_conversation_members($user1->id, $conversationid, true);
5248
 
5249
        // Sort them by id.
5250
        ksort($members);
5251
 
5252
        $this->assertCount(3, $members);
5253
 
5254
        $member1 = array_shift($members);
5255
        $member2 = array_shift($members);
5256
        $member3 = array_shift($members);
5257
 
5258
        // Confirm the standard fields are OK.
5259
        $this->assertEquals($user1->id, $member1->id);
5260
        $this->assertEquals(fullname($user1), $member1->fullname);
5261
        $this->assertEquals(true, $member1->isonline);
5262
        $this->assertEquals(true, $member1->showonlinestatus);
5263
        $this->assertEquals(false, $member1->iscontact);
5264
        $this->assertEquals(false, $member1->isblocked);
5265
        $this->assertCount(2, $member1->contactrequests);
5266
 
5267
        $this->assertEquals($user2->id, $member2->id);
5268
        $this->assertEquals(fullname($user2), $member2->fullname);
5269
        $this->assertEquals(false, $member2->isonline);
5270
        $this->assertEquals(true, $member2->showonlinestatus);
5271
        $this->assertEquals(true, $member2->iscontact);
5272
        $this->assertEquals(false, $member2->isblocked);
5273
        $this->assertCount(1, $member2->contactrequests);
5274
 
5275
        $this->assertEquals($user3->id, $member3->id);
5276
        $this->assertEquals(fullname($user3), $member3->fullname);
5277
        $this->assertEquals(false, $member3->isonline);
5278
        $this->assertEquals(true, $member3->showonlinestatus);
5279
        $this->assertEquals(false, $member3->iscontact);
5280
        $this->assertEquals(true, $member3->isblocked);
5281
        $this->assertCount(1, $member3->contactrequests);
5282
 
5283
        // Confirm the contact requests are OK.
5284
        $request1 = array_shift($member1->contactrequests);
5285
        $request2 = array_shift($member1->contactrequests);
5286
 
5287
        $this->assertEquals($user1->id, $request1->userid);
5288
        $this->assertEquals($user2->id, $request1->requesteduserid);
5289
 
5290
        $this->assertEquals($user1->id, $request2->userid);
5291
        $this->assertEquals($user3->id, $request2->requesteduserid);
5292
 
5293
        $request1 = array_shift($member2->contactrequests);
5294
 
5295
        $this->assertEquals($user1->id, $request1->userid);
5296
        $this->assertEquals($user2->id, $request1->requesteduserid);
5297
 
5298
        $request1 = array_shift($member3->contactrequests);
5299
 
5300
        $this->assertEquals($user1->id, $request1->userid);
5301
        $this->assertEquals($user3->id, $request1->requesteduserid);
5302
    }
5303
 
5304
    /**
5305
     * Test returning members of a self conversation.
5306
     */
11 efrain 5307
    public function test_get_conversation_members_with_self_conversation(): void {
5308
        $this->resetAfterTest();
5309
 
1 efrain 5310
        $lastaccess = new \stdClass();
5311
        $lastaccess->lastaccess = time();
5312
 
5313
        $user1 = self::getDataGenerator()->create_user($lastaccess);
5314
 
5315
        $selfconversation = api::get_self_conversation($user1->id);
5316
        testhelper::send_fake_message_to_conversation($user1, $selfconversation->id, 'This is a self-message!');
5317
 
5318
        // Get the members for the self-conversation.
5319
        $members = api::get_conversation_members($user1->id, $selfconversation->id);
5320
        $this->assertCount(1, $members);
5321
 
5322
        $member1 = array_shift($members);
5323
 
5324
        // Confirm the standard fields are OK.
5325
        $this->assertEquals($user1->id, $member1->id);
5326
        $this->assertEquals(fullname($user1), $member1->fullname);
5327
        $this->assertEquals(true, $member1->isonline);
5328
        $this->assertEquals(true, $member1->showonlinestatus);
5329
        $this->assertEquals(false, $member1->iscontact);
5330
        $this->assertEquals(false, $member1->isblocked);
5331
    }
5332
 
5333
    /**
5334
     * Test verifying that messages can be sent to existing individual conversations.
5335
     */
11 efrain 5336
    public function test_send_message_to_conversation_individual_conversation(): void {
5337
        $this->resetAfterTest();
5338
 
1 efrain 5339
        // Get a bunch of conversations, some group, some individual and in different states.
5340
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5341
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5342
 
5343
        // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5344
        $course = $this->getDataGenerator()->create_course();
5345
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5346
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5347
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5348
        $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5349
 
5350
        // Redirect messages.
5351
        // This marks messages as read, but we can still observe and verify the number of conversation recipients,
5352
        // based on the message_viewed events generated as part of marking the message as read for each user.
5353
        $this->preventResetByRollback();
5354
        $sink = $this->redirectMessages();
5355
 
5356
        // Send a message to an individual conversation.
5357
        $sink = $this->redirectEvents();
5358
        $messagessink = $this->redirectMessages();
5359
        $message1 = api::send_message_to_conversation($user1->id, $ic1->id, 'this is a message', FORMAT_MOODLE);
5360
        $events = $sink->get_events();
5361
        $messages = $messagessink->get_messages();
5362
        // Test customdata.
5363
        $customdata = json_decode($messages[0]->customdata);
5364
        $this->assertObjectHasProperty('notificationiconurl', $customdata);
5365
        $this->assertObjectHasProperty('actionbuttons', $customdata);
5366
        $this->assertCount(1, (array) $customdata->actionbuttons);
5367
        $this->assertObjectHasProperty('placeholders', $customdata);
5368
        $this->assertCount(1, (array) $customdata->placeholders);
5369
 
5370
        // Verify the message returned.
5371
        $this->assertInstanceOf(\stdClass::class, $message1);
5372
        $this->assertObjectHasProperty('id', $message1);
5373
        $this->assertEquals($user1->id, $message1->useridfrom);
5374
        $this->assertEquals('this is a message', $message1->text);
5375
        $this->assertObjectHasProperty('timecreated', $message1);
5376
 
5377
        // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(),
5378
        // however, we can still determine the number and ids of any recipients this way.
5379
        $this->assertCount(1, $events);
5380
        $userids = array_column($events, 'userid');
5381
        $this->assertNotContainsEquals($user1->id, $userids);
5382
        $this->assertContainsEquals($user2->id, $userids);
5383
    }
5384
 
5385
    /**
5386
     * Test verifying that messages can be sent to existing group conversations.
5387
     */
11 efrain 5388
    public function test_send_message_to_conversation_group_conversation(): void {
5389
        $this->resetAfterTest();
1 efrain 5390
        // Get a bunch of conversations, some group, some individual and in different states.
5391
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5392
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5393
 
5394
        // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5395
        $course = $this->getDataGenerator()->create_course();
5396
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5397
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5398
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5399
        $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5400
 
5401
        // Redirect messages.
5402
        // This marks messages as read, but we can still observe and verify the number of conversation recipients,
5403
        // based on the message_viewed events generated as part of marking the message as read for each user.
5404
        $this->preventResetByRollback();
5405
        $sink = $this->redirectMessages();
5406
 
5407
        // Send a message to a group conversation.
5408
        $sink = $this->redirectEvents();
5409
        $messagessink = $this->redirectMessages();
5410
        $message1 = api::send_message_to_conversation($user1->id, $gc2->id, 'message to the group', FORMAT_MOODLE);
5411
        $events = $sink->get_events();
5412
        $messages = $messagessink->get_messages();
5413
        // Verify the message returned.
5414
        $this->assertInstanceOf(\stdClass::class, $message1);
5415
        $this->assertObjectHasProperty('id', $message1);
5416
        $this->assertEquals($user1->id, $message1->useridfrom);
5417
        $this->assertEquals('message to the group', $message1->text);
5418
        $this->assertObjectHasProperty('timecreated', $message1);
5419
        // Test customdata.
5420
        $customdata = json_decode($messages[0]->customdata);
5421
        $this->assertObjectHasProperty('actionbuttons', $customdata);
5422
        $this->assertCount(1, (array) $customdata->actionbuttons);
5423
        $this->assertObjectHasProperty('placeholders', $customdata);
5424
        $this->assertCount(1, (array) $customdata->placeholders);
5425
        $this->assertObjectNotHasProperty('notificationiconurl', $customdata);    // No group image means no image.
5426
 
5427
        // Verify events. Note: the event is a message read event because of an if (PHPUNIT) conditional within message_send(),
5428
        // however, we can still determine the number and ids of any recipients this way.
5429
        $this->assertCount(2, $events);
5430
        $userids = array_column($events, 'userid');
5431
        $this->assertNotContainsEquals($user1->id, $userids);
5432
        $this->assertContainsEquals($user3->id, $userids);
5433
        $this->assertContainsEquals($user4->id, $userids);
5434
    }
5435
 
5436
    /**
5437
     * Test verifying that messages can be sent to existing linked group conversations.
5438
     */
11 efrain 5439
    public function test_send_message_to_conversation_linked_group_conversation(): void {
1 efrain 5440
        global $CFG, $PAGE;
11 efrain 5441
        $this->resetAfterTest();
1 efrain 5442
 
5443
        // Create some users.
5444
        $user1 = self::getDataGenerator()->create_user();
5445
        $user2 = self::getDataGenerator()->create_user();
5446
        $user3 = self::getDataGenerator()->create_user();
5447
 
5448
        $course = $this->getDataGenerator()->create_course();
5449
 
5450
        // Create a group with a linked conversation and a valid image.
5451
        $this->setAdminUser();
5452
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5453
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5454
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5455
        $group = $this->getDataGenerator()->create_group([
5456
            'courseid' => $course->id,
5457
            'enablemessaging' => 1,
5458
            'picturepath' => $CFG->dirroot . '/lib/tests/fixtures/gd-logo.png'
5459
        ]);
5460
 
5461
        // Add users to group.
5462
        $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user1->id));
5463
        $this->getDataGenerator()->create_group_member(array('groupid' => $group->id, 'userid' => $user2->id));
5464
 
5465
        // Verify the group with the image works as expected.
5466
        $conversations = api::get_conversations($user1->id);
5467
        $this->assertEquals(2, $conversations[0]->membercount);
5468
        $this->assertEquals($course->shortname, $conversations[0]->subname);
5469
        $groupimageurl = get_group_picture_url($group, $group->courseid, true);
5470
        $this->assertEquals($groupimageurl, $conversations[0]->imageurl);
5471
 
5472
        // Redirect messages.
5473
        // This marks messages as read, but we can still observe and verify the number of conversation recipients,
5474
        // based on the message_viewed events generated as part of marking the message as read for each user.
5475
        $this->preventResetByRollback();
5476
        $sink = $this->redirectMessages();
5477
 
5478
        // Send a message to a group conversation.
5479
        $messagessink = $this->redirectMessages();
5480
        $message1 = api::send_message_to_conversation($user1->id, $conversations[0]->id,
5481
            'message to the group', FORMAT_MOODLE);
5482
        $messages = $messagessink->get_messages();
5483
        // Verify the message returned.
5484
        $this->assertInstanceOf(\stdClass::class, $message1);
5485
        $this->assertObjectHasProperty('id', $message1);
5486
        $this->assertEquals($user1->id, $message1->useridfrom);
5487
        $this->assertEquals('message to the group', $message1->text);
5488
        $this->assertObjectHasProperty('timecreated', $message1);
5489
        // Test customdata.
5490
        $customdata = json_decode($messages[0]->customdata);
5491
        $this->assertObjectHasProperty('notificationiconurl', $customdata);
5492
        $this->assertObjectHasProperty('notificationsendericonurl', $customdata);
5493
        $this->assertEquals($groupimageurl, $customdata->notificationiconurl);
5494
        $this->assertEquals($group->name, $customdata->conversationname);
5495
        $userpicture = new \user_picture($user1);
5496
        $userpicture->size = 1; // Use f1 size.
5497
        $this->assertEquals($userpicture->get_url($PAGE)->out(false), $customdata->notificationsendericonurl);
5498
    }
5499
 
5500
    /**
5501
     * Test verifying that messages cannot be sent to conversations that don't exist.
5502
     */
11 efrain 5503
    public function test_send_message_to_conversation_non_existent_conversation(): void {
5504
        $this->resetAfterTest();
5505
 
1 efrain 5506
        // Get a bunch of conversations, some group, some individual and in different states.
5507
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5508
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5509
 
5510
        $this->expectException(\moodle_exception::class);
5511
        api::send_message_to_conversation($user1->id, 0, 'test', FORMAT_MOODLE);
5512
    }
5513
 
5514
    /**
5515
     * Test verifying that messages cannot be sent to conversations by users who are not members.
5516
     */
11 efrain 5517
    public function test_send_message_to_conversation_non_member(): void {
5518
        $this->resetAfterTest();
5519
 
1 efrain 5520
        // Get a bunch of conversations, some group, some individual and in different states.
5521
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5522
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5523
 
5524
        // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5525
        $course = $this->getDataGenerator()->create_course();
5526
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5527
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5528
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5529
        $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5530
 
5531
        $this->expectException(\moodle_exception::class);
5532
        api::send_message_to_conversation($user3->id, $ic1->id, 'test', FORMAT_MOODLE);
5533
    }
5534
 
5535
    /**
5536
     * Test verifying that messages cannot be sent to conversations by users who are not members.
5537
     */
11 efrain 5538
    public function test_send_message_to_conversation_blocked_user(): void {
5539
        $this->resetAfterTest();
5540
 
1 efrain 5541
        // Get a bunch of conversations, some group, some individual and in different states.
5542
        list($user1, $user2, $user3, $user4, $ic1, $ic2, $ic3,
5543
            $gc1, $gc2, $gc3, $gc4, $gc5, $gc6) = $this->create_conversation_test_data();
5544
 
5545
        // Enrol the users into the same course so the privacy checks will pass using default (contact+course members) setting.
5546
        $course = $this->getDataGenerator()->create_course();
5547
        $this->getDataGenerator()->enrol_user($user1->id, $course->id);
5548
        $this->getDataGenerator()->enrol_user($user2->id, $course->id);
5549
        $this->getDataGenerator()->enrol_user($user3->id, $course->id);
5550
        $this->getDataGenerator()->enrol_user($user4->id, $course->id);
5551
 
5552
        // User 1 blocks user 2.
5553
        api::block_user($user1->id, $user2->id);
5554
 
5555
        // Verify that a message can be sent to any group conversation in which user1 and user2 are members.
5556
        $this->assertNotEmpty(api::send_message_to_conversation($user1->id, $gc2->id, 'Hey guys', FORMAT_PLAIN));
5557
 
5558
        // User 2 cannot send a message to the conversation with user 1.
5559
        $this->expectException(\moodle_exception::class);
5560
        api::send_message_to_conversation($user2->id, $ic1->id, 'test', FORMAT_MOODLE);
5561
    }
5562
 
5563
    /**
5564
     * Test the get_conversation() function with a muted conversation.
5565
     */
11 efrain 5566
    public function test_get_conversation_with_muted_conversation(): void {
1 efrain 5567
        $this->resetAfterTest();
5568
 
5569
        $user1 = self::getDataGenerator()->create_user();
5570
        $user2 = self::getDataGenerator()->create_user();
5571
 
5572
        $this->setUser($user1);
5573
 
5574
        $conversation = api::create_conversation(api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
5575
            [$user1->id, $user2->id]);
5576
 
5577
        $conversation = api::get_conversation($user1->id, $conversation->id);
5578
 
5579
        $this->assertFalse($conversation->ismuted);
5580
 
5581
        // Now, mute the conversation.
5582
        api::mute_conversation($user1->id, $conversation->id);
5583
 
5584
        $conversation = api::get_conversation($user1->id, $conversation->id);
5585
 
5586
        $this->assertTrue($conversation->ismuted);
5587
    }
5588
 
5589
    /**
5590
     * Data provider for test_get_conversation_counts().
5591
     */
5592
    public function get_conversation_counts_test_cases() {
5593
        $typeindividual = api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL;
5594
        $typegroup = api::MESSAGE_CONVERSATION_TYPE_GROUP;
5595
        $typeself = api::MESSAGE_CONVERSATION_TYPE_SELF;
5596
        list($user1, $user2, $user3, $user4, $user5, $user6, $user7, $user8) = [0, 1, 2, 3, 4, 5, 6, 7];
5597
        $conversations = [
5598
            [
5599
                'type' => $typeindividual,
5600
                'users' => [$user1, $user2],
5601
                'messages' => [$user1, $user2, $user2],
5602
                'favourites' => [$user1],
5603
                'enabled' => null // Individual conversations cannot be disabled.
5604
            ],
5605
            [
5606
                'type' => $typeindividual,
5607
                'users' => [$user1, $user3],
5608
                'messages' => [$user1, $user3, $user1],
5609
                'favourites' => [],
5610
                'enabled' => null // Individual conversations cannot be disabled.
5611
            ],
5612
            [
5613
                'type' => $typegroup,
5614
                'users' => [$user1, $user2, $user3, $user4],
5615
                'messages' => [$user1, $user2, $user3, $user4],
5616
                'favourites' => [],
5617
                'enabled' => true
5618
            ],
5619
            [
5620
                'type' => $typegroup,
5621
                'users' => [$user2, $user3, $user4],
5622
                'messages' => [$user2, $user3, $user4],
5623
                'favourites' => [],
5624
                'enabled' => true
5625
            ],
5626
            [
5627
                'type' => $typegroup,
5628
                'users' => [$user6, $user7],
5629
                'messages' => [$user6, $user7, $user7],
5630
                'favourites' => [$user6],
5631
                'enabled' => false
5632
            ],
5633
            [
5634
                'type' => $typeself,
5635
                'users' => [$user8],
5636
                'messages' => [$user8],
5637
                'favourites' => [],
5638
                'enabled' => null // Self-conversations cannot be disabled.
5639
            ],
5640
        ];
5641
 
5642
        return [
5643
            'No conversations' => [
5644
                'conversationConfigs' => $conversations,
5645
                'deletemessagesuser' => null,
5646
                'deletemessages' => [],
5647
                'arguments' => [$user5],
5648
                'expectedcounts' => ['favourites' => 1, 'types' => [
5649
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5650
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5651
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5652
                ]],
5653
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5654
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5655
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5656
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5657
                ]],
5658
                'deletedusers' => []
5659
            ],
5660
            'No individual conversations, 2 group conversations' => [
5661
                'conversationConfigs' => $conversations,
5662
                'deletemessagesuser' => null,
5663
                'deletemessages' => [],
5664
                'arguments' => [$user4],
5665
                'expectedcounts' => ['favourites' => 1, 'types' => [
5666
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5667
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5668
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5669
                ]],
5670
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5671
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5672
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5673
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5674
                ]],
5675
                'deletedusers' => []
5676
            ],
5677
            '2 individual conversations (one favourited), 1 group conversation' => [
5678
                'conversationConfigs' => $conversations,
5679
                'deletemessagesuser' => null,
5680
                'deletemessages' => [],
5681
                'arguments' => [$user1],
5682
                'expectedcounts' => ['favourites' => 2, 'types' => [
5683
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5684
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5685
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5686
                ]],
5687
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5688
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5689
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5690
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5691
                ]],
5692
                'deletedusers' => []
5693
            ],
5694
            '1 individual conversation, 2 group conversations' => [
5695
                'conversationConfigs' => $conversations,
5696
                'deletemessagesuser' => null,
5697
                'deletemessages' => [],
5698
                'arguments' => [$user2],
5699
                'expectedcounts' => ['favourites' => 1, 'types' => [
5700
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5701
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5702
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5703
                ]],
5704
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5705
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5706
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5707
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5708
                ]],
5709
                'deletedusers' => []
5710
            ],
5711
            '2 group conversations only' => [
5712
                'conversationConfigs' => $conversations,
5713
                'deletemessagesuser' => null,
5714
                'deletemessages' => [],
5715
                'arguments' => [$user4],
5716
                'expectedcounts' => ['favourites' => 1, 'types' => [
5717
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5718
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5719
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5720
                ]],
5721
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5722
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5723
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5724
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5725
                ]],
5726
                'deletedusers' => []
5727
            ],
5728
            'All conversation types, delete a message from individual favourited, messages remaining' => [
5729
                'conversationConfigs' => $conversations,
5730
                'deletemessagesuser' => $user1,
5731
                'deletemessages' => [0],
5732
                'arguments' => [$user1],
5733
                'expectedcounts' => ['favourites' => 2, 'types' => [
5734
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5735
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5736
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5737
                ]],
5738
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5739
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5740
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5741
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5742
                ]],
5743
                'deletedusers' => []
5744
            ],
5745
            'All conversation types, delete a message from individual non-favourited, messages remaining' => [
5746
                'conversationConfigs' => $conversations,
5747
                'deletemessagesuser' => $user1,
5748
                'deletemessages' => [3],
5749
                'arguments' => [$user1],
5750
                'expectedcounts' => ['favourites' => 2, 'types' => [
5751
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5752
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5753
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5754
                ]],
5755
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5756
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5757
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5758
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5759
                ]],
5760
                'deletedusers' => []
5761
            ],
5762
            'All conversation types, delete all messages from individual favourited, no messages remaining' => [
5763
                'conversationConfigs' => $conversations,
5764
                'deletemessagesuser' => $user1,
5765
                'deletemessages' => [0, 1, 2],
5766
                'arguments' => [$user1],
5767
                'expectedcounts' => ['favourites' => 1, 'types' => [
5768
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5769
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5770
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5771
                ]],
5772
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5773
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5774
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5775
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5776
                ]],
5777
                'deletedusers' => []
5778
            ],
5779
            'All conversation types, delete all messages from individual non-favourited, no messages remaining' => [
5780
                'conversationConfigs' => $conversations,
5781
                'deletemessagesuser' => $user1,
5782
                'deletemessages' => [3, 4, 5],
5783
                'arguments' => [$user1],
5784
                'expectedcounts' => ['favourites' => 2, 'types' => [
5785
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5786
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5787
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5788
                ]],
5789
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5790
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5791
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5792
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5793
                ]],
5794
                'deletedusers' => []
5795
            ],
5796
            'All conversation types, delete all messages from individual favourited, no messages remaining, different user' => [
5797
                'conversationConfigs' => $conversations,
5798
                'deletemessagesuser' => $user1,
5799
                'deletemessages' => [0, 1, 2],
5800
                'arguments' => [$user2],
5801
                'expectedcounts' => ['favourites' => 1, 'types' => [
5802
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5803
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5804
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5805
                ]],
5806
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5807
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5808
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5809
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5810
                ]],
5811
                'deletedusers' => []
5812
            ],
5813
            'All conversation types, delete all messages from individual non-favourited, no messages remaining, different user' => [
5814
                'conversationConfigs' => $conversations,
5815
                'deletemessagesuser' => $user1,
5816
                'deletemessages' => [3, 4, 5],
5817
                'arguments' => [$user3],
5818
                'expectedcounts' => ['favourites' => 1, 'types' => [
5819
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5820
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5821
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5822
                ]],
5823
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5824
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5825
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 2,
5826
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5827
                ]],
5828
                'deletedusers' => []
5829
            ],
5830
            'All conversation types, delete some messages from group non-favourited, messages remaining,' => [
5831
                'conversationConfigs' => $conversations,
5832
                'deletemessagesuser' => $user1,
5833
                'deletemessages' => [6, 7],
5834
                'arguments' => [$user1],
5835
                'expectedcounts' => ['favourites' => 2, 'types' => [
5836
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5837
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5838
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5839
                ]],
5840
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5841
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5842
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5843
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5844
                ]],
5845
                'deletedusers' => []
5846
            ],
5847
            'All conversation types, delete all messages from group non-favourited, no messages remaining,' => [
5848
                'conversationConfigs' => $conversations,
5849
                'deletemessagesuser' => $user1,
5850
                'deletemessages' => [6, 7, 8, 9],
5851
                'arguments' => [$user1],
5852
                'expectedcounts' => ['favourites' => 2, 'types' => [
5853
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5854
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5855
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5856
                ]],
5857
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5858
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5859
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5860
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5861
                ]],
5862
                'deletedusers' => []
5863
            ],
5864
            'All conversation types, another user soft deleted' => [
5865
                'conversationConfigs' => $conversations,
5866
                'deletemessagesuser' => null,
5867
                'deletemessages' => [],
5868
                'arguments' => [$user1],
5869
                'expectedcounts' => ['favourites' => 2, 'types' => [
5870
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5871
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5872
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5873
                ]],
5874
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5875
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5876
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5877
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5878
                ]],
5879
                'deletedusers' => [$user2]
5880
            ],
5881
            'All conversation types, all group users soft deleted' => [
5882
                'conversationConfigs' => $conversations,
5883
                'deletemessagesuser' => null,
5884
                'deletemessages' => [],
5885
                'arguments' => [$user1],
5886
                'expectedcounts' => ['favourites' => 2, 'types' => [
5887
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5888
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5889
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5890
                ]],
5891
                'expectedunreadcounts' => ['favourites' => 1, 'types' => [
5892
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 1,
5893
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 1,
5894
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5895
                ]],
5896
                'deletedusers' => [$user2, $user3, $user4]
5897
            ],
5898
            'Group conversation which is disabled, favourited' => [
5899
                'conversationConfigs' => $conversations,
5900
                'deletemessagesuser' => null,
5901
                'deletemessages' => [],
5902
                'arguments' => [$user6],
5903
                'expectedcounts' => ['favourites' => 1, 'types' => [
5904
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5905
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5906
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5907
                ]],
5908
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5909
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5910
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5911
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5912
                ]],
5913
                'deletedusers' => []
5914
            ],
5915
            'Group conversation which is disabled, non-favourited' => [
5916
                'conversationConfigs' => $conversations,
5917
                'deletemessagesuser' => null,
5918
                'deletemessages' => [],
5919
                'arguments' => [$user7],
5920
                'expectedcounts' => ['favourites' => 1, 'types' => [
5921
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5922
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5923
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5924
                ]],
5925
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5926
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5927
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5928
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5929
                ]],
5930
                'deletedusers' => []
5931
            ],
5932
            'Conversation with self' => [
5933
                'conversationConfigs' => $conversations,
5934
                'deletemessagesuser' => null,
5935
                'deletemessages' => [],
5936
                'arguments' => [$user8],
5937
                'expectedcounts' => ['favourites' => 0, 'types' => [
5938
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5939
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5940
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 1
5941
                ]],
5942
                'expectedunreadcounts' => ['favourites' => 0, 'types' => [
5943
                    api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0,
5944
                    api::MESSAGE_CONVERSATION_TYPE_GROUP => 0,
5945
                    api::MESSAGE_CONVERSATION_TYPE_SELF => 0
5946
                ]],
5947
                'deletedusers' => []
5948
            ],
5949
        ];
5950
    }
5951
 
5952
    /**
5953
     * Test the get_conversation_counts() function.
5954
     *
5955
     * @dataProvider get_conversation_counts_test_cases
5956
     * @param array $conversationconfigs Conversations to create
5957
     * @param int $deletemessagesuser The user who is deleting the messages
5958
     * @param array $deletemessages The list of messages to delete (by index)
5959
     * @param array $arguments Arguments for the count conversations function
5960
     * @param array $expectedcounts the expected conversation counts
5961
     * @param array $expectedunreadcounts the expected unread conversation counts
5962
     * @param array $deletedusers the array of users to soft delete.
5963
     */
5964
    public function test_get_conversation_counts(
5965
        $conversationconfigs,
5966
        $deletemessagesuser,
5967
        $deletemessages,
5968
        $arguments,
5969
        $expectedcounts,
5970
        $expectedunreadcounts,
5971
        $deletedusers
11 efrain 5972
    ): void {
5973
        $this->resetAfterTest();
5974
 
1 efrain 5975
        $generator = $this->getDataGenerator();
5976
        $users = [
5977
            $generator->create_user(),
5978
            $generator->create_user(),
5979
            $generator->create_user(),
5980
            $generator->create_user(),
5981
            $generator->create_user(),
5982
            $generator->create_user(),
5983
            $generator->create_user(),
5984
            $generator->create_user()
5985
        ];
5986
 
5987
        $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null;
5988
        $arguments[0] = $users[$arguments[0]]->id;
5989
        $systemcontext = \context_system::instance();
5990
        $conversations = [];
5991
        $messageids = [];
5992
 
5993
        foreach ($conversationconfigs as $config) {
5994
            $conversation = api::create_conversation(
5995
                $config['type'],
5996
                array_map(function($userindex) use ($users) {
5997
                    return $users[$userindex]->id;
5998
                }, $config['users']),
5999
                null,
6000
                ($config['enabled'] ?? true)
6001
            );
6002
 
6003
            foreach ($config['messages'] as $userfromindex) {
6004
                $userfrom = $users[$userfromindex];
6005
                $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id);
6006
            }
6007
 
6008
            // Remove the self conversations created by the generator,
6009
            // so we can choose to set that ourself and honour the original intention of the test.
6010
            $userids = array_map(function($userindex) use ($users) {
6011
                return $users[$userindex]->id;
6012
            }, $config['users']);
6013
            foreach ($userids as $userid) {
6014
                if ($conversation->type == api::MESSAGE_CONVERSATION_TYPE_SELF) {
6015
                    api::unset_favourite_conversation($conversation->id, $userid);
6016
                }
6017
            }
6018
 
6019
            foreach ($config['favourites'] as $userfromindex) {
6020
                $userfrom = $users[$userfromindex];
6021
                $usercontext = \context_user::instance($userfrom->id);
6022
                $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
6023
                $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext);
6024
            }
6025
 
6026
            $conversations[] = $conversation;
6027
        }
6028
 
6029
        foreach ($deletemessages as $messageindex) {
6030
            api::delete_message($deleteuser->id, $messageids[$messageindex]);
6031
        }
6032
 
6033
        foreach ($deletedusers as $deleteduser) {
6034
            delete_user($users[$deleteduser]);
6035
        }
6036
 
6037
        $counts = api::get_conversation_counts(...$arguments);
6038
 
6039
        $this->assertEquals($expectedcounts['favourites'], $counts['favourites']);
6040
        $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
6041
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]);
6042
        $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP],
6043
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]);
6044
        $this->assertEquals($expectedcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF],
6045
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]);
6046
    }
6047
 
6048
    /**
6049
     * Test the count_contacts() function.
6050
     */
11 efrain 6051
    public function test_count_contacts(): void {
6052
        $this->resetAfterTest();
6053
 
1 efrain 6054
        $user1 = self::getDataGenerator()->create_user();
6055
        $user2 = self::getDataGenerator()->create_user();
6056
        $user3 = self::getDataGenerator()->create_user();
6057
 
6058
        $this->assertEquals(0, api::count_contacts($user1->id));
6059
 
6060
        api::create_contact_request($user1->id, $user2->id);
6061
 
6062
        // Still zero until the request is confirmed.
6063
        $this->assertEquals(0, api::count_contacts($user1->id));
6064
 
6065
        api::confirm_contact_request($user1->id, $user2->id);
6066
 
6067
        $this->assertEquals(1, api::count_contacts($user1->id));
6068
 
6069
        api::create_contact_request($user3->id, $user1->id);
6070
 
6071
        // Still one until the request is confirmed.
6072
        $this->assertEquals(1, api::count_contacts($user1->id));
6073
 
6074
        api::confirm_contact_request($user3->id, $user1->id);
6075
 
6076
        $this->assertEquals(2, api::count_contacts($user1->id));
6077
    }
6078
 
6079
    /**
6080
     * Test the get_unread_conversation_counts() function.
6081
     *
6082
     * @dataProvider get_conversation_counts_test_cases
6083
     * @param array $conversationconfigs Conversations to create
6084
     * @param int $deletemessagesuser The user who is deleting the messages
6085
     * @param array $deletemessages The list of messages to delete (by index)
6086
     * @param array $arguments Arguments for the count conversations function
6087
     * @param array $expectedcounts the expected conversation counts
6088
     * @param array $expectedunreadcounts the expected unread conversation counts
6089
     * @param array $deletedusers the list of users to soft-delete.
6090
     */
6091
    public function test_get_unread_conversation_counts(
6092
        $conversationconfigs,
6093
        $deletemessagesuser,
6094
        $deletemessages,
6095
        $arguments,
6096
        $expectedcounts,
6097
        $expectedunreadcounts,
6098
        $deletedusers
11 efrain 6099
    ): void {
1 efrain 6100
        $this->resetAfterTest();
6101
        $generator = $this->getDataGenerator();
6102
        $users = [
6103
            $generator->create_user(),
6104
            $generator->create_user(),
6105
            $generator->create_user(),
6106
            $generator->create_user(),
6107
            $generator->create_user(),
6108
            $generator->create_user(),
6109
            $generator->create_user(),
6110
            $generator->create_user()
6111
        ];
6112
 
6113
        $deleteuser = !is_null($deletemessagesuser) ? $users[$deletemessagesuser] : null;
6114
        $this->setUser($users[$arguments[0]]);
6115
        $arguments[0] = $users[$arguments[0]]->id;
6116
        $systemcontext = \context_system::instance();
6117
        $conversations = [];
6118
        $messageids = [];
6119
 
6120
        foreach ($conversationconfigs as $config) {
6121
            $conversation = api::create_conversation(
6122
                $config['type'],
6123
                array_map(function($userindex) use ($users) {
6124
                    return $users[$userindex]->id;
6125
                }, $config['users']),
6126
                null,
6127
                ($config['enabled'] ?? true)
6128
            );
6129
 
6130
            foreach ($config['messages'] as $userfromindex) {
6131
                $userfrom = $users[$userfromindex];
6132
                $messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id);
6133
            }
6134
 
6135
            foreach ($config['favourites'] as $userfromindex) {
6136
                $userfrom = $users[$userfromindex];
6137
                $usercontext = \context_user::instance($userfrom->id);
6138
                $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
6139
                $ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext);
6140
            }
6141
 
6142
            $conversations[] = $conversation;
6143
        }
6144
 
6145
        foreach ($deletemessages as $messageindex) {
6146
            api::delete_message($deleteuser->id, $messageids[$messageindex]);
6147
        }
6148
 
6149
        foreach ($deletedusers as $deleteduser) {
6150
            delete_user($users[$deleteduser]);
6151
        }
6152
 
6153
        $counts = api::get_unread_conversation_counts(...$arguments);
6154
 
6155
        $this->assertEquals($expectedunreadcounts['favourites'], $counts['favourites']);
6156
        $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL],
6157
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL]);
6158
        $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP],
6159
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_GROUP]);
6160
        $this->assertEquals($expectedunreadcounts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF],
6161
            $counts['types'][api::MESSAGE_CONVERSATION_TYPE_SELF]);
6162
    }
6163
 
11 efrain 6164
    public function test_delete_all_conversation_data(): void {
1 efrain 6165
        global $DB;
6166
 
6167
        $this->resetAfterTest();
6168
 
6169
        $this->setAdminUser();
6170
 
6171
        $course1 = $this->getDataGenerator()->create_course();
6172
        $coursecontext1 = \context_course::instance($course1->id);
6173
 
6174
        $user1 = $this->getDataGenerator()->create_user();
6175
        $user2 = $this->getDataGenerator()->create_user();
6176
 
6177
        $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
6178
        $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
6179
 
6180
        $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
6181
        $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
6182
 
6183
        // Add users to both groups.
6184
        $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
6185
        $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
6186
 
6187
        $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
6188
        $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
6189
 
6190
        $groupconversation1 = api::get_conversation_by_area(
6191
            'core_group',
6192
            'groups',
6193
            $group1->id,
6194
            $coursecontext1->id
6195
        );
6196
 
6197
        $groupconversation2 = api::get_conversation_by_area(
6198
            'core_group',
6199
            'groups',
6200
            $group2->id,
6201
            $coursecontext1->id
6202
        );
6203
 
6204
        // Send a few messages.
6205
        $g1m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id);
6206
        $g1m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id);
6207
        $g1m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation1->id);
6208
        $g1m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation1->id);
6209
 
6210
        $g2m1 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id);
6211
        $g2m2 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id);
6212
        $g2m3 = testhelper::send_fake_message_to_conversation($user1, $groupconversation2->id);
6213
        $g2m4 = testhelper::send_fake_message_to_conversation($user2, $groupconversation2->id);
6214
 
6215
        // Favourite the conversation for several of the users.
6216
        api::set_favourite_conversation($groupconversation1->id, $user1->id);
6217
        api::set_favourite_conversation($groupconversation1->id, $user2->id);
6218
 
6219
        // Delete a few messages.
6220
        api::delete_message($user1->id, $g1m1);
6221
        api::delete_message($user1->id, $g1m2);
6222
        api::delete_message($user1->id, $g2m1);
6223
        api::delete_message($user1->id, $g2m2);
6224
 
6225
        // Mute the conversations.
6226
        api::mute_conversation($user1->id, $groupconversation1->id);
6227
        api::mute_conversation($user1->id, $groupconversation2->id);
6228
 
6229
        // Now, delete all the data for the group 1 conversation.
6230
        api::delete_all_conversation_data($groupconversation1->id);
6231
 
6232
        // Confirm group conversation was deleted just for the group 1 conversation.
6233
        $this->assertEquals(0, $DB->count_records('message_conversations', ['id' => $groupconversation1->id]));
6234
        $this->assertEquals(1, $DB->count_records('message_conversations', ['id' => $groupconversation2->id]));
6235
 
6236
        // Confirm conversation members were deleted just for the group 1 conversation.
6237
        $this->assertEquals(0, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation1->id]));
6238
        $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $groupconversation2->id]));
6239
 
6240
        // Confirm message conversation actions were deleted just for the group 1 conversation.
6241
        $this->assertEquals(0, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation1->id]));
6242
        $this->assertEquals(1, $DB->count_records('message_conversation_actions', ['conversationid' => $groupconversation2->id]));
6243
 
6244
        // Confirm message user actions were deleted just for the group 1 conversation.
6245
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m1]));
6246
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m2]));
6247
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m3]));
6248
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g1m4]));
6249
        $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m1]));
6250
        $this->assertEquals(1, $DB->count_records('message_user_actions', ['messageid' => $g2m2]));
6251
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m3]));
6252
        $this->assertEquals(0, $DB->count_records('message_user_actions', ['messageid' => $g2m4]));
6253
 
6254
        // Confirm messages were deleted just for the group 1 conversation.
6255
        $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m1]));
6256
        $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m2]));
6257
        $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m3]));
6258
        $this->assertEquals(0, $DB->count_records('messages', ['id' => $g1m4]));
6259
        $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m1]));
6260
        $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m2]));
6261
        $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m3]));
6262
        $this->assertEquals(1, $DB->count_records('messages', ['id' => $g2m4]));
6263
 
6264
        // Confirm favourites were deleted for both users.
6265
        $user1service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id));
6266
        $this->assertFalse($user1service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id,
6267
            $coursecontext1));
6268
        $user2service = \core_favourites\service_factory::get_service_for_user_context(\context_user::instance($user1->id));
6269
        $this->assertFalse($user2service->favourite_exists('core_message', 'message_conversations', $groupconversation1->id,
6270
            $coursecontext1));
6271
    }
6272
 
6273
    /**
6274
     * Tests the user can delete message for all users as a teacher.
6275
     */
11 efrain 6276
    public function test_can_delete_message_for_all_users_teacher(): void {
1 efrain 6277
        global $DB;
6278
        $this->resetAfterTest(true);
6279
 
6280
        // Create fake data to test it.
6281
        list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
6282
 
6283
        // Allow Teacher can delete messages for all.
6284
        $editingteacher = $DB->get_record('role', ['shortname' => 'editingteacher']);
6285
        assign_capability('moodle/site:deleteanymessage', CAP_ALLOW, $editingteacher->id, \context_system::instance());
6286
 
6287
        // Set as the first user.
6288
        $this->setUser($teacher);
6289
 
6290
        // Send a message to private conversation and in a group conversation.
6291
        $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id);
6292
        $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id);
6293
 
6294
        // Teacher cannot delete message for everyone in a private conversation.
6295
        $this->assertFalse(api::can_delete_message_for_all_users($teacher->id, $messageidind));
6296
 
6297
        // Teacher can delete message for everyone in a group conversation.
6298
        $this->assertTrue(api::can_delete_message_for_all_users($teacher->id, $messageidgrp));
6299
    }
6300
 
6301
    /**
6302
     * Tests the user can delete message for all users as a student.
6303
     */
11 efrain 6304
    public function test_can_delete_message_for_all_users_student(): void {
1 efrain 6305
        $this->resetAfterTest(true);
6306
 
6307
        // Create fake data to test it.
6308
        list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
6309
 
6310
        // Set as the first user.
6311
        $this->setUser($student1);
6312
 
6313
        // Send a message to private conversation and in a group conversation.
6314
        $messageidind = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id);
6315
        $messageidgrp = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id);
6316
 
6317
        // Student1 cannot delete message for everyone in a private conversation.
6318
        $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidind));
6319
 
6320
        // Student1 cannot delete message for everyone in a group conversation.
6321
        $this->assertFalse(api::can_delete_message_for_all_users($student1->id, $messageidgrp));
6322
    }
6323
 
6324
    /**
6325
     * Tests tdelete message for all users in group conversation.
6326
     */
11 efrain 6327
    public function test_delete_message_for_all_users_group_conversation(): void {
1 efrain 6328
        global $DB;
6329
        $this->resetAfterTest(true);
6330
 
6331
        // Create fake data to test it.
6332
        list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
6333
 
6334
        // Send 3 messages to a group conversation.
6335
        $mgid1 = testhelper::send_fake_message_to_conversation($teacher, $convgroup->id);
6336
        $mgid2 = testhelper::send_fake_message_to_conversation($student1, $convgroup->id);
6337
        $mgid3 = testhelper::send_fake_message_to_conversation($student2, $convgroup->id);
6338
 
6339
        // Delete message 1 for all users.
6340
        api::delete_message_for_all_users($mgid1);
6341
 
6342
        // Get the messages to check if the message 1 was deleted for teacher.
6343
        $convmessages1 = api::get_conversation_messages($teacher->id, $convgroup->id);
6344
        // Only has to remains 2 messages.
6345
        $this->assertCount(2, $convmessages1['messages']);
6346
        // Check if no one of the two messages is message 1.
6347
        foreach ($convmessages1['messages'] as $message) {
6348
            $this->assertNotEquals($mgid1, $message->id);
6349
        }
6350
 
6351
        // Get the messages to check if the message 1 was deleted for student1.
6352
        $convmessages2 = api::get_conversation_messages($student1->id, $convgroup->id);
6353
        // Only has to remains 2 messages.
6354
        $this->assertCount(2, $convmessages2['messages']);
6355
        // Check if no one of the two messages is message 1.
6356
        foreach ($convmessages2['messages'] as $message) {
6357
            $this->assertNotEquals($mgid1, $message->id);
6358
        }
6359
 
6360
        // Get the messages to check if the message 1 was deleted for student2.
6361
        $convmessages3 = api::get_conversation_messages($student2->id, $convgroup->id);
6362
        // Only has to remains 2 messages.
6363
        $this->assertCount(2, $convmessages3['messages']);
6364
        // Check if no one of the two messages is message 1.
6365
        foreach ($convmessages3['messages'] as $message) {
6366
            $this->assertNotEquals($mgid1, $message->id);
6367
        }
6368
    }
6369
 
6370
    /**
6371
     * Tests delete message for all users in private conversation.
6372
     */
11 efrain 6373
    public function test_delete_message_for_all_users_individual_conversation(): void {
1 efrain 6374
        global $DB;
6375
        $this->resetAfterTest(true);
6376
 
6377
        // Create fake data to test it.
6378
        list($teacher, $student1, $student2, $convgroup, $convindividual) = $this->create_delete_message_test_data();
6379
 
6380
        // Send 2 messages in a individual conversation.
6381
        $mid1 = testhelper::send_fake_message_to_conversation($teacher, $convindividual->id);
6382
        $mid2 = testhelper::send_fake_message_to_conversation($student1, $convindividual->id);
6383
 
6384
        // Delete the first message for all users.
6385
        api::delete_message_for_all_users($mid1);
6386
 
6387
        // Get the messages to check if the message 1 was deleted for teacher.
6388
        $convmessages1 = api::get_conversation_messages($teacher->id, $convindividual->id);
6389
        // Only has to remains 1 messages for teacher.
6390
        $this->assertCount(1, $convmessages1['messages']);
6391
        // Check the one messages remains not is the first message.
6392
        $this->assertNotEquals($mid1, $convmessages1['messages'][0]->id);
6393
 
6394
        // Get the messages to check if the message 1 was deleted for student1.
6395
        $convmessages2 = api::get_conversation_messages($student1->id, $convindividual->id);
6396
        // Only has to remains 1 messages for student1.
6397
        $this->assertCount(1, $convmessages2['messages']);
6398
        // Check the one messages remains not is the first message.
6399
        $this->assertNotEquals($mid1, $convmessages2['messages'][0]->id);
6400
    }
6401
 
6402
    /**
6403
     * Test retrieving conversation messages by providing a timefrom higher than last message timecreated. It should return no
6404
     * messages but keep the return structure to not break when called from the ws.
6405
     */
11 efrain 6406
    public function test_get_conversation_messages_timefrom_higher_than_last_timecreated(): void {
6407
        $this->resetAfterTest();
6408
 
1 efrain 6409
        // Create some users.
6410
        $user1 = self::getDataGenerator()->create_user();
6411
        $user2 = self::getDataGenerator()->create_user();
6412
        $user3 = self::getDataGenerator()->create_user();
6413
        $user4 = self::getDataGenerator()->create_user();
6414
 
6415
        // Create group conversation.
6416
        $conversation = api::create_conversation(
6417
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
6418
            [$user1->id, $user2->id, $user3->id, $user4->id]
6419
        );
6420
 
6421
        // The person doing the search.
6422
        $this->setUser($user1);
6423
 
6424
        // Send some messages back and forth.
6425
        $time = 1;
6426
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 1', $time + 1);
6427
        testhelper::send_fake_message_to_conversation($user2, $conversation->id, 'Message 2', $time + 2);
6428
        testhelper::send_fake_message_to_conversation($user1, $conversation->id, 'Message 3', $time + 3);
6429
        testhelper::send_fake_message_to_conversation($user3, $conversation->id, 'Message 4', $time + 4);
6430
 
6431
        // Retrieve the messages from $time + 5, which should return no messages.
6432
        $convmessages = api::get_conversation_messages($user1->id, $conversation->id, 0, 0, '', $time + 5);
6433
 
6434
        // Confirm the conversation id is correct.
6435
        $this->assertEquals($conversation->id, $convmessages['id']);
6436
 
6437
        // Confirm the message data is correct.
6438
        $messages = $convmessages['messages'];
6439
        $this->assertEquals(0, count($messages));
6440
 
6441
        // Confirm that members key is present.
6442
        $this->assertArrayHasKey('members', $convmessages);
6443
    }
6444
 
6445
    /**
6446
     * Helper to seed the database with initial state with data.
6447
     */
6448
    protected function create_delete_message_test_data() {
6449
        // Create some users.
6450
        $teacher = self::getDataGenerator()->create_user();
6451
        $student1 = self::getDataGenerator()->create_user();
6452
        $student2 = self::getDataGenerator()->create_user();
6453
 
6454
        // Create a course and enrol the users.
6455
        $course = $this->getDataGenerator()->create_course();
6456
        $coursecontext = \context_course::instance($course->id);
6457
        $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
6458
        $this->getDataGenerator()->enrol_user($student1->id, $course->id, 'student');
6459
        $this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student');
6460
 
6461
        // Create a group and added the users into.
6462
        $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
6463
        groups_add_member($group1->id, $teacher->id);
6464
        groups_add_member($group1->id, $student1->id);
6465
        groups_add_member($group1->id, $student2->id);
6466
 
6467
        // Create a group conversation linked with the course.
6468
        $convgroup = api::create_conversation(
6469
            api::MESSAGE_CONVERSATION_TYPE_GROUP,
6470
            [$teacher->id, $student1->id, $student2->id],
6471
            'Group test delete for everyone', api::MESSAGE_CONVERSATION_ENABLED,
6472
            'core_group',
6473
            'groups',
6474
            $group1->id,
6475
            \context_course::instance($course->id)->id
6476
        );
6477
 
6478
        // Create and individual conversation.
6479
        $convindividual = api::create_conversation(
6480
            api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL,
6481
            [$teacher->id, $student1->id]
6482
        );
6483
 
6484
        return [$teacher, $student1, $student2, $convgroup, $convindividual];
6485
    }
6486
 
6487
    /**
6488
     * Comparison function for sorting contacts.
6489
     *
6490
     * @param \stdClass $a
6491
     * @param \stdClass $b
6492
     * @return bool
6493
     */
6494
    protected static function sort_contacts($a, $b) {
6495
        return $a->userid > $b->userid;
6496
    }
6497
}