Commit | Line | Data |
---|---|---|
bea71d57 MN |
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() { | |
39 | $this->resetAfterTest(); | |
40 | } | |
41 | ||
3b2be06b | 42 | public function test_chat_core_calendar_provide_event_action_chattime_event_yesterday() { |
bea71d57 MN |
43 | $this->setAdminUser(); |
44 | ||
45 | // Create a course. | |
46 | $course = $this->getDataGenerator()->create_course(); | |
47 | ||
48 | // Create a chat. | |
3b2be06b AN |
49 | $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, |
50 | 'chattime' => time() - DAYSECS)); | |
bea71d57 MN |
51 | |
52 | // Create a calendar event. | |
53 | $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); | |
54 | ||
73be2a88 AN |
55 | // Create an action factory. |
56 | $factory = new \core_calendar\action_factory(); | |
57 | ||
73be2a88 AN |
58 | // Decorate action event. |
59 | $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); | |
60 | ||
3b2be06b | 61 | // Confirm the event is not shown at all. |
73be2a88 | 62 | $this->assertNull($actionevent); |
bea71d57 MN |
63 | } |
64 | ||
3b2be06b | 65 | public function test_chat_core_calendar_provide_event_action_chattime_event_today() { |
bea71d57 MN |
66 | $this->setAdminUser(); |
67 | ||
68 | // Create a course. | |
69 | $course = $this->getDataGenerator()->create_course(); | |
70 | ||
71 | // Create a chat. | |
3b2be06b AN |
72 | $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, |
73 | 'chattime' => usergetmidnight(time()))); | |
74 | ||
75 | // Create a calendar event. | |
76 | $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); | |
77 | ||
78 | // Create an action factory. | |
79 | $factory = new \core_calendar\action_factory(); | |
80 | ||
81 | // Decorate action event. | |
82 | $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); | |
83 | ||
84 | // Confirm the event was decorated. | |
85 | $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); | |
86 | $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); | |
87 | $this->assertInstanceOf('moodle_url', $actionevent->get_url()); | |
88 | $this->assertEquals(1, $actionevent->get_item_count()); | |
89 | $this->assertTrue($actionevent->is_actionable()); | |
90 | } | |
91 | ||
92 | public function test_chat_core_calendar_provide_event_action_chattime_event_tonight() { | |
93 | $this->setAdminUser(); | |
94 | ||
95 | // Create a course. | |
96 | $course = $this->getDataGenerator()->create_course(); | |
97 | ||
98 | // Create a chat. | |
99 | $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, | |
100 | 'chattime' => usergetmidnight(time()) + (23 * HOURSECS))); | |
bea71d57 MN |
101 | |
102 | // Create a calendar event. | |
103 | $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); | |
104 | ||
105 | // Create an action factory. | |
106 | $factory = new \core_calendar\action_factory(); | |
107 | ||
108 | // Decorate action event. | |
109 | $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); | |
110 | ||
111 | // Confirm the event was decorated. | |
112 | $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); | |
113 | $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); | |
114 | $this->assertInstanceOf('moodle_url', $actionevent->get_url()); | |
115 | $this->assertEquals(1, $actionevent->get_item_count()); | |
116 | $this->assertTrue($actionevent->is_actionable()); | |
117 | } | |
118 | ||
3b2be06b | 119 | public function test_chat_core_calendar_provide_event_action_chattime_event_tomorrow() { |
bea71d57 MN |
120 | $this->setAdminUser(); |
121 | ||
122 | // Create a course. | |
123 | $course = $this->getDataGenerator()->create_course(); | |
124 | ||
125 | // Create a chat. | |
126 | $chat = $this->getDataGenerator()->create_module('chat', array('course' => $course->id, | |
127 | 'chattime' => time() + DAYSECS)); | |
128 | ||
129 | // Create a calendar event. | |
130 | $event = $this->create_action_event($course->id, $chat->id, CHAT_EVENT_TYPE_CHATTIME); | |
131 | ||
132 | // Create an action factory. | |
133 | $factory = new \core_calendar\action_factory(); | |
134 | ||
135 | // Decorate action event. | |
136 | $actionevent = mod_chat_core_calendar_provide_event_action($event, $factory); | |
137 | ||
138 | // Confirm the event was decorated. | |
139 | $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent); | |
140 | $this->assertEquals(get_string('enterchat', 'chat'), $actionevent->get_name()); | |
141 | $this->assertInstanceOf('moodle_url', $actionevent->get_url()); | |
142 | $this->assertEquals(1, $actionevent->get_item_count()); | |
143 | $this->assertFalse($actionevent->is_actionable()); | |
144 | } | |
145 | ||
70175dbe JP |
146 | /** |
147 | * Test for chat_get_sessions(). | |
148 | */ | |
149 | public function test_chat_get_sessions() { | |
150 | global $DB; | |
151 | ||
152 | $this->resetAfterTest(); | |
153 | ||
154 | $generator = $this->getDataGenerator(); | |
155 | ||
156 | // Setup test data. | |
157 | $this->setAdminUser(); | |
158 | $course = $generator->create_course(); | |
159 | $chat = $generator->create_module('chat', ['course' => $course->id]); | |
160 | ||
161 | $user1 = $generator->create_user(); | |
162 | $user2 = $generator->create_user(); | |
163 | $studentrole = $DB->get_record('role', ['shortname' => 'student']); | |
164 | $generator->enrol_user($user1->id, $course->id, $studentrole->id); | |
165 | $generator->enrol_user($user2->id, $course->id, $studentrole->id); | |
166 | ||
167 | // Login as user 1. | |
168 | $this->setUser($user1); | |
169 | $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); | |
170 | $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); | |
171 | ||
2bf974e7 EL |
172 | // Get the messages for this chat session. |
173 | $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC'); | |
174 | ||
175 | // We should have just 1 system (enter) messages. | |
176 | $this->assertCount(1, $messages); | |
177 | ||
178 | // This is when the session starts (when the first message - enter - has been sent). | |
179 | $sessionstart = reset($messages)->timestamp; | |
70175dbe JP |
180 | |
181 | // Send some messages. | |
182 | chat_send_chatmessage($chatuser, 'hello!'); | |
183 | chat_send_chatmessage($chatuser, 'bye bye!'); | |
184 | ||
185 | // Login as user 2. | |
186 | $this->setUser($user2); | |
187 | $chatsid = chat_login_user($chat->id, 'ajax', 0, $course); | |
188 | $chatuser = $DB->get_record('chat_users', ['sid' => $chatsid]); | |
189 | ||
190 | // Send a message and take note of this message ID. | |
191 | $messageid = chat_send_chatmessage($chatuser, 'greetings!'); | |
192 | ||
193 | // This is when the session ends (timestamp of the last message sent to the chat). | |
194 | $sessionend = $DB->get_field('chat_messages', 'timestamp', ['id' => $messageid]); | |
195 | ||
196 | // Get the messages for this chat session. | |
197 | $messages = chat_get_session_messages($chat->id, false, 0, 0, 'timestamp DESC'); | |
198 | ||
199 | // We should have 3 user and 2 system (enter) messages. | |
200 | $this->assertCount(5, $messages); | |
201 | ||
202 | // Fetch the chat sessions from the messages we retrieved. | |
203 | $sessions = chat_get_sessions($messages, true); | |
204 | ||
205 | // There should be only one session. | |
206 | $this->assertCount(1, $sessions); | |
207 | ||
208 | // Get this session. | |
209 | $session = reset($sessions); | |
210 | ||
211 | // Confirm that the start and end times of the session matches. | |
212 | $this->assertEquals($sessionstart, $session->sessionstart); | |
213 | $this->assertEquals($sessionend, $session->sessionend); | |
214 | // Confirm we have 2 participants in the chat. | |
215 | $this->assertCount(2, $session->sessionusers); | |
216 | } | |
217 | ||
218 | /** | |
219 | * Test for chat_get_sessions with messages belonging to multiple sessions. | |
220 | */ | |
221 | public function test_chat_get_sessions_multiple() { | |
222 | $messages = []; | |
70175dbe JP |
223 | $gap = 5; // 5 secs. |
224 | ||
225 | $now = time(); | |
226 | $timestamp = $now; | |
227 | ||
228 | // Messages belonging to 3 sessions. Session 1 has 10 messages, 2 has 15, 3 has 25. | |
229 | $sessionusers = []; | |
230 | $sessiontimes = []; | |
231 | $session = 0; // Incomplete session. | |
232 | for ($i = 1; $i <= 50; $i++) { | |
233 | // Take note of expected session times as we go through. | |
234 | switch ($i) { | |
235 | case 1: | |
236 | // Session 1 start time. | |
237 | $sessiontimes[0]['start'] = $timestamp; | |
238 | break; | |
239 | case 10: | |
240 | // Session 1 end time. | |
241 | $sessiontimes[0]['end'] = $timestamp; | |
242 | break; | |
243 | case 11: | |
244 | // Session 2 start time. | |
245 | $sessiontimes[1]['start'] = $timestamp; | |
246 | break; | |
247 | case 25: | |
248 | // Session 2 end time. | |
249 | $sessiontimes[1]['end'] = $timestamp; | |
250 | break; | |
251 | case 26: | |
252 | // Session 3 start time. | |
253 | $sessiontimes[2]['start'] = $timestamp; | |
254 | break; | |
255 | case 50: | |
256 | // Session 3 end time. | |
257 | $sessiontimes[2]['end'] = $timestamp; | |
258 | break; | |
259 | } | |
260 | ||
261 | // User 1 to 5. | |
262 | $user = rand(1, 5); | |
263 | ||
264 | // Let's also include system messages as well. Give them to pop in 1-in-10 chance. | |
265 | $issystem = rand(1, 10) == 10; | |
266 | ||
267 | if ($issystem) { | |
268 | $message = 'enter'; | |
269 | } else { | |
270 | $message = 'Message ' . $i; | |
271 | if (!isset($sessionusers[$session][$user])) { | |
272 | $sessionusers[$session][$user] = 1; | |
273 | } else { | |
274 | $sessionusers[$session][$user]++; | |
275 | } | |
276 | } | |
277 | $messages[] = (object)[ | |
278 | 'id' => $i, | |
279 | 'chatid' => 1, | |
280 | 'userid' => $user, | |
281 | 'message' => $message, | |
282 | 'issystem' => $issystem, | |
283 | 'timestamp' => $timestamp, | |
284 | ]; | |
285 | ||
286 | // Set the next timestamp. | |
287 | if ($i == 10 || $i == 25) { | |
288 | // New session. | |
289 | $session++; | |
64818f40 | 290 | $timestamp += CHAT_SESSION_GAP + 1; |
70175dbe JP |
291 | } else { |
292 | $timestamp += $gap; | |
293 | } | |
294 | } | |
295 | // Reverse sort the messages so they're in descending order. | |
296 | rsort($messages); | |
297 | ||
298 | // Get chat sessions showing only complete ones. | |
299 | $completesessions = chat_get_sessions($messages); | |
300 | // Session 1 is incomplete, so there should only be 2 sessions when $showall is false. | |
301 | $this->assertCount(2, $completesessions); | |
302 | ||
303 | // Reverse sort sessions so they are in ascending order matching our expected session times and users. | |
304 | $completesessions = array_reverse($completesessions); | |
305 | foreach ($completesessions as $index => $session) { | |
306 | // We increment index by 1 because the incomplete expected session (index=0) is not included. | |
307 | $expectedindex = $index + 1; | |
308 | ||
309 | // Check the session users. | |
310 | $users = $sessionusers[$expectedindex]; | |
311 | $this->assertCount(count($users), $session->sessionusers); | |
312 | // Check the message counts for each user in this session. | |
313 | foreach ($users as $userid => $messagecount) { | |
314 | $this->assertEquals($messagecount, $session->sessionusers[$userid]); | |
315 | } | |
316 | ||
317 | $sessionstart = $sessiontimes[$expectedindex]['start']; | |
318 | $sessionend = $sessiontimes[$expectedindex]['end']; | |
319 | $this->assertEquals($sessionstart, $session->sessionstart); | |
320 | $this->assertEquals($sessionend, $session->sessionend); | |
321 | } | |
322 | ||
323 | // Get all the chat sessions. | |
324 | $allsessions = chat_get_sessions($messages, true); | |
325 | // When showall is true, we should get 3 sessions. | |
326 | $this->assertCount(3, $allsessions); | |
327 | ||
328 | // Reverse sort sessions so they are in ascending order matching our expected session times and users. | |
329 | $allsessions = array_reverse($allsessions); | |
330 | foreach ($allsessions as $index => $session) { | |
331 | // Check the session users. | |
332 | $users = $sessionusers[$index]; | |
333 | $this->assertCount(count($users), $session->sessionusers); | |
334 | // Check the message counts for each user in this session. | |
335 | foreach ($users as $userid => $messagecount) { | |
336 | $this->assertEquals($messagecount, $session->sessionusers[$userid]); | |
337 | } | |
338 | ||
339 | $sessionstart = $sessiontimes[$index]['start']; | |
340 | $sessionend = $sessiontimes[$index]['end']; | |
341 | $this->assertEquals($sessionstart, $session->sessionstart); | |
342 | $this->assertEquals($sessionend, $session->sessionend); | |
343 | } | |
344 | } | |
345 | ||
bea71d57 MN |
346 | /** |
347 | * Creates an action event. | |
348 | * | |
349 | * @param int $courseid | |
350 | * @param int $instanceid The chat id. | |
351 | * @param string $eventtype The event type. eg. ASSIGN_EVENT_TYPE_DUE. | |
e1cd93ce | 352 | * @return bool|calendar_event |
bea71d57 MN |
353 | */ |
354 | private function create_action_event($courseid, $instanceid, $eventtype) { | |
355 | $event = new stdClass(); | |
356 | $event->name = 'Calendar event'; | |
357 | $event->modulename = 'chat'; | |
358 | $event->courseid = $courseid; | |
359 | $event->instance = $instanceid; | |
360 | $event->type = CALENDAR_EVENT_TYPE_ACTION; | |
361 | $event->eventtype = $eventtype; | |
362 | $event->timestart = time(); | |
363 | ||
e1cd93ce | 364 | return calendar_event::create($event); |
bea71d57 MN |
365 | } |
366 | } |