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