See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Contains class containing unit tests for mod/chat/lib.php. 19 * 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 24 */ 25 namespace mod_chat; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 /** 30 * Class containing unit tests for mod/chat/lib.php. 31 * 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 36 */ 37 class lib_test extends \advanced_testcase { 38 39 public function setUp(): void { 40 $this->resetAfterTest(); 41 } 42 43 /* 44 * The chat's event should not be shown to a user when the user cannot view the chat at all. 45 */ 46 public function test_chat_core_calendar_provide_event_action_in_hidden_section() { 47 global $CFG; 48 49 $this->setAdminUser(); 50 51 // Create a course. 52 $course = $this->getDataGenerator()->create_course(); 53 54 // Create a student. 55 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 56 57 // Create a chat. 58 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 59 'chattime' => usergetmidnight(time()))); 60 61 // Create a calendar event. 62 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 63 64 // Set sections 0 as hidden. 65 set_section_visible($course->id, 0, 0); 66 67 // Now, log out. 68 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 69 $this->setUser(); 70 71 // Create an action factory. 72 $factory = new \core_calendar\action_factory(); 73 74 // Decorate action event for the student. 75 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 76 77 // Confirm the event is not shown at all. 78 $this->assertNull($actionevent); 79 } 80 81 /* 82 * The chat's event should not be shown to a user who does not have permission to view the chat at all. 83 */ 84 public function test_chat_core_calendar_provide_event_action_for_non_user() { 85 global $CFG; 86 87 $this->setAdminUser(); 88 89 // Create a course. 90 $course = $this->getDataGenerator()->create_course(); 91 92 // Create a chat. 93 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 94 'chattime' => usergetmidnight(time()))); 95 96 // Create a calendar event. 97 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 98 99 // Now, log out. 100 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities. 101 $this->setUser(); 102 103 // Create an action factory. 104 $factory = new \core_calendar\action_factory(); 105 106 // Decorate action event. 107 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 108 109 // Confirm the event is not shown at all. 110 $this->assertNull($actionevent); 111 } 112 113 public function test_chat_core_calendar_provide_event_action_chattime_event_yesterday() { 114 $this->setAdminUser(); 115 116 // Create a course. 117 $course = $this->getDataGenerator()->create_course(); 118 119 // Create a chat. 120 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 121 'chattime' => time() - DAYSECS)); 122 123 // Create a calendar event. 124 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 125 126 // Create an action factory. 127 $factory = new \core_calendar\action_factory(); 128 129 // Decorate action event. 130 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 131 132 // Confirm the event is not shown at all. 133 $this->assertNull($actionevent); 134 } 135 136 public function test_chat_core_calendar_provide_event_action_chattime_event_yesterday_for_user() { 137 global $CFG; 138 139 $this->setAdminUser(); 140 141 // Create a course. 142 $course = $this->getDataGenerator()->create_course(); 143 144 // Enrol a student in the course. 145 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 146 147 // Create a chat. 148 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 149 'chattime' => time() - DAYSECS)); 150 151 // Create a calendar event. 152 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 153 154 // Now, log out. 155 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default. 156 $this->setUser(); 157 158 // Create an action factory. 159 $factory = new \core_calendar\action_factory(); 160 161 // Decorate action event for the student. 162 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 163 164 // Confirm the event is not shown at all. 165 $this->assertNull($actionevent); 166 } 167 168 public function test_chat_core_calendar_provide_event_action_chattime_event_today() { 169 $this->setAdminUser(); 170 171 // Create a course. 172 $course = $this->getDataGenerator()->create_course(); 173 174 // Create a chat. 175 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 176 'chattime' => usergetmidnight(time()))); 177 178 // Create a calendar event. 179 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 180 181 // Create an action factory. 182 $factory = new \core_calendar\action_factory(); 183 184 // Decorate action event. 185 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 186 187 // Confirm the event was decorated. 188 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 189 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 190 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 191 $this->assertEquals(1, $actionevent->get_item_count()); 192 $this->assertTrue($actionevent->is_actionable()); 193 } 194 195 public function test_chat_core_calendar_provide_event_action_chattime_event_today_for_user() { 196 global $CFG; 197 198 $this->setAdminUser(); 199 200 // Create a course. 201 $course = $this->getDataGenerator()->create_course(); 202 203 // Enrol a student in the course. 204 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 205 206 // Create a chat. 207 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 208 'chattime' => usergetmidnight(time()))); 209 210 // Create a calendar event. 211 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 212 213 // Now, log out. 214 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default. 215 $this->setUser(); 216 217 // Create an action factory. 218 $factory = new \core_calendar\action_factory(); 219 220 // Decorate action event for the student. 221 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 222 223 // Confirm the event was decorated. 224 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 225 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 226 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 227 $this->assertEquals(1, $actionevent->get_item_count()); 228 $this->assertTrue($actionevent->is_actionable()); 229 } 230 231 public function test_chat_core_calendar_provide_event_action_chattime_event_tonight() { 232 $this->setAdminUser(); 233 234 // Create a course. 235 $course = $this->getDataGenerator()->create_course(); 236 237 // Create a chat. 238 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 239 'chattime' => usergetmidnight(time()) + (23 * HOURSECS))); 240 241 // Create a calendar event. 242 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 243 244 // Create an action factory. 245 $factory = new \core_calendar\action_factory(); 246 247 // Decorate action event. 248 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 249 250 // Confirm the event was decorated. 251 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 252 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 253 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 254 $this->assertEquals(1, $actionevent->get_item_count()); 255 $this->assertTrue($actionevent->is_actionable()); 256 } 257 258 public function test_chat_core_calendar_provide_event_action_chattime_event_tonight_for_user() { 259 global $CFG; 260 261 $this->setAdminUser(); 262 263 // Create a course. 264 $course = $this->getDataGenerator()->create_course(); 265 266 // Enrol a student in the course. 267 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 268 269 // Create a chat. 270 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 271 'chattime' => usergetmidnight(time()) + (23 * HOURSECS))); 272 273 // Create a calendar event. 274 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 275 276 // Now, log out. 277 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default. 278 $this->setUser(); 279 280 // Create an action factory. 281 $factory = new \core_calendar\action_factory(); 282 283 // Decorate action event for the student. 284 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 285 286 // Confirm the event was decorated. 287 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 288 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 289 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 290 $this->assertEquals(1, $actionevent->get_item_count()); 291 $this->assertTrue($actionevent->is_actionable()); 292 } 293 294 public function test_chat_core_calendar_provide_event_action_chattime_event_tomorrow() { 295 $this->setAdminUser(); 296 297 // Create a course. 298 $course = $this->getDataGenerator()->create_course(); 299 300 // Create a chat. 301 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 302 'chattime' => time() + DAYSECS)); 303 304 // Create a calendar event. 305 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 306 307 // Create an action factory. 308 $factory = new \core_calendar\action_factory(); 309 310 // Decorate action event. 311 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 312 313 // Confirm the event was decorated. 314 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 315 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 316 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 317 $this->assertEquals(1, $actionevent->get_item_count()); 318 $this->assertFalse($actionevent->is_actionable()); 319 } 320 321 public function test_chat_core_calendar_provide_event_action_chattime_event_tomorrow_for_user() { 322 global $CFG; 323 324 $this->setAdminUser(); 325 326 // Create a course. 327 $course = $this->getDataGenerator()->create_course(); 328 329 // Enrol a student in the course. 330 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 331 332 // Create a chat. 333 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 334 'chattime' => time() + DAYSECS)); 335 336 // Create a calendar event. 337 $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); 338 339 // Now, log out. 340 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default. 341 $this->setUser(); 342 343 // Create an action factory. 344 $factory = new \core_calendar\action_factory(); 345 346 // Decorate action event for the student. 347 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 348 349 // Confirm the event was decorated. 350 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); 351 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); 352 $this->assertInstanceOf('moodle_url', $actionevent->get_url()); 353 $this->assertEquals(1, $actionevent->get_item_count()); 354 $this->assertFalse($actionevent->is_actionable()); 355 } 356 357 public function test_chat_core_calendar_provide_event_action_chattime_event_different_timezones() { 358 global $CFG; 359 360 $this->setAdminUser(); 361 362 // Create a course. 363 $course = $this->getDataGenerator()->create_course(); 364 365 $hour = gmdate('H'); 366 367 // This could have been much easier if MDL-37327 were implemented. 368 // We don't know when this test is being ran and there is no standard way to 369 // mock the time() function (MDL-37327 to handle that). 370 if ($hour < 10) { 371 $timezone1 = 'UTC'; // GMT. 372 $timezone2 = 'Pacific/Pago_Pago'; // GMT -11:00. 373 } else if ($hour < 11) { 374 $timezone1 = 'Pacific/Kiritimati'; // GMT +14:00. 375 $timezone2 = 'America/Sao_Paulo'; // GMT -03:00. 376 } else { 377 $timezone1 = 'Pacific/Kiritimati'; // GMT +14:00. 378 $timezone2 = 'UTC'; // GMT. 379 } 380 381 $this->setTimezone($timezone2); 382 383 // Enrol 2 students with different timezones in the course. 384 $student1 = $this->getDataGenerator()->create_and_enrol($course, 'student', (object)['timezone' => $timezone1]); 385 $student2 = $this->getDataGenerator()->create_and_enrol($course, 'student', (object)['timezone' => $timezone2]); 386 387 // Create a chat. 388 $chat1 = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 389 'chattime' => mktime(1, 0, 0))); // This is always yesterday in timezone1 time 390 // and always today in timezone2 time. 391 392 // Create a chat. 393 $chat2 = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, 394 'chattime' => mktime(1, 0, 0) + DAYSECS)); // This is always today in timezone1 time 395 // and always tomorrow in timezone2 time. 396 397 // Create calendar events for the 2 chats above. 398 $event1 = $this->create_action_event($course->id, $chat1->id, CHAT_EVENT_TYPE_CHATTIME); 399 $event2 = $this->create_action_event($course->id, $chat2->id, CHAT_EVENT_TYPE_CHATTIME); 400 401 // Now, log out. 402 $CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users have mod/chat:view capability by default. 403 $this->setUser(); 404 405 // Create an action factory. 406 $factory = new \core_calendar\action_factory(); 407 408 // Decorate action event for student1. 409 $actionevent11 = mod_chat_core_calendar_provide_event_action($event1, $factory, $student1->id); 410 $actionevent12 = mod_chat_core_calendar_provide_event_action($event1, $factory, $student2->id); 411 $actionevent21 = mod_chat_core_calendar_provide_event_action($event2, $factory, $student1->id); 412 $actionevent22 = mod_chat_core_calendar_provide_event_action($event2, $factory, $student2->id); 413 414 // Confirm event1 is not shown to student1 at all. 415 $this->assertNull($actionevent11, 'Failed for UTC time ' . gmdate('H:i')); 416 417 // Confirm event1 was decorated for student2 and it is actionable. 418 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent12); 419 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent12->get_name()); 420 $this->assertInstanceOf('moodle_url', $actionevent12->get_url()); 421 $this->assertEquals(1, $actionevent12->get_item_count()); 422 $this->assertTrue($actionevent12->is_actionable()); 423 424 // Confirm event2 was decorated for student1 and it is actionable. 425 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent21); 426 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent21->get_name()); 427 $this->assertInstanceOf('moodle_url', $actionevent21->get_url()); 428 $this->assertEquals(1, $actionevent21->get_item_count()); 429 $this->assertTrue($actionevent21->is_actionable()); 430 431 // Confirm event2 was decorated for student2 and it is not actionable. 432 $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent22); 433 $this->assertEquals(get_string('enterchat', 'chat'), $actionevent22->get_name()); 434 $this->assertInstanceOf('moodle_url', $actionevent22->get_url()); 435 $this->assertEquals(1, $actionevent22->get_item_count()); 436 $this->assertFalse($actionevent22->is_actionable()); 437 } 438 439 /** 440 * Test for chat_get_sessions(). 441 */ 442 public function test_chat_get_sessions() { 443 global $DB; 444 445 $this->resetAfterTest(); 446 447 $generator = $this->getDataGenerator(); 448 449 // Setup test data. 450 $this->setAdminUser(); 451 $course = $generator->create_course(); 452 $chat = $generator->create_module('chat', ['course' => $course->id]); 453 454 $user1 = $generator->create_user(); 455 $user2 = $generator->create_user(); 456 $studentrole = $DB->get_record('role', ['shortname' => 'student']); 457 $generator->enrol_user($user1->id, $course->id, $studentrole->id); 458 $generator->enrol_user($user2->id, $course->id, $studentrole->id); 459 460 // Login as user 1. 461 $this->setUser($user1); 462 $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); 463 $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); 464 465 // Get the messages for this chat session. 466 $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC'); 467 468 // We should have just 1 system (enter) messages. 469 $this->assertCount(1, $messages); 470 471 // This is when the session starts (when the first message - enter - has been sent). 472 $sessionstart = reset($messages)->timestamp; 473 474 // Send some messages. 475 chat_send_chatmessage($chatuser, 'hello!'); 476 chat_send_chatmessage($chatuser, 'bye bye!'); 477 478 // Login as user 2. 479 $this->setUser($user2); 480 $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); 481 $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); 482 483 // Send a message and take note of this message ID. 484 $messageid = chat_send_chatmessage($chatuser, 'greetings!'); 485 486 // This is when the session ends (timestamp of the last message sent to the chat). 487 $sessionend = $DB->get_field('chat_messages', 'timestamp', ['id' => $messageid]); 488 489 // Get the messages for this chat session. 490 $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC'); 491 492 // We should have 3 user and 2 system (enter) messages. 493 $this->assertCount(5, $messages); 494 495 // Fetch the chat sessions from the messages we retrieved. 496 $sessions = chat_get_sessions($messages, true); 497 498 // There should be only one session. 499 $this->assertCount(1, $sessions); 500 501 // Get this session. 502 $session = reset($sessions); 503 504 // Confirm that the start and end times of the session matches. 505 $this->assertEquals($sessionstart, $session->sessionstart); 506 $this->assertEquals($sessionend, $session->sessionend); 507 // Confirm we have 2 participants in the chat. 508 $this->assertCount(2, $session->sessionusers); 509 } 510 511 /** 512 * Test for chat_get_sessions with messages belonging to multiple sessions. 513 */ 514 public function test_chat_get_sessions_multiple() { 515 $messages = []; 516 $gap = 5; // 5 secs. 517 518 $now = time(); 519 $timestamp = $now; 520 521 // Messages belonging to 3 sessions. Session 1 has 10 messages, 2 has 15, 3 has 25. 522 $sessionusers = []; 523 $sessiontimes = []; 524 $session = 0; // Incomplete session. 525 for ($i = 1; $i <= 50; $i++) { 526 // Take note of expected session times as we go through. 527 switch ($i) { 528 case 1: 529 // Session 1 start time. 530 $sessiontimes[0]['start'] = $timestamp; 531 break; 532 case 10: 533 // Session 1 end time. 534 $sessiontimes[0]['end'] = $timestamp; 535 break; 536 case 11: 537 // Session 2 start time. 538 $sessiontimes[1]['start'] = $timestamp; 539 break; 540 case 25: 541 // Session 2 end time. 542 $sessiontimes[1]['end'] = $timestamp; 543 break; 544 case 26: 545 // Session 3 start time. 546 $sessiontimes[2]['start'] = $timestamp; 547 break; 548 case 50: 549 // Session 3 end time. 550 $sessiontimes[2]['end'] = $timestamp; 551 break; 552 } 553 554 // User 1 to 5. 555 $user = rand(1, 5); 556 557 // Let's also include system messages as well. Give them to pop in 1-in-10 chance. 558 $issystem = rand(1, 10) == 10; 559 560 if ($issystem) { 561 $message = 'enter'; 562 } else { 563 $message = 'Message ' . $i; 564 if (!isset($sessionusers[$session][$user])) { 565 $sessionusers[$session][$user] = 1; 566 } else { 567 $sessionusers[$session][$user]++; 568 } 569 } 570 $messages[] = (object)[ 571 'id' => $i, 572 'chatid' => 1, 573 'userid' => $user, 574 'message' => $message, 575 'issystem' => $issystem, 576 'timestamp' => $timestamp, 577 ]; 578 579 // Set the next timestamp. 580 if ($i == 10 || $i == 25) { 581 // New session. 582 $session++; 583 $timestamp += CHAT_SESSION_GAP + 1; 584 } else { 585 $timestamp += $gap; 586 } 587 } 588 // Reverse sort the messages so they're in descending order. 589 rsort($messages); 590 591 // Get chat sessions showing only complete ones. 592 $completesessions = chat_get_sessions($messages); 593 // Session 1 is incomplete, so there should only be 2 sessions when $showall is false. 594 $this->assertCount(2, $completesessions); 595 596 // Reverse sort sessions so they are in ascending order matching our expected session times and users. 597 $completesessions = array_reverse($completesessions); 598 foreach ($completesessions as $index => $session) { 599 // We increment index by 1 because the incomplete expected session (index=0) is not included. 600 $expectedindex = $index + 1; 601 602 // Check the session users. 603 $users = $sessionusers[$expectedindex]; 604 $this->assertCount(count($users), $session->sessionusers); 605 // Check the message counts for each user in this session. 606 foreach ($users as $userid => $messagecount) { 607 $this->assertEquals($messagecount, $session->sessionusers[$userid]); 608 } 609 610 $sessionstart = $sessiontimes[$expectedindex]['start']; 611 $sessionend = $sessiontimes[$expectedindex]['end']; 612 $this->assertEquals($sessionstart, $session->sessionstart); 613 $this->assertEquals($sessionend, $session->sessionend); 614 } 615 616 // Get all the chat sessions. 617 $allsessions = chat_get_sessions($messages, true); 618 // When showall is true, we should get 3 sessions. 619 $this->assertCount(3, $allsessions); 620 621 // Reverse sort sessions so they are in ascending order matching our expected session times and users. 622 $allsessions = array_reverse($allsessions); 623 foreach ($allsessions as $index => $session) { 624 // Check the session users. 625 $users = $sessionusers[$index]; 626 $this->assertCount(count($users), $session->sessionusers); 627 // Check the message counts for each user in this session. 628 foreach ($users as $userid => $messagecount) { 629 $this->assertEquals($messagecount, $session->sessionusers[$userid]); 630 } 631 632 $sessionstart = $sessiontimes[$index]['start']; 633 $sessionend = $sessiontimes[$index]['end']; 634 $this->assertEquals($sessionstart, $session->sessionstart); 635 $this->assertEquals($sessionend, $session->sessionend); 636 } 637 } 638 639 public function test_chat_core_calendar_provide_event_action_already_completed() { 640 set_config('enablecompletion', 1); 641 $this->setAdminUser(); 642 643 // Create the activity. 644 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 645 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id), 646 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 647 648 // Get some additional data. 649 $cm = get_coursemodule_from_instance('chat', $chat->id); 650 651 // Create a calendar event. 652 $event = $this->create_action_event($course->id, $chat->id, 653 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 654 655 // Mark the activity as completed. 656 $completion = new \completion_info($course); 657 $completion->set_module_viewed($cm); 658 659 // Create an action factory. 660 $factory = new \core_calendar\action_factory(); 661 662 // Decorate action event. 663 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); 664 665 // Ensure result was null. 666 $this->assertNull($actionevent); 667 } 668 669 public function test_chat_core_calendar_provide_event_action_already_completed_for_user() { 670 set_config('enablecompletion', 1); 671 $this->setAdminUser(); 672 673 // Create the activity. 674 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); 675 $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id), 676 array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS)); 677 678 // Enrol a student in the course. 679 $student = $this->getDataGenerator()->create_and_enrol($course, 'student'); 680 681 // Get some additional data. 682 $cm = get_coursemodule_from_instance('chat', $chat->id); 683 684 // Create a calendar event. 685 $event = $this->create_action_event($course->id, $chat->id, 686 \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED); 687 688 // Mark the activity as completed for the student. 689 $completion = new \completion_info($course); 690 $completion->set_module_viewed($cm, $student->id); 691 692 // Create an action factory. 693 $factory = new \core_calendar\action_factory(); 694 695 // Decorate action event for the student. 696 $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory, $student->id); 697 698 // Ensure result was null. 699 $this->assertNull($actionevent); 700 } 701 702 /** 703 * Creates an action event. 704 * 705 * @param int $courseid 706 * @param int $instanceid The chat id. 707 * @param string $eventtype The event type. eg. ASSIGN_EVENT_TYPE_DUE. 708 * @return bool|calendar_event 709 */ 710 private function create_action_event($courseid, $instanceid, $eventtype) { 711 $event = new \stdClass(); 712 $event->name = 'Calendar event'; 713 $event->modulename = 'chat'; 714 $event->courseid = $courseid; 715 $event->instance = $instanceid; 716 $event->type = CALENDAR_EVENT_TYPE_ACTION; 717 $event->eventtype = $eventtype; 718 $event->timestart = time(); 719 720 return \calendar_event::create($event); 721 } 722 723 /** 724 * A user who does not have capabilities to add events to the calendar should be able to create an chat. 725 */ 726 public function test_creation_with_no_calendar_capabilities() { 727 $this->resetAfterTest(); 728 $course = self::getDataGenerator()->create_course(); 729 $context = \context_course::instance($course->id); 730 $user = self::getDataGenerator()->create_and_enrol($course, 'editingteacher'); 731 $roleid = self::getDataGenerator()->create_role(); 732 self::getDataGenerator()->role_assign($roleid, $user->id, $context->id); 733 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); 734 $generator = self::getDataGenerator()->get_plugin_generator('mod_chat'); 735 // Create an instance as a user without the calendar capabilities. 736 $this->setUser($user); 737 $params = array( 738 'course' => $course->id, 739 'chattime' => time() + 500, 740 ); 741 $generator->create_instance($params); 742 } 743 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body