diff --git a/mod/chat/tests/externallib_test.php b/mod/chat/tests/externallib_test.php index 2443f71d6b1..050753baaa6 100644 --- a/mod/chat/tests/externallib_test.php +++ b/mod/chat/tests/externallib_test.php @@ -428,7 +428,8 @@ class mod_chat_external_testcase extends externallib_advanced_testcase { $result = external_api::clean_returnvalue(mod_chat_external::get_sessions_returns(), $result); $this->assertCount(1, $result['sessions']); // One session. $this->assertTrue($result['sessions'][0]['iscomplete']); // Session complete. - $this->assertEquals($timenow - HOURSECS + 70, $result['sessions'][0]['sessionstart']); // First not system message time. + // The session started when user1 entered the chat. + $this->assertEquals($timenow - HOURSECS, $result['sessions'][0]['sessionstart']); $this->assertEmpty($result['warnings']); } diff --git a/mod/chat/tests/lib_test.php b/mod/chat/tests/lib_test.php index 4edef1aea5a..cd9c9e90aec 100644 --- a/mod/chat/tests/lib_test.php +++ b/mod/chat/tests/lib_test.php @@ -143,6 +143,201 @@ class mod_chat_lib_testcase extends advanced_testcase { $this->assertFalse($actionevent->is_actionable()); } + /** + * Test for chat_get_sessions(). + */ + public function test_chat_get_sessions() { + global $DB; + + $this->resetAfterTest(); + + $generator = $this->getDataGenerator(); + + // Setup test data. + $this->setAdminUser(); + $course = $generator->create_course(); + $chat = $generator->create_module('chat', ['course' => $course->id]); + + $user1 = $generator->create_user(); + $user2 = $generator->create_user(); + $studentrole = $DB->get_record('role', ['shortname' => 'student']); + $generator->enrol_user($user1->id, $course->id, $studentrole->id); + $generator->enrol_user($user2->id, $course->id, $studentrole->id); + + // Login as user 1. + $this->setUser($user1); + $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); + $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); + + // This is when the session starts (when the user enters the chat). + $sessionstart = $chatuser->lastping; + + // Send some messages. + chat_send_chatmessage($chatuser, 'hello!'); + chat_send_chatmessage($chatuser, 'bye bye!'); + + // Login as user 2. + $this->setUser($user2); + $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); + $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); + + // Send a message and take note of this message ID. + $messageid = chat_send_chatmessage($chatuser, 'greetings!'); + + // This is when the session ends (timestamp of the last message sent to the chat). + $sessionend = $DB->get_field('chat_messages', 'timestamp', ['id' => $messageid]); + + // Get the messages for this chat session. + $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC'); + + // We should have 3 user and 2 system (enter) messages. + $this->assertCount(5, $messages); + + // Fetch the chat sessions from the messages we retrieved. + $sessions = chat_get_sessions($messages, true); + + // There should be only one session. + $this->assertCount(1, $sessions); + + // Get this session. + $session = reset($sessions); + + // Confirm that the start and end times of the session matches. + $this->assertEquals($sessionstart, $session->sessionstart); + $this->assertEquals($sessionend, $session->sessionend); + // Confirm we have 2 participants in the chat. + $this->assertCount(2, $session->sessionusers); + } + + /** + * Test for chat_get_sessions with messages belonging to multiple sessions. + */ + public function test_chat_get_sessions_multiple() { + $messages = []; + $widegap = 5 * 60; // 5 mins. + $gap = 5; // 5 secs. + + $now = time(); + $timestamp = $now; + + // Messages belonging to 3 sessions. Session 1 has 10 messages, 2 has 15, 3 has 25. + $sessionusers = []; + $sessiontimes = []; + $session = 0; // Incomplete session. + for ($i = 1; $i <= 50; $i++) { + // Take note of expected session times as we go through. + switch ($i) { + case 1: + // Session 1 start time. + $sessiontimes[0]['start'] = $timestamp; + break; + case 10: + // Session 1 end time. + $sessiontimes[0]['end'] = $timestamp; + break; + case 11: + // Session 2 start time. + $sessiontimes[1]['start'] = $timestamp; + break; + case 25: + // Session 2 end time. + $sessiontimes[1]['end'] = $timestamp; + break; + case 26: + // Session 3 start time. + $sessiontimes[2]['start'] = $timestamp; + break; + case 50: + // Session 3 end time. + $sessiontimes[2]['end'] = $timestamp; + break; + } + + // User 1 to 5. + $user = rand(1, 5); + + // Let's also include system messages as well. Give them to pop in 1-in-10 chance. + $issystem = rand(1, 10) == 10; + + if ($issystem) { + $message = 'enter'; + } else { + $message = 'Message ' . $i; + if (!isset($sessionusers[$session][$user])) { + $sessionusers[$session][$user] = 1; + } else { + $sessionusers[$session][$user]++; + } + } + $messages[] = (object)[ + 'id' => $i, + 'chatid' => 1, + 'userid' => $user, + 'message' => $message, + 'issystem' => $issystem, + 'timestamp' => $timestamp, + ]; + + // Set the next timestamp. + if ($i == 10 || $i == 25) { + // New session. + $session++; + $timestamp += $widegap + 1; + } else { + $timestamp += $gap; + } + } + // Reverse sort the messages so they're in descending order. + rsort($messages); + + // Get chat sessions showing only complete ones. + $completesessions = chat_get_sessions($messages); + // Session 1 is incomplete, so there should only be 2 sessions when $showall is false. + $this->assertCount(2, $completesessions); + + // Reverse sort sessions so they are in ascending order matching our expected session times and users. + $completesessions = array_reverse($completesessions); + foreach ($completesessions as $index => $session) { + // We increment index by 1 because the incomplete expected session (index=0) is not included. + $expectedindex = $index + 1; + + // Check the session users. + $users = $sessionusers[$expectedindex]; + $this->assertCount(count($users), $session->sessionusers); + // Check the message counts for each user in this session. + foreach ($users as $userid => $messagecount) { + $this->assertEquals($messagecount, $session->sessionusers[$userid]); + } + + $sessionstart = $sessiontimes[$expectedindex]['start']; + $sessionend = $sessiontimes[$expectedindex]['end']; + $this->assertEquals($sessionstart, $session->sessionstart); + $this->assertEquals($sessionend, $session->sessionend); + } + + // Get all the chat sessions. + $allsessions = chat_get_sessions($messages, true); + // When showall is true, we should get 3 sessions. + $this->assertCount(3, $allsessions); + + // Reverse sort sessions so they are in ascending order matching our expected session times and users. + $allsessions = array_reverse($allsessions); + foreach ($allsessions as $index => $session) { + // Check the session users. + $users = $sessionusers[$index]; + $this->assertCount(count($users), $session->sessionusers); + // Check the message counts for each user in this session. + foreach ($users as $userid => $messagecount) { + $this->assertEquals($messagecount, $session->sessionusers[$userid]); + } + + $sessionstart = $sessiontimes[$index]['start']; + $sessionend = $sessiontimes[$index]['end']; + $this->assertEquals($sessionstart, $session->sessionstart); + $this->assertEquals($sessionend, $session->sessionend); + } + } + /** * Creates an action event. *