MDL-81574 mod_forum: Fix deprecated usage of format_text
[moodle.git] / mod / chat / tests / lib_test.php
blob865c6486d6590b5747bdce085376e1d389f800c6
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.
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/>.
17 /**
18 * Contains class containing unit tests for mod/chat/lib.php.
20 * @package mod_chat
21 * @category test
22 * @copyright 2017 Mark Nelson <markn@moodle.com>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 namespace mod_chat;
27 defined('MOODLE_INTERNAL') || die();
29 /**
30 * Class containing unit tests for mod/chat/lib.php.
32 * @package mod_chat
33 * @category test
34 * @copyright 2017 Mark Nelson <markn@moodle.com>
35 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37 class lib_test extends \advanced_testcase {
39 public function setUp(): void {
40 $this->resetAfterTest();
42 // Chat module is disabled by default, enable it for testing.
43 $manager = \core_plugin_manager::resolve_plugininfo_class('mod');
44 $manager::enable_plugin('chat', 1);
48 * The chat's event should not be shown to a user when the user cannot view the chat at all.
50 public function test_chat_core_calendar_provide_event_action_in_hidden_section() {
51 global $CFG;
53 $this->setAdminUser();
55 // Create a course.
56 $course = $this->getDataGenerator()->create_course();
58 // Create a student.
59 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
61 // Create a chat.
62 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
63 'chattime' => usergetmidnight(time())));
65 // Create a calendar event.
66 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
68 // Set sections 0 as hidden.
69 set_section_visible($course->id, 0, 0);
71 // Now, log out.
72 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
73 $this->setUser();
75 // Create an action factory.
76 $factory = new \core_calendar\action_factory();
78 // Decorate action event for the student.
79 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
81 // Confirm the event is not shown at all.
82 $this->assertNull($actionevent);
86 * The chat's event should not be shown to a user who does not have permission to view the chat at all.
88 public function test_chat_core_calendar_provide_event_action_for_non_user() {
89 global $CFG;
91 $this->setAdminUser();
93 // Create a course.
94 $course = $this->getDataGenerator()->create_course();
96 // Create a chat.
97 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
98 'chattime' => usergetmidnight(time())));
100 // Create a calendar event.
101 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
103 // Now, log out.
104 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
105 $this->setUser();
107 // Create an action factory.
108 $factory = new \core_calendar\action_factory();
110 // Decorate action event.
111 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
113 // Confirm the event is not shown at all.
114 $this->assertNull($actionevent);
117 public function test_chat_core_calendar_provide_event_action_chattime_event_yesterday() {
118 $this->setAdminUser();
120 // Create a course.
121 $course = $this->getDataGenerator()->create_course();
123 // Create a chat.
124 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
125 'chattime' => time() - DAYSECS));
127 // Create a calendar event.
128 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
130 // Create an action factory.
131 $factory = new \core_calendar\action_factory();
133 // Decorate action event.
134 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
136 // Confirm the event is not shown at all.
137 $this->assertNull($actionevent);
140 public function test_chat_core_calendar_provide_event_action_chattime_event_yesterday_for_user() {
141 global $CFG;
143 $this->setAdminUser();
145 // Create a course.
146 $course = $this->getDataGenerator()->create_course();
148 // Enrol a student in the course.
149 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
151 // Create a chat.
152 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
153 'chattime' => time() - DAYSECS));
155 // Create a calendar event.
156 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
158 // Now, log out.
159 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default.
160 $this->setUser();
162 // Create an action factory.
163 $factory = new \core_calendar\action_factory();
165 // Decorate action event for the student.
166 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
168 // Confirm the event is not shown at all.
169 $this->assertNull($actionevent);
172 public function test_chat_core_calendar_provide_event_action_chattime_event_today() {
173 $this->setAdminUser();
175 // Create a course.
176 $course = $this->getDataGenerator()->create_course();
178 // Create a chat.
179 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
180 'chattime' => usergetmidnight(time())));
182 // Create a calendar event.
183 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
185 // Create an action factory.
186 $factory = new \core_calendar\action_factory();
188 // Decorate action event.
189 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
191 // Confirm the event was decorated.
192 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
193 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
194 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
195 $this->assertEquals(1, $actionevent->get_item_count());
196 $this->assertTrue($actionevent->is_actionable());
199 public function test_chat_core_calendar_provide_event_action_chattime_event_today_for_user() {
200 global $CFG;
202 $this->setAdminUser();
204 // Create a course.
205 $course = $this->getDataGenerator()->create_course();
207 // Enrol a student in the course.
208 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
210 // Create a chat.
211 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
212 'chattime' => usergetmidnight(time())));
214 // Create a calendar event.
215 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
217 // Now, log out.
218 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default.
219 $this->setUser();
221 // Create an action factory.
222 $factory = new \core_calendar\action_factory();
224 // Decorate action event for the student.
225 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
227 // Confirm the event was decorated.
228 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
229 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
230 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
231 $this->assertEquals(1, $actionevent->get_item_count());
232 $this->assertTrue($actionevent->is_actionable());
235 public function test_chat_core_calendar_provide_event_action_chattime_event_tonight() {
236 $this->setAdminUser();
238 // Create a course.
239 $course = $this->getDataGenerator()->create_course();
241 // Create a chat.
242 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
243 'chattime' => usergetmidnight(time()) + (23 * HOURSECS)));
245 // Create a calendar event.
246 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
248 // Create an action factory.
249 $factory = new \core_calendar\action_factory();
251 // Decorate action event.
252 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
254 // Confirm the event was decorated.
255 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
256 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
257 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
258 $this->assertEquals(1, $actionevent->get_item_count());
259 $this->assertTrue($actionevent->is_actionable());
262 public function test_chat_core_calendar_provide_event_action_chattime_event_tonight_for_user() {
263 global $CFG;
265 $this->setAdminUser();
267 // Create a course.
268 $course = $this->getDataGenerator()->create_course();
270 // Enrol a student in the course.
271 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
273 // Create a chat.
274 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
275 'chattime' => usergetmidnight(time()) + (23 * HOURSECS)));
277 // Create a calendar event.
278 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
280 // Now, log out.
281 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default.
282 $this->setUser();
284 // Create an action factory.
285 $factory = new \core_calendar\action_factory();
287 // Decorate action event for the student.
288 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
290 // Confirm the event was decorated.
291 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
292 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
293 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
294 $this->assertEquals(1, $actionevent->get_item_count());
295 $this->assertTrue($actionevent->is_actionable());
298 public function test_chat_core_calendar_provide_event_action_chattime_event_tomorrow() {
299 $this->setAdminUser();
301 // Create a course.
302 $course = $this->getDataGenerator()->create_course();
304 // Create a chat.
305 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
306 'chattime' => time() + DAYSECS));
308 // Create a calendar event.
309 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
311 // Create an action factory.
312 $factory = new \core_calendar\action_factory();
314 // Decorate action event.
315 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
317 // Confirm the event was decorated.
318 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
319 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
320 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
321 $this->assertEquals(1, $actionevent->get_item_count());
322 $this->assertFalse($actionevent->is_actionable());
325 public function test_chat_core_calendar_provide_event_action_chattime_event_tomorrow_for_user() {
326 global $CFG;
328 $this->setAdminUser();
330 // Create a course.
331 $course = $this->getDataGenerator()->create_course();
333 // Enrol a student in the course.
334 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
336 // Create a chat.
337 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
338 'chattime' => time() + DAYSECS));
340 // Create a calendar event.
341 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME);
343 // Now, log out.
344 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default.
345 $this->setUser();
347 // Create an action factory.
348 $factory = new \core_calendar\action_factory();
350 // Decorate action event for the student.
351 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
353 // Confirm the event was decorated.
354 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
355 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name());
356 $this->assertInstanceOf('moodle_url', $actionevent->get_url());
357 $this->assertEquals(1, $actionevent->get_item_count());
358 $this->assertFalse($actionevent->is_actionable());
361 public function test_chat_core_calendar_provide_event_action_chattime_event_different_timezones() {
362 global $CFG;
364 $this->setAdminUser();
366 // Create a course.
367 $course = $this->getDataGenerator()->create_course();
369 $hour = gmdate('H');
371 // This could have been much easier if MDL-37327 were implemented.
372 // We don't know when this test is being ran and there is no standard way to
373 // mock the time() function (MDL-37327 to handle that).
374 if ($hour < 10) {
375 $timezone1 = 'UTC'; // GMT.
376 $timezone2 = 'Pacific/Pago_Pago'; // GMT -11:00.
377 } else if ($hour < 11) {
378 $timezone1 = 'Pacific/Kiritimati'; // GMT +14:00.
379 $timezone2 = 'America/Sao_Paulo'; // GMT -03:00.
380 } else {
381 $timezone1 = 'Pacific/Kiritimati'; // GMT +14:00.
382 $timezone2 = 'UTC'; // GMT.
385 $this->setTimezone($timezone2);
387 // Enrol 2 students with different timezones in the course.
388 $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student', (object)['timezone' => $timezone1]);
389 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student', (object)['timezone' => $timezone2]);
391 // Create a chat.
392 $chat1 = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
393 'chattime' => mktime(1, 0, 0))); // This is always yesterday in timezone1 time
394 // and always today in timezone2 time.
396 // Create a chat.
397 $chat2 = $this->getDataGenerator()->create_module('chat', array('course' => $course->id,
398 'chattime' => mktime(1, 0, 0) + DAYSECS)); // This is always today in timezone1 time
399 // and always tomorrow in timezone2 time.
401 // Create calendar events for the 2 chats above.
402 $event1 = $this->create_action_event($course->id, $chat1->id, CHAT_EVENT_TYPE_CHATTIME);
403 $event2 = $this->create_action_event($course->id, $chat2->id, CHAT_EVENT_TYPE_CHATTIME);
405 // Now, log out.
406 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default.
407 $this->setUser();
409 // Create an action factory.
410 $factory = new \core_calendar\action_factory();
412 // Decorate action event for student1.
413 $actionevent11 = mod_chat_core_calendar_provide_event_action($event1, $factory, $student1->id);
414 $actionevent12 = mod_chat_core_calendar_provide_event_action($event1, $factory, $student2->id);
415 $actionevent21 = mod_chat_core_calendar_provide_event_action($event2, $factory, $student1->id);
416 $actionevent22 = mod_chat_core_calendar_provide_event_action($event2, $factory, $student2->id);
418 // Confirm event1 is not shown to student1 at all.
419 $this->assertNull($actionevent11, 'Failed for UTC time ' . gmdate('H:i'));
421 // Confirm event1 was decorated for student2 and it is actionable.
422 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent12);
423 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent12->get_name());
424 $this->assertInstanceOf('moodle_url', $actionevent12->get_url());
425 $this->assertEquals(1, $actionevent12->get_item_count());
426 $this->assertTrue($actionevent12->is_actionable());
428 // Confirm event2 was decorated for student1 and it is actionable.
429 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent21);
430 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent21->get_name());
431 $this->assertInstanceOf('moodle_url', $actionevent21->get_url());
432 $this->assertEquals(1, $actionevent21->get_item_count());
433 $this->assertTrue($actionevent21->is_actionable());
435 // Confirm event2 was decorated for student2 and it is not actionable.
436 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent22);
437 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent22->get_name());
438 $this->assertInstanceOf('moodle_url', $actionevent22->get_url());
439 $this->assertEquals(1, $actionevent22->get_item_count());
440 $this->assertFalse($actionevent22->is_actionable());
444 * Test for chat_get_sessions().
446 public function test_chat_get_sessions() {
447 global $DB;
449 $this->resetAfterTest();
451 $generator = $this->getDataGenerator();
453 // Setup test data.
454 $this->setAdminUser();
455 $course = $generator->create_course();
456 $chat = $generator->create_module('chat', ['course' => $course->id]);
458 $user1 = $generator->create_user();
459 $user2 = $generator->create_user();
460 $studentrole = $DB->get_record('role', ['shortname' => 'student']);
461 $generator->enrol_user($user1->id, $course->id, $studentrole->id);
462 $generator->enrol_user($user2->id, $course->id, $studentrole->id);
464 // Login as user 1.
465 $this->setUser($user1);
466 $chatsid = chat_login_user($chat->id, 'ajax', 0, $course);
467 $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]);
469 // Get the messages for this chat session.
470 $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC');
472 // We should have just 1 system (enter) messages.
473 $this->assertCount(1, $messages);
475 // This is when the session starts (when the first message - enter - has been sent).
476 $sessionstart = reset($messages)->timestamp;
478 // Send some messages.
479 chat_send_chatmessage($chatuser, 'hello!');
480 chat_send_chatmessage($chatuser, 'bye bye!');
482 // Login as user 2.
483 $this->setUser($user2);
484 $chatsid = chat_login_user($chat->id, 'ajax', 0, $course);
485 $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]);
487 // Send a message and take note of this message ID.
488 $messageid = chat_send_chatmessage($chatuser, 'greetings!');
490 // This is when the session ends (timestamp of the last message sent to the chat).
491 $sessionend = $DB->get_field('chat_messages', 'timestamp', ['id' => $messageid]);
493 // Get the messages for this chat session.
494 $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC');
496 // We should have 3 user and 2 system (enter) messages.
497 $this->assertCount(5, $messages);
499 // Fetch the chat sessions from the messages we retrieved.
500 $sessions = chat_get_sessions($messages, true);
502 // There should be only one session.
503 $this->assertCount(1, $sessions);
505 // Get this session.
506 $session = reset($sessions);
508 // Confirm that the start and end times of the session matches.
509 $this->assertEquals($sessionstart, $session->sessionstart);
510 $this->assertEquals($sessionend, $session->sessionend);
511 // Confirm we have 2 participants in the chat.
512 $this->assertCount(2, $session->sessionusers);
516 * Test for chat_get_sessions with messages belonging to multiple sessions.
518 public function test_chat_get_sessions_multiple() {
519 $messages = [];
520 $gap = 5; // 5 secs.
522 $now = time();
523 $timestamp = $now;
525 // Messages belonging to 3 sessions. Session 1 has 10 messages, 2 has 15, 3 has 25.
526 $sessionusers = [];
527 $sessiontimes = [];
528 $session = 0; // Incomplete session.
529 for ($i = 1; $i <= 50; $i++) {
530 // Take note of expected session times as we go through.
531 switch ($i) {
532 case 1:
533 // Session 1 start time.
534 $sessiontimes[0]['start'] = $timestamp;
535 break;
536 case 10:
537 // Session 1 end time.
538 $sessiontimes[0]['end'] = $timestamp;
539 break;
540 case 11:
541 // Session 2 start time.
542 $sessiontimes[1]['start'] = $timestamp;
543 break;
544 case 25:
545 // Session 2 end time.
546 $sessiontimes[1]['end'] = $timestamp;
547 break;
548 case 26:
549 // Session 3 start time.
550 $sessiontimes[2]['start'] = $timestamp;
551 break;
552 case 50:
553 // Session 3 end time.
554 $sessiontimes[2]['end'] = $timestamp;
555 break;
558 // User 1 to 5.
559 $user = rand(1, 5);
561 // Let's also include system messages as well. Give them to pop in 1-in-10 chance.
562 $issystem = rand(1, 10) == 10;
564 if ($issystem) {
565 $message = 'enter';
566 } else {
567 $message = 'Message ' . $i;
568 if (!isset($sessionusers[$session][$user])) {
569 $sessionusers[$session][$user] = 1;
570 } else {
571 $sessionusers[$session][$user]++;
574 $messages[] = (object)[
575 'id' => $i,
576 'chatid' => 1,
577 'userid' => $user,
578 'message' => $message,
579 'issystem' => $issystem,
580 'timestamp' => $timestamp,
583 // Set the next timestamp.
584 if ($i == 10 || $i == 25) {
585 // New session.
586 $session++;
587 $timestamp += CHAT_SESSION_GAP + 1;
588 } else {
589 $timestamp += $gap;
592 // Reverse sort the messages so they're in descending order.
593 rsort($messages);
595 // Get chat sessions showing only complete ones.
596 $completesessions = chat_get_sessions($messages);
597 // Session 1 is incomplete, so there should only be 2 sessions when $showall is false.
598 $this->assertCount(2, $completesessions);
600 // Reverse sort sessions so they are in ascending order matching our expected session times and users.
601 $completesessions = array_reverse($completesessions);
602 foreach ($completesessions as $index => $session) {
603 // We increment index by 1 because the incomplete expected session (index=0) is not included.
604 $expectedindex = $index + 1;
606 // Check the session users.
607 $users = $sessionusers[$expectedindex];
608 $this->assertCount(count($users), $session->sessionusers);
609 // Check the message counts for each user in this session.
610 foreach ($users as $userid => $messagecount) {
611 $this->assertEquals($messagecount, $session->sessionusers[$userid]);
614 $sessionstart = $sessiontimes[$expectedindex]['start'];
615 $sessionend = $sessiontimes[$expectedindex]['end'];
616 $this->assertEquals($sessionstart, $session->sessionstart);
617 $this->assertEquals($sessionend, $session->sessionend);
620 // Get all the chat sessions.
621 $allsessions = chat_get_sessions($messages, true);
622 // When showall is true, we should get 3 sessions.
623 $this->assertCount(3, $allsessions);
625 // Reverse sort sessions so they are in ascending order matching our expected session times and users.
626 $allsessions = array_reverse($allsessions);
627 foreach ($allsessions as $index => $session) {
628 // Check the session users.
629 $users = $sessionusers[$index];
630 $this->assertCount(count($users), $session->sessionusers);
631 // Check the message counts for each user in this session.
632 foreach ($users as $userid => $messagecount) {
633 $this->assertEquals($messagecount, $session->sessionusers[$userid]);
636 $sessionstart = $sessiontimes[$index]['start'];
637 $sessionend = $sessiontimes[$index]['end'];
638 $this->assertEquals($sessionstart, $session->sessionstart);
639 $this->assertEquals($sessionend, $session->sessionend);
643 public function test_chat_core_calendar_provide_event_action_already_completed() {
644 set_config('enablecompletion', 1);
645 $this->setAdminUser();
647 // Create the activity.
648 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
649 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id),
650 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
652 // Get some additional data.
653 $cm = get_coursemodule_from_instance('chat', $chat->id);
655 // Create a calendar event.
656 $event = $this->create_action_event($course->id, $chat->id,
657 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
659 // Mark the activity as completed.
660 $completion = new \completion_info($course);
661 $completion->set_module_viewed($cm);
663 // Create an action factory.
664 $factory = new \core_calendar\action_factory();
666 // Decorate action event.
667 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory);
669 // Ensure result was null.
670 $this->assertNull($actionevent);
673 public function test_chat_core_calendar_provide_event_action_already_completed_for_user() {
674 set_config('enablecompletion', 1);
675 $this->setAdminUser();
677 // Create the activity.
678 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
679 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id),
680 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
682 // Enrol a student in the course.
683 $student = $this->getDataGenerator()->create_and_enrol($course, 'student');
685 // Get some additional data.
686 $cm = get_coursemodule_from_instance('chat', $chat->id);
688 // Create a calendar event.
689 $event = $this->create_action_event($course->id, $chat->id,
690 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
692 // Mark the activity as completed for the student.
693 $completion = new \completion_info($course);
694 $completion->set_module_viewed($cm, $student->id);
696 // Create an action factory.
697 $factory = new \core_calendar\action_factory();
699 // Decorate action event for the student.
700 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id);
702 // Ensure result was null.
703 $this->assertNull($actionevent);
707 * Creates an action event.
709 * @param int $courseid
710 * @param int $instanceid The chat id.
711 * @param string $eventtype The event type. eg. ASSIGN_EVENT_TYPE_DUE.
712 * @return bool|calendar_event
714 private function create_action_event($courseid, $instanceid, $eventtype) {
715 $event = new \stdClass();
716 $event->name = 'Calendar event';
717 $event->modulename = 'chat';
718 $event->courseid = $courseid;
719 $event->instance = $instanceid;
720 $event->type = CALENDAR_EVENT_TYPE_ACTION;
721 $event->eventtype = $eventtype;
722 $event->timestart = time();
724 return \calendar_event::create($event);
728 * A user who does not have capabilities to add events to the calendar should be able to create an chat.
730 public function test_creation_with_no_calendar_capabilities() {
731 $this->resetAfterTest();
732 $course = self::getDataGenerator()->create_course();
733 $context = \context_course::instance($course->id);
734 $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher');
735 $roleid = self::getDataGenerator()->create_role();
736 self::getDataGenerator()->role_assign($roleid, $user->id, $context->id);
737 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
738 $generator = self::getDataGenerator()->get_plugin_generator('mod_chat');
739 // Create an instance as a user without the calendar capabilities.
740 $this->setUser($user);
741 $params = array(
742 'course' => $course->id,
743 'chattime' => time() + 500,
745 $generator->create_instance($params);