MDL-55982 mod_forum: Add time-based discussion locking
[moodle.git] / mod / forum / tests / lib_test.php
CommitLineData
62b3b997
FM
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 * The module forums tests
19 *
20 * @package mod_forum
21 * @copyright 2013 Frédéric Massart
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26
e3bbfb52
AN
27global $CFG;
28require_once($CFG->dirroot . '/mod/forum/lib.php');
731c2712 29require_once($CFG->dirroot . '/rating/lib.php');
e3bbfb52 30
62b3b997
FM
31class mod_forum_lib_testcase extends advanced_testcase {
32
59075a43
AN
33 public function setUp() {
34 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
35 // tests using these functions.
36 \mod_forum\subscriptions::reset_forum_cache();
37 }
38
39 public function tearDown() {
40 // We must clear the subscription caches. This has to be done both before each test, and after in case of other
41 // tests using these functions.
42 \mod_forum\subscriptions::reset_forum_cache();
43 }
44
62b3b997
FM
45 public function test_forum_trigger_content_uploaded_event() {
46 $this->resetAfterTest();
47
48 $user = $this->getDataGenerator()->create_user();
49 $course = $this->getDataGenerator()->create_course();
50 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
51 $context = context_module::instance($forum->cmid);
52
53 $this->setUser($user->id);
54 $fakepost = (object) array('id' => 123, 'message' => 'Yay!', 'discussion' => 100);
74b63eae 55 $cm = get_coursemodule_from_instance('forum', $forum->id);
62b3b997
FM
56
57 $fs = get_file_storage();
58 $dummy = (object) array(
59 'contextid' => $context->id,
60 'component' => 'mod_forum',
61 'filearea' => 'attachment',
62 'itemid' => $fakepost->id,
63 'filepath' => '/',
64 'filename' => 'myassignmnent.pdf'
65 );
66 $fi = $fs->create_file_from_string($dummy, 'Content of ' . $dummy->filename);
67
68 $data = new stdClass();
69 $sink = $this->redirectEvents();
70 forum_trigger_content_uploaded_event($fakepost, $cm, 'some triggered from value');
71 $events = $sink->get_events();
72
73 $this->assertCount(1, $events);
74 $event = reset($events);
75 $this->assertInstanceOf('\mod_forum\event\assessable_uploaded', $event);
76 $this->assertEquals($context->id, $event->contextid);
77 $this->assertEquals($fakepost->id, $event->objectid);
78 $this->assertEquals($fakepost->message, $event->other['content']);
79 $this->assertEquals($fakepost->discussion, $event->other['discussionid']);
80 $this->assertCount(1, $event->other['pathnamehashes']);
81 $this->assertEquals($fi->get_pathnamehash(), $event->other['pathnamehashes'][0]);
82 $expected = new stdClass();
83 $expected->modulename = 'forum';
84 $expected->name = 'some triggered from value';
85 $expected->cmid = $forum->cmid;
86 $expected->itemid = $fakepost->id;
87 $expected->courseid = $course->id;
88 $expected->userid = $user->id;
89 $expected->content = $fakepost->message;
90 $expected->pathnamehashes = array($fi->get_pathnamehash());
91 $this->assertEventLegacyData($expected, $event);
623a32e5 92 $this->assertEventContextNotUsed($event);
62b3b997
FM
93 }
94
de316687
DP
95 public function test_forum_get_courses_user_posted_in() {
96 $this->resetAfterTest();
97
98 $user1 = $this->getDataGenerator()->create_user();
99 $user2 = $this->getDataGenerator()->create_user();
100 $user3 = $this->getDataGenerator()->create_user();
101
102 $course1 = $this->getDataGenerator()->create_course();
103 $course2 = $this->getDataGenerator()->create_course();
104 $course3 = $this->getDataGenerator()->create_course();
105
106 // Create 3 forums, one in each course.
107 $record = new stdClass();
108 $record->course = $course1->id;
109 $forum1 = $this->getDataGenerator()->create_module('forum', $record);
110
111 $record = new stdClass();
112 $record->course = $course2->id;
113 $forum2 = $this->getDataGenerator()->create_module('forum', $record);
114
115 $record = new stdClass();
116 $record->course = $course3->id;
117 $forum3 = $this->getDataGenerator()->create_module('forum', $record);
118
72c2c0bb
DP
119 // Add a second forum in course 1.
120 $record = new stdClass();
121 $record->course = $course1->id;
122 $forum4 = $this->getDataGenerator()->create_module('forum', $record);
123
124 // Add discussions to course 1 started by user1.
de316687
DP
125 $record = new stdClass();
126 $record->course = $course1->id;
127 $record->userid = $user1->id;
128 $record->forum = $forum1->id;
129 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
130
72c2c0bb
DP
131 $record = new stdClass();
132 $record->course = $course1->id;
133 $record->userid = $user1->id;
134 $record->forum = $forum4->id;
135 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
136
137 // Add discussions to course2 started by user1.
de316687
DP
138 $record = new stdClass();
139 $record->course = $course2->id;
140 $record->userid = $user1->id;
141 $record->forum = $forum2->id;
142 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
143
144 // Add discussions to course 3 started by user2.
145 $record = new stdClass();
146 $record->course = $course3->id;
147 $record->userid = $user2->id;
148 $record->forum = $forum3->id;
149 $discussion3 = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
150
151 // Add post to course 3 by user1.
152 $record = new stdClass();
153 $record->course = $course3->id;
154 $record->userid = $user1->id;
155 $record->forum = $forum3->id;
156 $record->discussion = $discussion3->id;
157 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
158
159 // User 3 hasn't posted anything, so shouldn't get any results.
160 $user3courses = forum_get_courses_user_posted_in($user3);
161 $this->assertEmpty($user3courses);
162
163 // User 2 has only posted in course3.
164 $user2courses = forum_get_courses_user_posted_in($user2);
165 $this->assertCount(1, $user2courses);
166 $user2course = array_shift($user2courses);
167 $this->assertEquals($course3->id, $user2course->id);
168 $this->assertEquals($course3->shortname, $user2course->shortname);
169
170 // User 1 has posted in all 3 courses.
171 $user1courses = forum_get_courses_user_posted_in($user1);
172 $this->assertCount(3, $user1courses);
173 foreach ($user1courses as $course) {
174 $this->assertContains($course->id, array($course1->id, $course2->id, $course3->id));
175 $this->assertContains($course->shortname, array($course1->shortname, $course2->shortname,
176 $course3->shortname));
177
178 }
179
180 // User 1 has only started a discussion in course 1 and 2 though.
181 $user1courses = forum_get_courses_user_posted_in($user1, true);
182 $this->assertCount(2, $user1courses);
183 foreach ($user1courses as $course) {
184 $this->assertContains($course->id, array($course1->id, $course2->id));
185 $this->assertContains($course->shortname, array($course1->shortname, $course2->shortname));
186 }
187 }
bb78e249 188
20e6782f
EM
189 /**
190 * Test the logic in the forum_tp_can_track_forums() function.
191 */
192 public function test_forum_tp_can_track_forums() {
193 global $CFG;
194
195 $this->resetAfterTest();
196
197 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1));
198 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0));
199 $course = $this->getDataGenerator()->create_course();
200 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off.
201 $forumoff = $this->getDataGenerator()->create_module('forum', $options);
202
bd8f5d45 203 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On.
20e6782f
EM
204 $forumforce = $this->getDataGenerator()->create_module('forum', $options);
205
206 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional.
207 $forumoptional = $this->getDataGenerator()->create_module('forum', $options);
208
209 // Allow force.
210 $CFG->forum_allowforcedreadtracking = 1;
211
212 // User on, forum off, should be off.
213 $result = forum_tp_can_track_forums($forumoff, $useron);
214 $this->assertEquals(false, $result);
215
216 // User on, forum on, should be on.
217 $result = forum_tp_can_track_forums($forumforce, $useron);
218 $this->assertEquals(true, $result);
219
220 // User on, forum optional, should be on.
221 $result = forum_tp_can_track_forums($forumoptional, $useron);
222 $this->assertEquals(true, $result);
223
224 // User off, forum off, should be off.
225 $result = forum_tp_can_track_forums($forumoff, $useroff);
226 $this->assertEquals(false, $result);
227
228 // User off, forum force, should be on.
229 $result = forum_tp_can_track_forums($forumforce, $useroff);
230 $this->assertEquals(true, $result);
231
232 // User off, forum optional, should be off.
233 $result = forum_tp_can_track_forums($forumoptional, $useroff);
234 $this->assertEquals(false, $result);
235
236 // Don't allow force.
237 $CFG->forum_allowforcedreadtracking = 0;
238
239 // User on, forum off, should be off.
240 $result = forum_tp_can_track_forums($forumoff, $useron);
241 $this->assertEquals(false, $result);
242
243 // User on, forum on, should be on.
244 $result = forum_tp_can_track_forums($forumforce, $useron);
245 $this->assertEquals(true, $result);
246
247 // User on, forum optional, should be on.
248 $result = forum_tp_can_track_forums($forumoptional, $useron);
249 $this->assertEquals(true, $result);
250
251 // User off, forum off, should be off.
252 $result = forum_tp_can_track_forums($forumoff, $useroff);
253 $this->assertEquals(false, $result);
254
255 // User off, forum force, should be off.
256 $result = forum_tp_can_track_forums($forumforce, $useroff);
257 $this->assertEquals(false, $result);
258
259 // User off, forum optional, should be off.
260 $result = forum_tp_can_track_forums($forumoptional, $useroff);
261 $this->assertEquals(false, $result);
262
263 }
264
265 /**
266 * Test the logic in the test_forum_tp_is_tracked() function.
267 */
268 public function test_forum_tp_is_tracked() {
269 global $CFG;
270
271 $this->resetAfterTest();
272
273 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1));
274 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0));
275 $course = $this->getDataGenerator()->create_course();
276 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off.
277 $forumoff = $this->getDataGenerator()->create_module('forum', $options);
278
bd8f5d45 279 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On.
20e6782f
EM
280 $forumforce = $this->getDataGenerator()->create_module('forum', $options);
281
282 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional.
283 $forumoptional = $this->getDataGenerator()->create_module('forum', $options);
284
285 // Allow force.
286 $CFG->forum_allowforcedreadtracking = 1;
287
288 // User on, forum off, should be off.
289 $result = forum_tp_is_tracked($forumoff, $useron);
290 $this->assertEquals(false, $result);
291
292 // User on, forum force, should be on.
293 $result = forum_tp_is_tracked($forumforce, $useron);
294 $this->assertEquals(true, $result);
295
296 // User on, forum optional, should be on.
297 $result = forum_tp_is_tracked($forumoptional, $useron);
298 $this->assertEquals(true, $result);
299
300 // User off, forum off, should be off.
301 $result = forum_tp_is_tracked($forumoff, $useroff);
302 $this->assertEquals(false, $result);
303
304 // User off, forum force, should be on.
305 $result = forum_tp_is_tracked($forumforce, $useroff);
306 $this->assertEquals(true, $result);
307
308 // User off, forum optional, should be off.
309 $result = forum_tp_is_tracked($forumoptional, $useroff);
310 $this->assertEquals(false, $result);
311
312 // Don't allow force.
313 $CFG->forum_allowforcedreadtracking = 0;
314
315 // User on, forum off, should be off.
316 $result = forum_tp_is_tracked($forumoff, $useron);
317 $this->assertEquals(false, $result);
318
319 // User on, forum force, should be on.
320 $result = forum_tp_is_tracked($forumforce, $useron);
321 $this->assertEquals(true, $result);
322
323 // User on, forum optional, should be on.
324 $result = forum_tp_is_tracked($forumoptional, $useron);
325 $this->assertEquals(true, $result);
326
327 // User off, forum off, should be off.
328 $result = forum_tp_is_tracked($forumoff, $useroff);
329 $this->assertEquals(false, $result);
330
331 // User off, forum force, should be off.
332 $result = forum_tp_is_tracked($forumforce, $useroff);
333 $this->assertEquals(false, $result);
334
335 // User off, forum optional, should be off.
336 $result = forum_tp_is_tracked($forumoptional, $useroff);
337 $this->assertEquals(false, $result);
338
339 // Stop tracking so we can test again.
340 forum_tp_stop_tracking($forumforce->id, $useron->id);
341 forum_tp_stop_tracking($forumoptional->id, $useron->id);
342 forum_tp_stop_tracking($forumforce->id, $useroff->id);
343 forum_tp_stop_tracking($forumoptional->id, $useroff->id);
344
345 // Allow force.
346 $CFG->forum_allowforcedreadtracking = 1;
347
348 // User on, preference off, forum force, should be on.
349 $result = forum_tp_is_tracked($forumforce, $useron);
350 $this->assertEquals(true, $result);
351
352 // User on, preference off, forum optional, should be on.
353 $result = forum_tp_is_tracked($forumoptional, $useron);
354 $this->assertEquals(false, $result);
355
356 // User off, preference off, forum force, should be on.
357 $result = forum_tp_is_tracked($forumforce, $useroff);
358 $this->assertEquals(true, $result);
359
360 // User off, preference off, forum optional, should be off.
361 $result = forum_tp_is_tracked($forumoptional, $useroff);
362 $this->assertEquals(false, $result);
363
364 // Don't allow force.
365 $CFG->forum_allowforcedreadtracking = 0;
366
367 // User on, preference off, forum force, should be on.
368 $result = forum_tp_is_tracked($forumforce, $useron);
369 $this->assertEquals(false, $result);
370
371 // User on, preference off, forum optional, should be on.
372 $result = forum_tp_is_tracked($forumoptional, $useron);
373 $this->assertEquals(false, $result);
374
375 // User off, preference off, forum force, should be off.
376 $result = forum_tp_is_tracked($forumforce, $useroff);
377 $this->assertEquals(false, $result);
378
379 // User off, preference off, forum optional, should be off.
380 $result = forum_tp_is_tracked($forumoptional, $useroff);
381 $this->assertEquals(false, $result);
382 }
383
384 /**
385 * Test the logic in the forum_tp_get_course_unread_posts() function.
386 */
387 public function test_forum_tp_get_course_unread_posts() {
388 global $CFG;
389
390 $this->resetAfterTest();
391
392 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1));
393 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0));
394 $course = $this->getDataGenerator()->create_course();
395 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off.
396 $forumoff = $this->getDataGenerator()->create_module('forum', $options);
397
bd8f5d45 398 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On.
20e6782f
EM
399 $forumforce = $this->getDataGenerator()->create_module('forum', $options);
400
401 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional.
402 $forumoptional = $this->getDataGenerator()->create_module('forum', $options);
403
404 // Add discussions to the tracking off forum.
405 $record = new stdClass();
406 $record->course = $course->id;
407 $record->userid = $useron->id;
408 $record->forum = $forumoff->id;
409 $discussionoff = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
410
411 // Add discussions to the tracking forced forum.
412 $record = new stdClass();
413 $record->course = $course->id;
414 $record->userid = $useron->id;
415 $record->forum = $forumforce->id;
416 $discussionforce = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
417
418 // Add post to the tracking forced discussion.
419 $record = new stdClass();
420 $record->course = $course->id;
421 $record->userid = $useroff->id;
422 $record->forum = $forumforce->id;
423 $record->discussion = $discussionforce->id;
424 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);
425
426 // Add discussions to the tracking optional forum.
427 $record = new stdClass();
428 $record->course = $course->id;
429 $record->userid = $useron->id;
430 $record->forum = $forumoptional->id;
431 $discussionoptional = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
432
433 // Allow force.
434 $CFG->forum_allowforcedreadtracking = 1;
435
436 $result = forum_tp_get_course_unread_posts($useron->id, $course->id);
437 $this->assertEquals(2, count($result));
438 $this->assertEquals(false, isset($result[$forumoff->id]));
439 $this->assertEquals(true, isset($result[$forumforce->id]));
440 $this->assertEquals(2, $result[$forumforce->id]->unread);
441 $this->assertEquals(true, isset($result[$forumoptional->id]));
442 $this->assertEquals(1, $result[$forumoptional->id]->unread);
443
444 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id);
445 $this->assertEquals(1, count($result));
446 $this->assertEquals(false, isset($result[$forumoff->id]));
447 $this->assertEquals(true, isset($result[$forumforce->id]));
448 $this->assertEquals(2, $result[$forumforce->id]->unread);
449 $this->assertEquals(false, isset($result[$forumoptional->id]));
450
451 // Don't allow force.
452 $CFG->forum_allowforcedreadtracking = 0;
453
454 $result = forum_tp_get_course_unread_posts($useron->id, $course->id);
455 $this->assertEquals(2, count($result));
456 $this->assertEquals(false, isset($result[$forumoff->id]));
457 $this->assertEquals(true, isset($result[$forumforce->id]));
458 $this->assertEquals(2, $result[$forumforce->id]->unread);
459 $this->assertEquals(true, isset($result[$forumoptional->id]));
460 $this->assertEquals(1, $result[$forumoptional->id]->unread);
461
462 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id);
463 $this->assertEquals(0, count($result));
464 $this->assertEquals(false, isset($result[$forumoff->id]));
465 $this->assertEquals(false, isset($result[$forumforce->id]));
466 $this->assertEquals(false, isset($result[$forumoptional->id]));
467
468 // Stop tracking so we can test again.
469 forum_tp_stop_tracking($forumforce->id, $useron->id);
470 forum_tp_stop_tracking($forumoptional->id, $useron->id);
471 forum_tp_stop_tracking($forumforce->id, $useroff->id);
472 forum_tp_stop_tracking($forumoptional->id, $useroff->id);
473
474 // Allow force.
475 $CFG->forum_allowforcedreadtracking = 1;
476
477 $result = forum_tp_get_course_unread_posts($useron->id, $course->id);
478 $this->assertEquals(1, count($result));
479 $this->assertEquals(false, isset($result[$forumoff->id]));
480 $this->assertEquals(true, isset($result[$forumforce->id]));
481 $this->assertEquals(2, $result[$forumforce->id]->unread);
482 $this->assertEquals(false, isset($result[$forumoptional->id]));
483
484 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id);
485 $this->assertEquals(1, count($result));
486 $this->assertEquals(false, isset($result[$forumoff->id]));
487 $this->assertEquals(true, isset($result[$forumforce->id]));
488 $this->assertEquals(2, $result[$forumforce->id]->unread);
489 $this->assertEquals(false, isset($result[$forumoptional->id]));
490
491 // Don't allow force.
492 $CFG->forum_allowforcedreadtracking = 0;
493
494 $result = forum_tp_get_course_unread_posts($useron->id, $course->id);
495 $this->assertEquals(0, count($result));
496 $this->assertEquals(false, isset($result[$forumoff->id]));
497 $this->assertEquals(false, isset($result[$forumforce->id]));
498 $this->assertEquals(false, isset($result[$forumoptional->id]));
499
500 $result = forum_tp_get_course_unread_posts($useroff->id, $course->id);
501 $this->assertEquals(0, count($result));
502 $this->assertEquals(false, isset($result[$forumoff->id]));
503 $this->assertEquals(false, isset($result[$forumforce->id]));
504 $this->assertEquals(false, isset($result[$forumoptional->id]));
505 }
506
507 /**
508 * Test the logic in the test_forum_tp_get_untracked_forums() function.
509 */
510 public function test_forum_tp_get_untracked_forums() {
511 global $CFG;
512
513 $this->resetAfterTest();
514
515 $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1));
516 $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0));
517 $course = $this->getDataGenerator()->create_course();
518 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off.
519 $forumoff = $this->getDataGenerator()->create_module('forum', $options);
520
bd8f5d45 521 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_FORCED); // On.
20e6782f
EM
522 $forumforce = $this->getDataGenerator()->create_module('forum', $options);
523
524 $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional.
525 $forumoptional = $this->getDataGenerator()->create_module('forum', $options);
526
527 // Allow force.
528 $CFG->forum_allowforcedreadtracking = 1;
529
530 // On user with force on.
531 $result = forum_tp_get_untracked_forums($useron->id, $course->id);
532 $this->assertEquals(1, count($result));
533 $this->assertEquals(true, isset($result[$forumoff->id]));
534
535 // Off user with force on.
536 $result = forum_tp_get_untracked_forums($useroff->id, $course->id);
537 $this->assertEquals(2, count($result));
538 $this->assertEquals(true, isset($result[$forumoff->id]));
539 $this->assertEquals(true, isset($result[$forumoptional->id]));
540
541 // Don't allow force.
542 $CFG->forum_allowforcedreadtracking = 0;
543
544 // On user with force off.
545 $result = forum_tp_get_untracked_forums($useron->id, $course->id);
546 $this->assertEquals(1, count($result));
547 $this->assertEquals(true, isset($result[$forumoff->id]));
548
549 // Off user with force off.
550 $result = forum_tp_get_untracked_forums($useroff->id, $course->id);
551 $this->assertEquals(3, count($result));
552 $this->assertEquals(true, isset($result[$forumoff->id]));
553 $this->assertEquals(true, isset($result[$forumoptional->id]));
554 $this->assertEquals(true, isset($result[$forumforce->id]));
555
556 // Stop tracking so we can test again.
557 forum_tp_stop_tracking($forumforce->id, $useron->id);
558 forum_tp_stop_tracking($forumoptional->id, $useron->id);
559 forum_tp_stop_tracking($forumforce->id, $useroff->id);
560 forum_tp_stop_tracking($forumoptional->id, $useroff->id);
561
562 // Allow force.
563 $CFG->forum_allowforcedreadtracking = 1;
564
565 // On user with force on.
566 $result = forum_tp_get_untracked_forums($useron->id, $course->id);
567 $this->assertEquals(2, count($result));
568 $this->assertEquals(true, isset($result[$forumoff->id]));
569 $this->assertEquals(true, isset($result[$forumoptional->id]));
570
571 // Off user with force on.
572 $result = forum_tp_get_untracked_forums($useroff->id, $course->id);
573 $this->assertEquals(2, count($result));
574 $this->assertEquals(true, isset($result[$forumoff->id]));
575 $this->assertEquals(true, isset($result[$forumoptional->id]));
576
577 // Don't allow force.
578 $CFG->forum_allowforcedreadtracking = 0;
579
580 // On user with force off.
581 $result = forum_tp_get_untracked_forums($useron->id, $course->id);
582 $this->assertEquals(3, count($result));
583 $this->assertEquals(true, isset($result[$forumoff->id]));
584 $this->assertEquals(true, isset($result[$forumoptional->id]));
585 $this->assertEquals(true, isset($result[$forumforce->id]));
586
587 // Off user with force off.
588 $result = forum_tp_get_untracked_forums($useroff->id, $course->id);
589 $this->assertEquals(3, count($result));
590 $this->assertEquals(true, isset($result[$forumoff->id]));
591 $this->assertEquals(true, isset($result[$forumoptional->id]));
592 $this->assertEquals(true, isset($result[$forumforce->id]));
593 }
7bb7de44
AN
594
595 /**
596 * Test subscription using automatic subscription on create.
597 */
598 public function test_forum_auto_subscribe_on_create() {
599 global $CFG;
600
601 $this->resetAfterTest();
602
603 $usercount = 5;
604 $course = $this->getDataGenerator()->create_course();
605 $users = array();
606
607 for ($i = 0; $i < $usercount; $i++) {
608 $user = $this->getDataGenerator()->create_user();
609 $users[] = $user;
610 $this->getDataGenerator()->enrol_user($user->id, $course->id);
611 }
612
613 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_INITIALSUBSCRIBE); // Automatic Subscription.
614 $forum = $this->getDataGenerator()->create_module('forum', $options);
615
59075a43 616 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum);
7bb7de44
AN
617 $this->assertEquals($usercount, count($result));
618 foreach ($users as $user) {
59075a43 619 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
7bb7de44
AN
620 }
621 }
622
623 /**
624 * Test subscription using forced subscription on create.
625 */
626 public function test_forum_forced_subscribe_on_create() {
627 global $CFG;
628
629 $this->resetAfterTest();
630
631 $usercount = 5;
632 $course = $this->getDataGenerator()->create_course();
633 $users = array();
634
635 for ($i = 0; $i < $usercount; $i++) {
636 $user = $this->getDataGenerator()->create_user();
637 $users[] = $user;
638 $this->getDataGenerator()->enrol_user($user->id, $course->id);
639 }
640
641 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_FORCESUBSCRIBE); // Forced subscription.
642 $forum = $this->getDataGenerator()->create_module('forum', $options);
643
59075a43 644 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum);
7bb7de44
AN
645 $this->assertEquals($usercount, count($result));
646 foreach ($users as $user) {
59075a43 647 $this->assertTrue(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
7bb7de44
AN
648 }
649 }
650
651 /**
652 * Test subscription using optional subscription on create.
653 */
654 public function test_forum_optional_subscribe_on_create() {
655 global $CFG;
656
657 $this->resetAfterTest();
658
659 $usercount = 5;
660 $course = $this->getDataGenerator()->create_course();
661 $users = array();
662
663 for ($i = 0; $i < $usercount; $i++) {
664 $user = $this->getDataGenerator()->create_user();
665 $users[] = $user;
666 $this->getDataGenerator()->enrol_user($user->id, $course->id);
667 }
668
669 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE); // Subscription optional.
670 $forum = $this->getDataGenerator()->create_module('forum', $options);
671
59075a43 672 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum);
7bb7de44
AN
673 // No subscriptions by default.
674 $this->assertEquals(0, count($result));
675 foreach ($users as $user) {
59075a43 676 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
7bb7de44
AN
677 }
678 }
679
680 /**
681 * Test subscription using disallow subscription on create.
682 */
683 public function test_forum_disallow_subscribe_on_create() {
684 global $CFG;
685
686 $this->resetAfterTest();
687
688 $usercount = 5;
689 $course = $this->getDataGenerator()->create_course();
690 $users = array();
691
692 for ($i = 0; $i < $usercount; $i++) {
693 $user = $this->getDataGenerator()->create_user();
694 $users[] = $user;
695 $this->getDataGenerator()->enrol_user($user->id, $course->id);
696 }
697
698 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_DISALLOWSUBSCRIBE); // Subscription prevented.
699 $forum = $this->getDataGenerator()->create_module('forum', $options);
700
59075a43 701 $result = \mod_forum\subscriptions::fetch_subscribed_users($forum);
7bb7de44
AN
702 // No subscriptions by default.
703 $this->assertEquals(0, count($result));
704 foreach ($users as $user) {
59075a43 705 $this->assertFalse(\mod_forum\subscriptions::is_subscribed($user->id, $forum));
7bb7de44
AN
706 }
707 }
59075a43
AN
708
709 /**
710 * Test that context fetching returns the appropriate context.
711 */
712 public function test_forum_get_context() {
713 global $DB, $PAGE;
714
715 $this->resetAfterTest();
716
717 // Setup test data.
718 $course = $this->getDataGenerator()->create_course();
719 $coursecontext = \context_course::instance($course->id);
720
721 $options = array('course' => $course->id, 'forcesubscribe' => FORUM_CHOOSESUBSCRIBE);
722 $forum = $this->getDataGenerator()->create_module('forum', $options);
723 $forumcm = get_coursemodule_from_instance('forum', $forum->id);
724 $forumcontext = \context_module::instance($forumcm->id);
725
726 // First check that specifying the context results in the correct context being returned.
727 // Do this before we set up the page object and we should return from the coursemodule record.
728 // There should be no DB queries here because the context type was correct.
729 $startcount = $DB->perf_get_reads();
730 $result = forum_get_context($forum->id, $forumcontext);
731 $aftercount = $DB->perf_get_reads();
732 $this->assertEquals($forumcontext, $result);
733 $this->assertEquals(0, $aftercount - $startcount);
734
735 // And a context which is not the correct type.
736 // This tests will result in a DB query to fetch the course_module.
737 $startcount = $DB->perf_get_reads();
738 $result = forum_get_context($forum->id, $coursecontext);
739 $aftercount = $DB->perf_get_reads();
740 $this->assertEquals($forumcontext, $result);
741 $this->assertEquals(1, $aftercount - $startcount);
742
743 // Now do not specify a context at all.
744 // This tests will result in a DB query to fetch the course_module.
745 $startcount = $DB->perf_get_reads();
746 $result = forum_get_context($forum->id);
747 $aftercount = $DB->perf_get_reads();
748 $this->assertEquals($forumcontext, $result);
749 $this->assertEquals(1, $aftercount - $startcount);
750
751 // Set up the default page event to use the forum.
752 $PAGE = new moodle_page();
753 $PAGE->set_context($forumcontext);
754 $PAGE->set_cm($forumcm, $course, $forum);
755
756 // Now specify a context which is not a context_module.
757 // There should be no DB queries here because we use the PAGE.
758 $startcount = $DB->perf_get_reads();
759 $result = forum_get_context($forum->id, $coursecontext);
760 $aftercount = $DB->perf_get_reads();
761 $this->assertEquals($forumcontext, $result);
762 $this->assertEquals(0, $aftercount - $startcount);
763
764 // Now do not specify a context at all.
765 // There should be no DB queries here because we use the PAGE.
766 $startcount = $DB->perf_get_reads();
767 $result = forum_get_context($forum->id);
768 $aftercount = $DB->perf_get_reads();
769 $this->assertEquals($forumcontext, $result);
770 $this->assertEquals(0, $aftercount - $startcount);
771
772 // Now specify the page context of the course instead..
773 $PAGE = new moodle_page();
774 $PAGE->set_context($coursecontext);
775
776 // Now specify a context which is not a context_module.
777 // This tests will result in a DB query to fetch the course_module.
778 $startcount = $DB->perf_get_reads();
779 $result = forum_get_context($forum->id, $coursecontext);
780 $aftercount = $DB->perf_get_reads();
781 $this->assertEquals($forumcontext, $result);
782 $this->assertEquals(1, $aftercount - $startcount);
783
784 // Now do not specify a context at all.
785 // This tests will result in a DB query to fetch the course_module.
786 $startcount = $DB->perf_get_reads();
787 $result = forum_get_context($forum->id);
788 $aftercount = $DB->perf_get_reads();
789 $this->assertEquals($forumcontext, $result);
790 $this->assertEquals(1, $aftercount - $startcount);
791 }
826cb6f6
FM
792
793 /**
794 * Test getting the neighbour threads of a discussion.
795 */
796 public function test_forum_get_neighbours() {
797 global $CFG, $DB;
798 $this->resetAfterTest();
799
5f219cf1
BK
800 $timenow = time();
801 $timenext = $timenow;
802
826cb6f6
FM
803 // Setup test data.
804 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
805 $course = $this->getDataGenerator()->create_course();
806 $user = $this->getDataGenerator()->create_user();
807 $user2 = $this->getDataGenerator()->create_user();
808
809 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
810 $cm = get_coursemodule_from_instance('forum', $forum->id);
811 $context = context_module::instance($cm->id);
812
813 $record = new stdClass();
814 $record->course = $course->id;
815 $record->userid = $user->id;
816 $record->forum = $forum->id;
6ec76606 817 $record->timemodified = time();
826cb6f6 818 $disc1 = $forumgen->create_discussion($record);
6ec76606 819 $record->timemodified++;
826cb6f6 820 $disc2 = $forumgen->create_discussion($record);
6ec76606 821 $record->timemodified++;
826cb6f6 822 $disc3 = $forumgen->create_discussion($record);
6ec76606 823 $record->timemodified++;
826cb6f6 824 $disc4 = $forumgen->create_discussion($record);
6ec76606 825 $record->timemodified++;
826cb6f6
FM
826 $disc5 = $forumgen->create_discussion($record);
827
828 // Getting the neighbours.
9e381efd 829 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum);
826cb6f6
FM
830 $this->assertEmpty($neighbours['prev']);
831 $this->assertEquals($disc2->id, $neighbours['next']->id);
832
9e381efd 833 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
826cb6f6
FM
834 $this->assertEquals($disc1->id, $neighbours['prev']->id);
835 $this->assertEquals($disc3->id, $neighbours['next']->id);
836
9e381efd 837 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
826cb6f6
FM
838 $this->assertEquals($disc2->id, $neighbours['prev']->id);
839 $this->assertEquals($disc4->id, $neighbours['next']->id);
840
9e381efd 841 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum);
826cb6f6
FM
842 $this->assertEquals($disc3->id, $neighbours['prev']->id);
843 $this->assertEquals($disc5->id, $neighbours['next']->id);
844
9e381efd 845 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum);
826cb6f6
FM
846 $this->assertEquals($disc4->id, $neighbours['prev']->id);
847 $this->assertEmpty($neighbours['next']);
848
849 // Post in some discussions. We manually update the discussion record because
850 // the data generator plays with timemodified in a way that would break this test.
6ec76606
AN
851 $record->timemodified++;
852 $disc1->timemodified = $record->timemodified;
826cb6f6
FM
853 $DB->update_record('forum_discussions', $disc1);
854
9e381efd 855 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum);
826cb6f6
FM
856 $this->assertEquals($disc4->id, $neighbours['prev']->id);
857 $this->assertEquals($disc1->id, $neighbours['next']->id);
858
9e381efd 859 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
826cb6f6
FM
860 $this->assertEmpty($neighbours['prev']);
861 $this->assertEquals($disc3->id, $neighbours['next']->id);
862
9e381efd 863 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum);
826cb6f6
FM
864 $this->assertEquals($disc5->id, $neighbours['prev']->id);
865 $this->assertEmpty($neighbours['next']);
866
867 // After some discussions were created.
6ec76606 868 $record->timemodified++;
826cb6f6 869 $disc6 = $forumgen->create_discussion($record);
9e381efd 870 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum);
826cb6f6
FM
871 $this->assertEquals($disc1->id, $neighbours['prev']->id);
872 $this->assertEmpty($neighbours['next']);
873
6ec76606 874 $record->timemodified++;
826cb6f6 875 $disc7 = $forumgen->create_discussion($record);
9e381efd 876 $neighbours = forum_get_discussion_neighbours($cm, $disc7, $forum);
826cb6f6
FM
877 $this->assertEquals($disc6->id, $neighbours['prev']->id);
878 $this->assertEmpty($neighbours['next']);
879
880 // Adding timed discussions.
881 $CFG->forum_enabletimedposts = true;
6ec76606 882 $now = $record->timemodified;
826cb6f6
FM
883 $past = $now - 60;
884 $future = $now + 60;
885
886 $record = new stdClass();
887 $record->course = $course->id;
888 $record->userid = $user->id;
889 $record->forum = $forum->id;
890 $record->timestart = $past;
891 $record->timeend = $future;
6ec76606
AN
892 $record->timemodified = $now;
893 $record->timemodified++;
826cb6f6 894 $disc8 = $forumgen->create_discussion($record);
6ec76606 895 $record->timemodified++;
826cb6f6
FM
896 $record->timestart = $future;
897 $record->timeend = 0;
898 $disc9 = $forumgen->create_discussion($record);
6ec76606 899 $record->timemodified++;
826cb6f6
FM
900 $record->timestart = 0;
901 $record->timeend = 0;
902 $disc10 = $forumgen->create_discussion($record);
6ec76606 903 $record->timemodified++;
826cb6f6
FM
904 $record->timestart = 0;
905 $record->timeend = $past;
906 $disc11 = $forumgen->create_discussion($record);
6ec76606 907 $record->timemodified++;
826cb6f6
FM
908 $record->timestart = $past;
909 $record->timeend = $future;
910 $disc12 = $forumgen->create_discussion($record);
6ec76606 911 $record->timemodified++;
1e366657
AO
912 $record->timestart = $future + 1; // Should be last post for those that can see it.
913 $record->timeend = 0;
914 $disc13 = $forumgen->create_discussion($record);
826cb6f6
FM
915
916 // Admin user ignores the timed settings of discussions.
1e366657
AO
917 // Post ordering taking into account timestart:
918 // 8 = t
919 // 10 = t+3
920 // 11 = t+4
921 // 12 = t+5
922 // 9 = t+60
923 // 13 = t+61.
826cb6f6 924 $this->setAdminUser();
9e381efd 925 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
826cb6f6 926 $this->assertEquals($disc7->id, $neighbours['prev']->id);
1e366657 927 $this->assertEquals($disc10->id, $neighbours['next']->id);
826cb6f6 928
9e381efd 929 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
1e366657
AO
930 $this->assertEquals($disc12->id, $neighbours['prev']->id);
931 $this->assertEquals($disc13->id, $neighbours['next']->id);
826cb6f6 932
9e381efd 933 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
1e366657 934 $this->assertEquals($disc8->id, $neighbours['prev']->id);
826cb6f6
FM
935 $this->assertEquals($disc11->id, $neighbours['next']->id);
936
9e381efd 937 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
826cb6f6
FM
938 $this->assertEquals($disc10->id, $neighbours['prev']->id);
939 $this->assertEquals($disc12->id, $neighbours['next']->id);
940
9e381efd 941 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
826cb6f6 942 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1e366657
AO
943 $this->assertEquals($disc9->id, $neighbours['next']->id);
944
945 $neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum);
946 $this->assertEquals($disc9->id, $neighbours['prev']->id);
826cb6f6
FM
947 $this->assertEmpty($neighbours['next']);
948
949 // Normal user can see their own timed discussions.
950 $this->setUser($user);
9e381efd 951 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
826cb6f6 952 $this->assertEquals($disc7->id, $neighbours['prev']->id);
1e366657 953 $this->assertEquals($disc10->id, $neighbours['next']->id);
826cb6f6 954
9e381efd 955 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
1e366657
AO
956 $this->assertEquals($disc12->id, $neighbours['prev']->id);
957 $this->assertEquals($disc13->id, $neighbours['next']->id);
826cb6f6 958
9e381efd 959 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
1e366657 960 $this->assertEquals($disc8->id, $neighbours['prev']->id);
826cb6f6
FM
961 $this->assertEquals($disc11->id, $neighbours['next']->id);
962
9e381efd 963 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
826cb6f6
FM
964 $this->assertEquals($disc10->id, $neighbours['prev']->id);
965 $this->assertEquals($disc12->id, $neighbours['next']->id);
966
9e381efd 967 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
826cb6f6 968 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1e366657
AO
969 $this->assertEquals($disc9->id, $neighbours['next']->id);
970
971 $neighbours = forum_get_discussion_neighbours($cm, $disc13, $forum);
972 $this->assertEquals($disc9->id, $neighbours['prev']->id);
826cb6f6
FM
973 $this->assertEmpty($neighbours['next']);
974
975 // Normal user does not ignore timed settings.
976 $this->setUser($user2);
9e381efd 977 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
826cb6f6
FM
978 $this->assertEquals($disc7->id, $neighbours['prev']->id);
979 $this->assertEquals($disc10->id, $neighbours['next']->id);
980
9e381efd 981 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
826cb6f6
FM
982 $this->assertEquals($disc8->id, $neighbours['prev']->id);
983 $this->assertEquals($disc12->id, $neighbours['next']->id);
984
9e381efd 985 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
826cb6f6
FM
986 $this->assertEquals($disc10->id, $neighbours['prev']->id);
987 $this->assertEmpty($neighbours['next']);
988
989 // Reset to normal mode.
990 $CFG->forum_enabletimedposts = false;
991 $this->setAdminUser();
992
5f219cf1
BK
993 // Two discussions with identical timemodified will sort by id.
994 $record->timemodified += 25;
6ec76606
AN
995 $DB->update_record('forum_discussions', (object) array('id' => $disc3->id, 'timemodified' => $record->timemodified));
996 $DB->update_record('forum_discussions', (object) array('id' => $disc2->id, 'timemodified' => $record->timemodified));
5f219cf1 997 $DB->update_record('forum_discussions', (object) array('id' => $disc12->id, 'timemodified' => $record->timemodified - 5));
826cb6f6
FM
998 $disc2 = $DB->get_record('forum_discussions', array('id' => $disc2->id));
999 $disc3 = $DB->get_record('forum_discussions', array('id' => $disc3->id));
1000
5f219cf1
BK
1001 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
1002 $this->assertEquals($disc2->id, $neighbours['prev']->id);
1003 $this->assertEmpty($neighbours['next']);
1004
9e381efd 1005 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
5f219cf1
BK
1006 $this->assertEquals($disc12->id, $neighbours['prev']->id);
1007 $this->assertEquals($disc3->id, $neighbours['next']->id);
1008
1009 // Set timemodified to not be identical.
1010 $DB->update_record('forum_discussions', (object) array('id' => $disc2->id, 'timemodified' => $record->timemodified - 1));
1011
1012 // Test pinned posts behave correctly.
f9621c56 1013 $disc8->pinned = FORUM_DISCUSSION_PINNED;
5f219cf1
BK
1014 $DB->update_record('forum_discussions', (object) array('id' => $disc8->id, 'pinned' => $disc8->pinned));
1015 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
1016 $this->assertEquals($disc3->id, $neighbours['prev']->id);
826cb6f6
FM
1017 $this->assertEmpty($neighbours['next']);
1018
9e381efd 1019 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
5f219cf1
BK
1020 $this->assertEquals($disc2->id, $neighbours['prev']->id);
1021 $this->assertEquals($disc8->id, $neighbours['next']->id);
1022
1023 // Test 3 pinned posts.
f9621c56 1024 $disc6->pinned = FORUM_DISCUSSION_PINNED;
5f219cf1 1025 $DB->update_record('forum_discussions', (object) array('id' => $disc6->id, 'pinned' => $disc6->pinned));
f9621c56 1026 $disc4->pinned = FORUM_DISCUSSION_PINNED;
5f219cf1
BK
1027 $DB->update_record('forum_discussions', (object) array('id' => $disc4->id, 'pinned' => $disc4->pinned));
1028
1029 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum);
1030 $this->assertEquals($disc4->id, $neighbours['prev']->id);
1031 $this->assertEquals($disc8->id, $neighbours['next']->id);
1032
1033 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum);
1034 $this->assertEquals($disc3->id, $neighbours['prev']->id);
1035 $this->assertEquals($disc6->id, $neighbours['next']->id);
1036
1037 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
1038 $this->assertEquals($disc6->id, $neighbours['prev']->id);
826cb6f6
FM
1039 $this->assertEmpty($neighbours['next']);
1040 }
1041
8d960707
DM
1042 /**
1043 * Test getting the neighbour threads of a blog-like forum.
1044 */
1045 public function test_forum_get_neighbours_blog() {
1046 global $CFG, $DB;
1047 $this->resetAfterTest();
1048
5f219cf1
BK
1049 $timenow = time();
1050 $timenext = $timenow;
1051
8d960707
DM
1052 // Setup test data.
1053 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
1054 $course = $this->getDataGenerator()->create_course();
1055 $user = $this->getDataGenerator()->create_user();
1056 $user2 = $this->getDataGenerator()->create_user();
1057
1058 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog'));
1059 $cm = get_coursemodule_from_instance('forum', $forum->id);
1060 $context = context_module::instance($cm->id);
1061
1062 $record = new stdClass();
1063 $record->course = $course->id;
1064 $record->userid = $user->id;
1065 $record->forum = $forum->id;
6ec76606 1066 $record->timemodified = time();
8d960707 1067 $disc1 = $forumgen->create_discussion($record);
6ec76606 1068 $record->timemodified++;
8d960707 1069 $disc2 = $forumgen->create_discussion($record);
6ec76606 1070 $record->timemodified++;
8d960707 1071 $disc3 = $forumgen->create_discussion($record);
6ec76606 1072 $record->timemodified++;
8d960707 1073 $disc4 = $forumgen->create_discussion($record);
6ec76606 1074 $record->timemodified++;
8d960707
DM
1075 $disc5 = $forumgen->create_discussion($record);
1076
1077 // Getting the neighbours.
1078 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum);
1079 $this->assertEmpty($neighbours['prev']);
1080 $this->assertEquals($disc2->id, $neighbours['next']->id);
1081
1082 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
1083 $this->assertEquals($disc1->id, $neighbours['prev']->id);
1084 $this->assertEquals($disc3->id, $neighbours['next']->id);
1085
1086 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
1087 $this->assertEquals($disc2->id, $neighbours['prev']->id);
1088 $this->assertEquals($disc4->id, $neighbours['next']->id);
1089
1090 $neighbours = forum_get_discussion_neighbours($cm, $disc4, $forum);
1091 $this->assertEquals($disc3->id, $neighbours['prev']->id);
1092 $this->assertEquals($disc5->id, $neighbours['next']->id);
1093
1094 $neighbours = forum_get_discussion_neighbours($cm, $disc5, $forum);
1095 $this->assertEquals($disc4->id, $neighbours['prev']->id);
1096 $this->assertEmpty($neighbours['next']);
1097
1098 // Make sure that the thread's timemodified does not affect the order.
6ec76606
AN
1099 $record->timemodified++;
1100 $disc1->timemodified = $record->timemodified;
8d960707
DM
1101 $DB->update_record('forum_discussions', $disc1);
1102
1103 $neighbours = forum_get_discussion_neighbours($cm, $disc1, $forum);
1104 $this->assertEmpty($neighbours['prev']);
1105 $this->assertEquals($disc2->id, $neighbours['next']->id);
1106
1107 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
1108 $this->assertEquals($disc1->id, $neighbours['prev']->id);
1109 $this->assertEquals($disc3->id, $neighbours['next']->id);
1110
1111 // Add another blog post.
6ec76606 1112 $record->timemodified++;
8d960707
DM
1113 $disc6 = $forumgen->create_discussion($record);
1114 $neighbours = forum_get_discussion_neighbours($cm, $disc6, $forum);
1115 $this->assertEquals($disc5->id, $neighbours['prev']->id);
1116 $this->assertEmpty($neighbours['next']);
1117
6ec76606 1118 $record->timemodified++;
8d960707
DM
1119 $disc7 = $forumgen->create_discussion($record);
1120 $neighbours = forum_get_discussion_neighbours($cm, $disc7, $forum);
1121 $this->assertEquals($disc6->id, $neighbours['prev']->id);
1122 $this->assertEmpty($neighbours['next']);
1123
1124 // Adding timed discussions.
1125 $CFG->forum_enabletimedposts = true;
6ec76606 1126 $now = $record->timemodified;
8d960707
DM
1127 $past = $now - 60;
1128 $future = $now + 60;
1129
1130 $record = new stdClass();
1131 $record->course = $course->id;
1132 $record->userid = $user->id;
1133 $record->forum = $forum->id;
1134 $record->timestart = $past;
1135 $record->timeend = $future;
6ec76606
AN
1136 $record->timemodified = $now;
1137 $record->timemodified++;
8d960707 1138 $disc8 = $forumgen->create_discussion($record);
6ec76606 1139 $record->timemodified++;
8d960707
DM
1140 $record->timestart = $future;
1141 $record->timeend = 0;
1142 $disc9 = $forumgen->create_discussion($record);
6ec76606 1143 $record->timemodified++;
8d960707
DM
1144 $record->timestart = 0;
1145 $record->timeend = 0;
1146 $disc10 = $forumgen->create_discussion($record);
6ec76606 1147 $record->timemodified++;
8d960707
DM
1148 $record->timestart = 0;
1149 $record->timeend = $past;
1150 $disc11 = $forumgen->create_discussion($record);
6ec76606 1151 $record->timemodified++;
8d960707
DM
1152 $record->timestart = $past;
1153 $record->timeend = $future;
1154 $disc12 = $forumgen->create_discussion($record);
1155
1156 // Admin user ignores the timed settings of discussions.
1157 $this->setAdminUser();
1158 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
1159 $this->assertEquals($disc7->id, $neighbours['prev']->id);
1160 $this->assertEquals($disc9->id, $neighbours['next']->id);
1161
1162 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
1163 $this->assertEquals($disc8->id, $neighbours['prev']->id);
1164 $this->assertEquals($disc10->id, $neighbours['next']->id);
1165
1166 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
1167 $this->assertEquals($disc9->id, $neighbours['prev']->id);
1168 $this->assertEquals($disc11->id, $neighbours['next']->id);
1169
1170 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
1171 $this->assertEquals($disc10->id, $neighbours['prev']->id);
1172 $this->assertEquals($disc12->id, $neighbours['next']->id);
1173
1174 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
1175 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1176 $this->assertEmpty($neighbours['next']);
1177
1178 // Normal user can see their own timed discussions.
1179 $this->setUser($user);
1180 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
1181 $this->assertEquals($disc7->id, $neighbours['prev']->id);
1182 $this->assertEquals($disc9->id, $neighbours['next']->id);
1183
1184 $neighbours = forum_get_discussion_neighbours($cm, $disc9, $forum);
1185 $this->assertEquals($disc8->id, $neighbours['prev']->id);
1186 $this->assertEquals($disc10->id, $neighbours['next']->id);
1187
1188 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
1189 $this->assertEquals($disc9->id, $neighbours['prev']->id);
1190 $this->assertEquals($disc11->id, $neighbours['next']->id);
1191
1192 $neighbours = forum_get_discussion_neighbours($cm, $disc11, $forum);
1193 $this->assertEquals($disc10->id, $neighbours['prev']->id);
1194 $this->assertEquals($disc12->id, $neighbours['next']->id);
1195
1196 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
1197 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1198 $this->assertEmpty($neighbours['next']);
1199
1200 // Normal user does not ignore timed settings.
1201 $this->setUser($user2);
1202 $neighbours = forum_get_discussion_neighbours($cm, $disc8, $forum);
1203 $this->assertEquals($disc7->id, $neighbours['prev']->id);
1204 $this->assertEquals($disc10->id, $neighbours['next']->id);
1205
1206 $neighbours = forum_get_discussion_neighbours($cm, $disc10, $forum);
1207 $this->assertEquals($disc8->id, $neighbours['prev']->id);
1208 $this->assertEquals($disc12->id, $neighbours['next']->id);
1209
1210 $neighbours = forum_get_discussion_neighbours($cm, $disc12, $forum);
1211 $this->assertEquals($disc10->id, $neighbours['prev']->id);
1212 $this->assertEmpty($neighbours['next']);
1213
1214 // Reset to normal mode.
1215 $CFG->forum_enabletimedposts = false;
1216 $this->setAdminUser();
1217
6ec76606 1218 $record->timemodified++;
5f219cf1 1219 // Two blog posts with identical creation time will sort by id.
6ec76606
AN
1220 $DB->update_record('forum_posts', (object) array('id' => $disc2->firstpost, 'created' => $record->timemodified));
1221 $DB->update_record('forum_posts', (object) array('id' => $disc3->firstpost, 'created' => $record->timemodified));
8d960707
DM
1222
1223 $neighbours = forum_get_discussion_neighbours($cm, $disc2, $forum);
1224 $this->assertEquals($disc12->id, $neighbours['prev']->id);
5f219cf1 1225 $this->assertEquals($disc3->id, $neighbours['next']->id);
8d960707
DM
1226
1227 $neighbours = forum_get_discussion_neighbours($cm, $disc3, $forum);
5f219cf1 1228 $this->assertEquals($disc2->id, $neighbours['prev']->id);
826cb6f6
FM
1229 $this->assertEmpty($neighbours['next']);
1230 }
1231
1232 /**
1233 * Test getting the neighbour threads of a discussion.
1234 */
1235 public function test_forum_get_neighbours_with_groups() {
1236 $this->resetAfterTest();
1237
5f219cf1
BK
1238 $timenow = time();
1239 $timenext = $timenow;
1240
826cb6f6
FM
1241 // Setup test data.
1242 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
1243 $course = $this->getDataGenerator()->create_course();
1244 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1245 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1246 $user1 = $this->getDataGenerator()->create_user();
1247 $user2 = $this->getDataGenerator()->create_user();
1248 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1249 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1250 $this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group1->id));
1251
1252 $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'groupmode' => VISIBLEGROUPS));
1253 $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'groupmode' => SEPARATEGROUPS));
1254 $cm1 = get_coursemodule_from_instance('forum', $forum1->id);
1255 $cm2 = get_coursemodule_from_instance('forum', $forum2->id);
1256 $context1 = context_module::instance($cm1->id);
1257 $context2 = context_module::instance($cm2->id);
1258
1259 // Creating discussions in both forums.
1260 $record = new stdClass();
1261 $record->course = $course->id;
1262 $record->userid = $user1->id;
1263 $record->forum = $forum1->id;
1264 $record->groupid = $group1->id;
6ec76606 1265 $record->timemodified = time();
826cb6f6
FM
1266 $disc11 = $forumgen->create_discussion($record);
1267 $record->forum = $forum2->id;
6ec76606 1268 $record->timemodified++;
826cb6f6
FM
1269 $disc21 = $forumgen->create_discussion($record);
1270
6ec76606 1271 $record->timemodified++;
826cb6f6
FM
1272 $record->userid = $user2->id;
1273 $record->forum = $forum1->id;
1274 $record->groupid = $group2->id;
1275 $disc12 = $forumgen->create_discussion($record);
1276 $record->forum = $forum2->id;
1277 $disc22 = $forumgen->create_discussion($record);
1278
6ec76606 1279 $record->timemodified++;
826cb6f6
FM
1280 $record->userid = $user1->id;
1281 $record->forum = $forum1->id;
1282 $record->groupid = null;
1283 $disc13 = $forumgen->create_discussion($record);
1284 $record->forum = $forum2->id;
1285 $disc23 = $forumgen->create_discussion($record);
1286
6ec76606 1287 $record->timemodified++;
826cb6f6
FM
1288 $record->userid = $user2->id;
1289 $record->forum = $forum1->id;
1290 $record->groupid = $group2->id;
1291 $disc14 = $forumgen->create_discussion($record);
1292 $record->forum = $forum2->id;
1293 $disc24 = $forumgen->create_discussion($record);
1294
6ec76606 1295 $record->timemodified++;
826cb6f6
FM
1296 $record->userid = $user1->id;
1297 $record->forum = $forum1->id;
1298 $record->groupid = $group1->id;
1299 $disc15 = $forumgen->create_discussion($record);
1300 $record->forum = $forum2->id;
1301 $disc25 = $forumgen->create_discussion($record);
1302
1303 // Admin user can see all groups.
1304 $this->setAdminUser();
8d960707
DM
1305 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
1306 $this->assertEmpty($neighbours['prev']);
1307 $this->assertEquals($disc12->id, $neighbours['next']->id);
1308 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
1309 $this->assertEmpty($neighbours['prev']);
1310 $this->assertEquals($disc22->id, $neighbours['next']->id);
1311
1312 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1);
1313 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1314 $this->assertEquals($disc13->id, $neighbours['next']->id);
1315 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2);
1316 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1317 $this->assertEquals($disc23->id, $neighbours['next']->id);
1318
1319 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
1320 $this->assertEquals($disc12->id, $neighbours['prev']->id);
1321 $this->assertEquals($disc14->id, $neighbours['next']->id);
1322 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
1323 $this->assertEquals($disc22->id, $neighbours['prev']->id);
1324 $this->assertEquals($disc24->id, $neighbours['next']->id);
1325
1326 $neighbours = forum_get_discussion_neighbours($cm1, $disc14, $forum1);
1327 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1328 $this->assertEquals($disc15->id, $neighbours['next']->id);
1329 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2);
1330 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1331 $this->assertEquals($disc25->id, $neighbours['next']->id);
1332
1333 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
1334 $this->assertEquals($disc14->id, $neighbours['prev']->id);
1335 $this->assertEmpty($neighbours['next']);
1336 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
1337 $this->assertEquals($disc24->id, $neighbours['prev']->id);
1338 $this->assertEmpty($neighbours['next']);
1339
1340 // Admin user is only viewing group 1.
1341 $_POST['group'] = $group1->id;
1342 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true));
1343 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true));
1344
1345 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
1346 $this->assertEmpty($neighbours['prev']);
1347 $this->assertEquals($disc13->id, $neighbours['next']->id);
1348 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
1349 $this->assertEmpty($neighbours['prev']);
1350 $this->assertEquals($disc23->id, $neighbours['next']->id);
1351
1352 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
1353 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1354 $this->assertEquals($disc15->id, $neighbours['next']->id);
1355 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
1356 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1357 $this->assertEquals($disc25->id, $neighbours['next']->id);
1358
1359 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
1360 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1361 $this->assertEmpty($neighbours['next']);
1362 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
1363 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1364 $this->assertEmpty($neighbours['next']);
1365
1366 // Normal user viewing non-grouped posts (this is only possible in visible groups).
1367 $this->setUser($user1);
1368 $_POST['group'] = 0;
1369 $this->assertEquals(0, groups_get_activity_group($cm1, true));
1370
1371 // They can see anything in visible groups.
1372 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1);
1373 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1374 $this->assertEquals($disc13->id, $neighbours['next']->id);
1375 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
1376 $this->assertEquals($disc12->id, $neighbours['prev']->id);
1377 $this->assertEquals($disc14->id, $neighbours['next']->id);
1378
1379 // Normal user, orphan of groups, can only see non-grouped posts in separate groups.
1380 $this->setUser($user2);
1381 $_POST['group'] = 0;
1382 $this->assertEquals(0, groups_get_activity_group($cm2, true));
1383
1384 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
1385 $this->assertEmpty($neighbours['prev']);
1386 $this->assertEmpty($neighbours['next']);
1387
1388 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2);
1389 $this->assertEmpty($neighbours['prev']);
1390 $this->assertEquals($disc23->id, $neighbours['next']->id);
1391
1392 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2);
1393 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1394 $this->assertEmpty($neighbours['next']);
1395
1396 // Switching to viewing group 1.
1397 $this->setUser($user1);
1398 $_POST['group'] = $group1->id;
1399 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true));
1400 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true));
1401
1402 // They can see non-grouped or same group.
1403 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
1404 $this->assertEmpty($neighbours['prev']);
1405 $this->assertEquals($disc13->id, $neighbours['next']->id);
1406 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
1407 $this->assertEmpty($neighbours['prev']);
1408 $this->assertEquals($disc23->id, $neighbours['next']->id);
1409
1410 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
1411 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1412 $this->assertEquals($disc15->id, $neighbours['next']->id);
1413 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
1414 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1415 $this->assertEquals($disc25->id, $neighbours['next']->id);
1416
1417 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
1418 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1419 $this->assertEmpty($neighbours['next']);
1420 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
1421 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1422 $this->assertEmpty($neighbours['next']);
1423
1424 // Querying the neighbours of a discussion passing the wrong CM.
52f3e060 1425 $this->expectException('coding_exception');
8d960707
DM
1426 forum_get_discussion_neighbours($cm2, $disc11, $forum2);
1427 }
1428
1429 /**
1430 * Test getting the neighbour threads of a blog-like forum with groups involved.
1431 */
1432 public function test_forum_get_neighbours_with_groups_blog() {
1433 $this->resetAfterTest();
1434
5f219cf1
BK
1435 $timenow = time();
1436 $timenext = $timenow;
1437
8d960707
DM
1438 // Setup test data.
1439 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
1440 $course = $this->getDataGenerator()->create_course();
1441 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1442 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1443 $user1 = $this->getDataGenerator()->create_user();
1444 $user2 = $this->getDataGenerator()->create_user();
1445 $this->getDataGenerator()->enrol_user($user1->id, $course->id);
1446 $this->getDataGenerator()->enrol_user($user2->id, $course->id);
1447 $this->getDataGenerator()->create_group_member(array('userid' => $user1->id, 'groupid' => $group1->id));
1448
1449 $forum1 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog',
1450 'groupmode' => VISIBLEGROUPS));
1451 $forum2 = $this->getDataGenerator()->create_module('forum', array('course' => $course->id, 'type' => 'blog',
1452 'groupmode' => SEPARATEGROUPS));
1453 $cm1 = get_coursemodule_from_instance('forum', $forum1->id);
1454 $cm2 = get_coursemodule_from_instance('forum', $forum2->id);
1455 $context1 = context_module::instance($cm1->id);
1456 $context2 = context_module::instance($cm2->id);
1457
1458 // Creating blog posts in both forums.
1459 $record = new stdClass();
1460 $record->course = $course->id;
1461 $record->userid = $user1->id;
1462 $record->forum = $forum1->id;
826cb6f6 1463 $record->groupid = $group1->id;
6ec76606 1464 $record->timemodified = time();
826cb6f6 1465 $disc11 = $forumgen->create_discussion($record);
5f219cf1 1466 $record->timenow = $timenext++;
826cb6f6 1467 $record->forum = $forum2->id;
6ec76606 1468 $record->timemodified++;
826cb6f6
FM
1469 $disc21 = $forumgen->create_discussion($record);
1470
6ec76606 1471 $record->timemodified++;
826cb6f6
FM
1472 $record->userid = $user2->id;
1473 $record->forum = $forum1->id;
1474 $record->groupid = $group2->id;
1475 $disc12 = $forumgen->create_discussion($record);
1476 $record->forum = $forum2->id;
1477 $disc22 = $forumgen->create_discussion($record);
1478
6ec76606 1479 $record->timemodified++;
826cb6f6
FM
1480 $record->userid = $user1->id;
1481 $record->forum = $forum1->id;
1482 $record->groupid = null;
1483 $disc13 = $forumgen->create_discussion($record);
1484 $record->forum = $forum2->id;
1485 $disc23 = $forumgen->create_discussion($record);
1486
6ec76606 1487 $record->timemodified++;
826cb6f6
FM
1488 $record->userid = $user2->id;
1489 $record->forum = $forum1->id;
1490 $record->groupid = $group2->id;
1491 $disc14 = $forumgen->create_discussion($record);
1492 $record->forum = $forum2->id;
1493 $disc24 = $forumgen->create_discussion($record);
1494
6ec76606 1495 $record->timemodified++;
826cb6f6
FM
1496 $record->userid = $user1->id;
1497 $record->forum = $forum1->id;
1498 $record->groupid = $group1->id;
1499 $disc15 = $forumgen->create_discussion($record);
1500 $record->forum = $forum2->id;
1501 $disc25 = $forumgen->create_discussion($record);
1502
1503 // Admin user can see all groups.
1504 $this->setAdminUser();
9e381efd 1505 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
826cb6f6
FM
1506 $this->assertEmpty($neighbours['prev']);
1507 $this->assertEquals($disc12->id, $neighbours['next']->id);
9e381efd 1508 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
826cb6f6
FM
1509 $this->assertEmpty($neighbours['prev']);
1510 $this->assertEquals($disc22->id, $neighbours['next']->id);
1511
9e381efd 1512 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1);
826cb6f6
FM
1513 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1514 $this->assertEquals($disc13->id, $neighbours['next']->id);
9e381efd 1515 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2);
826cb6f6
FM
1516 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1517 $this->assertEquals($disc23->id, $neighbours['next']->id);
1518
9e381efd 1519 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
826cb6f6
FM
1520 $this->assertEquals($disc12->id, $neighbours['prev']->id);
1521 $this->assertEquals($disc14->id, $neighbours['next']->id);
9e381efd 1522 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
826cb6f6
FM
1523 $this->assertEquals($disc22->id, $neighbours['prev']->id);
1524 $this->assertEquals($disc24->id, $neighbours['next']->id);
1525
9e381efd 1526 $neighbours = forum_get_discussion_neighbours($cm1, $disc14, $forum1);
826cb6f6
FM
1527 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1528 $this->assertEquals($disc15->id, $neighbours['next']->id);
9e381efd 1529 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2);
826cb6f6
FM
1530 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1531 $this->assertEquals($disc25->id, $neighbours['next']->id);
1532
9e381efd 1533 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
826cb6f6
FM
1534 $this->assertEquals($disc14->id, $neighbours['prev']->id);
1535 $this->assertEmpty($neighbours['next']);
9e381efd 1536 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
826cb6f6
FM
1537 $this->assertEquals($disc24->id, $neighbours['prev']->id);
1538 $this->assertEmpty($neighbours['next']);
1539
1540 // Admin user is only viewing group 1.
1541 $_POST['group'] = $group1->id;
1542 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true));
1543 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true));
1544
9e381efd 1545 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
826cb6f6
FM
1546 $this->assertEmpty($neighbours['prev']);
1547 $this->assertEquals($disc13->id, $neighbours['next']->id);
9e381efd 1548 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
826cb6f6
FM
1549 $this->assertEmpty($neighbours['prev']);
1550 $this->assertEquals($disc23->id, $neighbours['next']->id);
1551
9e381efd 1552 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
826cb6f6
FM
1553 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1554 $this->assertEquals($disc15->id, $neighbours['next']->id);
9e381efd 1555 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
826cb6f6
FM
1556 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1557 $this->assertEquals($disc25->id, $neighbours['next']->id);
1558
9e381efd 1559 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
826cb6f6
FM
1560 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1561 $this->assertEmpty($neighbours['next']);
9e381efd 1562 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
826cb6f6
FM
1563 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1564 $this->assertEmpty($neighbours['next']);
1565
1566 // Normal user viewing non-grouped posts (this is only possible in visible groups).
1567 $this->setUser($user1);
1568 $_POST['group'] = 0;
1569 $this->assertEquals(0, groups_get_activity_group($cm1, true));
1570
1571 // They can see anything in visible groups.
9e381efd 1572 $neighbours = forum_get_discussion_neighbours($cm1, $disc12, $forum1);
826cb6f6
FM
1573 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1574 $this->assertEquals($disc13->id, $neighbours['next']->id);
9e381efd 1575 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
826cb6f6
FM
1576 $this->assertEquals($disc12->id, $neighbours['prev']->id);
1577 $this->assertEquals($disc14->id, $neighbours['next']->id);
1578
1579 // Normal user, orphan of groups, can only see non-grouped posts in separate groups.
1580 $this->setUser($user2);
1581 $_POST['group'] = 0;
1582 $this->assertEquals(0, groups_get_activity_group($cm2, true));
1583
9e381efd 1584 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
826cb6f6
FM
1585 $this->assertEmpty($neighbours['prev']);
1586 $this->assertEmpty($neighbours['next']);
1587
9e381efd 1588 $neighbours = forum_get_discussion_neighbours($cm2, $disc22, $forum2);
826cb6f6
FM
1589 $this->assertEmpty($neighbours['prev']);
1590 $this->assertEquals($disc23->id, $neighbours['next']->id);
1591
9e381efd 1592 $neighbours = forum_get_discussion_neighbours($cm2, $disc24, $forum2);
826cb6f6
FM
1593 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1594 $this->assertEmpty($neighbours['next']);
1595
1596 // Switching to viewing group 1.
1597 $this->setUser($user1);
1598 $_POST['group'] = $group1->id;
1599 $this->assertEquals($group1->id, groups_get_activity_group($cm1, true));
1600 $this->assertEquals($group1->id, groups_get_activity_group($cm2, true));
1601
1602 // They can see non-grouped or same group.
9e381efd 1603 $neighbours = forum_get_discussion_neighbours($cm1, $disc11, $forum1);
826cb6f6
FM
1604 $this->assertEmpty($neighbours['prev']);
1605 $this->assertEquals($disc13->id, $neighbours['next']->id);
9e381efd 1606 $neighbours = forum_get_discussion_neighbours($cm2, $disc21, $forum2);
826cb6f6
FM
1607 $this->assertEmpty($neighbours['prev']);
1608 $this->assertEquals($disc23->id, $neighbours['next']->id);
1609
9e381efd 1610 $neighbours = forum_get_discussion_neighbours($cm1, $disc13, $forum1);
826cb6f6
FM
1611 $this->assertEquals($disc11->id, $neighbours['prev']->id);
1612 $this->assertEquals($disc15->id, $neighbours['next']->id);
9e381efd 1613 $neighbours = forum_get_discussion_neighbours($cm2, $disc23, $forum2);
826cb6f6
FM
1614 $this->assertEquals($disc21->id, $neighbours['prev']->id);
1615 $this->assertEquals($disc25->id, $neighbours['next']->id);
1616
9e381efd 1617 $neighbours = forum_get_discussion_neighbours($cm1, $disc15, $forum1);
826cb6f6
FM
1618 $this->assertEquals($disc13->id, $neighbours['prev']->id);
1619 $this->assertEmpty($neighbours['next']);
9e381efd 1620 $neighbours = forum_get_discussion_neighbours($cm2, $disc25, $forum2);
826cb6f6
FM
1621 $this->assertEquals($disc23->id, $neighbours['prev']->id);
1622 $this->assertEmpty($neighbours['next']);
1623
1624 // Querying the neighbours of a discussion passing the wrong CM.
52f3e060 1625 $this->expectException('coding_exception');
9e381efd 1626 forum_get_discussion_neighbours($cm2, $disc11, $forum2);
826cb6f6 1627 }
94802d35
AN
1628
1629 public function test_count_discussion_replies_basic() {
1630 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1631
1632 // Count the discussion replies in the forum.
1633 $result = forum_count_discussion_replies($forum->id);
1634 $this->assertCount(10, $result);
1635 }
1636
1637 public function test_count_discussion_replies_limited() {
1638 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1639 // Adding limits shouldn't make a difference.
1640 $result = forum_count_discussion_replies($forum->id, "", 20);
1641 $this->assertCount(10, $result);
1642 }
1643
1644 public function test_count_discussion_replies_paginated() {
1645 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1646 // Adding paging shouldn't make any difference.
1647 $result = forum_count_discussion_replies($forum->id, "", -1, 0, 100);
1648 $this->assertCount(10, $result);
1649 }
1650
1651 public function test_count_discussion_replies_paginated_sorted() {
1652 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1653 // Specifying the forumsort should also give a good result. This follows a different path.
1654 $result = forum_count_discussion_replies($forum->id, "d.id asc", -1, 0, 100);
1655 $this->assertCount(10, $result);
1656 foreach ($result as $row) {
1657 // Grab the first discussionid.
1658 $discussionid = array_shift($discussionids);
1659 $this->assertEquals($discussionid, $row->discussion);
1660 }
1661 }
1662
1663 public function test_count_discussion_replies_limited_sorted() {
1664 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1665 // Adding limits, and a forumsort shouldn't make a difference.
1666 $result = forum_count_discussion_replies($forum->id, "d.id asc", 20);
1667 $this->assertCount(10, $result);
1668 foreach ($result as $row) {
1669 // Grab the first discussionid.
1670 $discussionid = array_shift($discussionids);
1671 $this->assertEquals($discussionid, $row->discussion);
1672 }
1673 }
1674
1675 public function test_count_discussion_replies_paginated_sorted_small() {
1676 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1677 // Grabbing a smaller subset and they should be ordered as expected.
1678 $result = forum_count_discussion_replies($forum->id, "d.id asc", -1, 0, 5);
1679 $this->assertCount(5, $result);
1680 foreach ($result as $row) {
1681 // Grab the first discussionid.
1682 $discussionid = array_shift($discussionids);
1683 $this->assertEquals($discussionid, $row->discussion);
1684 }
1685 }
1686
1687 public function test_count_discussion_replies_paginated_sorted_small_reverse() {
1688 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1689 // Grabbing a smaller subset and they should be ordered as expected.
1690 $result = forum_count_discussion_replies($forum->id, "d.id desc", -1, 0, 5);
1691 $this->assertCount(5, $result);
1692 foreach ($result as $row) {
1693 // Grab the last discussionid.
1694 $discussionid = array_pop($discussionids);
1695 $this->assertEquals($discussionid, $row->discussion);
1696 }
1697 }
1698
1699 public function test_count_discussion_replies_limited_sorted_small_reverse() {
1700 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1701 // Adding limits, and a forumsort shouldn't make a difference.
1702 $result = forum_count_discussion_replies($forum->id, "d.id desc", 5);
1703 $this->assertCount(5, $result);
1704 foreach ($result as $row) {
1705 // Grab the last discussionid.
1706 $discussionid = array_pop($discussionids);
1707 $this->assertEquals($discussionid, $row->discussion);
1708 }
1709 }
5f219cf1
BK
1710 public function test_discussion_pinned_sort() {
1711 list($forum, $discussionids) = $this->create_multiple_discussions_with_replies(10, 5);
1712 $cm = get_coursemodule_from_instance('forum', $forum->id);
1713 $discussions = forum_get_discussions($cm);
1714 // First discussion should be pinned.
1715 $first = reset($discussions);
1716 $this->assertEquals(1, $first->pinned, "First discussion should be pinned discussion");
1717 }
ebfa74c7
JL
1718 public function test_forum_view() {
1719 global $CFG;
1720
1721 $CFG->enablecompletion = 1;
1722 $this->resetAfterTest();
1723
1724 // Setup test data.
1725 $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
1726 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id),
1727 array('completion' => 2, 'completionview' => 1));
1728 $context = context_module::instance($forum->cmid);
1729 $cm = get_coursemodule_from_instance('forum', $forum->id);
1730
1731 // Trigger and capture the event.
1732 $sink = $this->redirectEvents();
1733
1734 $this->setAdminUser();
1735 forum_view($forum, $course, $cm, $context);
1736
1737 $events = $sink->get_events();
1738 // 2 additional events thanks to completion.
1739 $this->assertCount(3, $events);
1740 $event = array_pop($events);
1741
1742 // Checking that the event contains the expected values.
1743 $this->assertInstanceOf('\mod_forum\event\course_module_viewed', $event);
1744 $this->assertEquals($context, $event->get_context());
1745 $url = new \moodle_url('/mod/forum/view.php', array('f' => $forum->id));
1746 $this->assertEquals($url, $event->get_url());
1747 $this->assertEventContextNotUsed($event);
1748 $this->assertNotEmpty($event->get_name());
1749
1750 // Check completion status.
1751 $completion = new completion_info($course);
1752 $completiondata = $completion->get_data($cm);
1753 $this->assertEquals(1, $completiondata->completionstate);
1754
1755 }
1756
6e5df52c
JL
1757 /**
1758 * Test forum_discussion_view.
1759 */
1760 public function test_forum_discussion_view() {
1761 global $CFG, $USER;
1762
1763 $this->resetAfterTest();
1764
1765 // Setup test data.
1766 $course = $this->getDataGenerator()->create_course();
1767 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1768 $discussion = $this->create_single_discussion_with_replies($forum, $USER, 2);
1769
1770 $context = context_module::instance($forum->cmid);
1771 $cm = get_coursemodule_from_instance('forum', $forum->id);
1772
1773 // Trigger and capture the event.
1774 $sink = $this->redirectEvents();
1775
1776 $this->setAdminUser();
1777 forum_discussion_view($context, $forum, $discussion);
1778
1779 $events = $sink->get_events();
1780 $this->assertCount(1, $events);
1781 $event = array_pop($events);
1782
1783 // Checking that the event contains the expected values.
1784 $this->assertInstanceOf('\mod_forum\event\discussion_viewed', $event);
1785 $this->assertEquals($context, $event->get_context());
1786 $expected = array($course->id, 'forum', 'view discussion', "discuss.php?d={$discussion->id}",
1787 $discussion->id, $forum->cmid);
1788 $this->assertEventLegacyLogData($expected, $event);
1789 $this->assertEventContextNotUsed($event);
1790
1791 $this->assertNotEmpty($event->get_name());
1792
1793 }
1794
94802d35
AN
1795 /**
1796 * Create a new course, forum, and user with a number of discussions and replies.
1797 *
1798 * @param int $discussioncount The number of discussions to create
1799 * @param int $replycount The number of replies to create in each discussion
1800 * @return array Containing the created forum object, and the ids of the created discussions.
1801 */
1802 protected function create_multiple_discussions_with_replies($discussioncount, $replycount) {
1803 $this->resetAfterTest();
1804
1805 // Setup the content.
1806 $user = $this->getDataGenerator()->create_user();
1807 $course = $this->getDataGenerator()->create_course();
1808 $record = new stdClass();
1809 $record->course = $course->id;
1810 $forum = $this->getDataGenerator()->create_module('forum', $record);
1811
1812 // Create 10 discussions with replies.
1813 $discussionids = array();
1814 for ($i = 0; $i < $discussioncount; $i++) {
5f219cf1
BK
1815 // Pin 3rd discussion.
1816 if ($i == 3) {
1817 $discussion = $this->create_single_discussion_pinned_with_replies($forum, $user, $replycount);
1818 } else {
1819 $discussion = $this->create_single_discussion_with_replies($forum, $user, $replycount);
1820 }
1821
94802d35
AN
1822 $discussionids[] = $discussion->id;
1823 }
1824 return array($forum, $discussionids);
1825 }
1826
1827 /**
1828 * Create a discussion with a number of replies.
1829 *
1830 * @param object $forum The forum which has been created
1831 * @param object $user The user making the discussion and replies
1832 * @param int $replycount The number of replies
1833 * @return object $discussion
1834 */
1835 protected function create_single_discussion_with_replies($forum, $user, $replycount) {
1836 global $DB;
1837
1838 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum');
1839
1840 $record = new stdClass();
1841 $record->course = $forum->course;
1842 $record->forum = $forum->id;
1843 $record->userid = $user->id;
1844 $discussion = $generator->create_discussion($record);
1845
1846 // Retrieve the first post.
1847 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
5f219cf1
BK
1848
1849 // Create the replies.
1850 $post = new stdClass();
1851 $post->userid = $user->id;
1852 $post->discussion = $discussion->id;
1853 $post->parent = $replyto->id;
1854
1855 for ($i = 0; $i < $replycount; $i++) {
1856 $generator->create_post($post);
1857 }
1858
1859 return $discussion;
1860 }
1861 /**
1862 * Create a discussion with a number of replies.
1863 *
1864 * @param object $forum The forum which has been created
1865 * @param object $user The user making the discussion and replies
1866 * @param int $replycount The number of replies
1867 * @return object $discussion
1868 */
1869 protected function create_single_discussion_pinned_with_replies($forum, $user, $replycount) {
1870 global $DB;
1871
1872 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum');
1873
1874 $record = new stdClass();
1875 $record->course = $forum->course;
1876 $record->forum = $forum->id;
1877 $record->userid = $user->id;
f9621c56 1878 $record->pinned = FORUM_DISCUSSION_PINNED;
5f219cf1
BK
1879 $discussion = $generator->create_discussion($record);
1880
1881 // Retrieve the first post.
1882 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
94802d35
AN
1883
1884 // Create the replies.
1885 $post = new stdClass();
1886 $post->userid = $user->id;
1887 $post->discussion = $discussion->id;
1888 $post->parent = $replyto->id;
1889
1890 for ($i = 0; $i < $replycount; $i++) {
1891 $generator->create_post($post);
1892 }
1893
1894 return $discussion;
1895 }
1896
731c2712
AA
1897 /**
1898 * Tests for mod_forum_rating_can_see_item_ratings().
1899 *
1900 * @throws coding_exception
1901 * @throws rating_exception
1902 */
1903 public function test_mod_forum_rating_can_see_item_ratings() {
1904 global $DB;
1905
1906 $this->resetAfterTest();
1907
1908 // Setup test data.
1909 $course = new stdClass();
1910 $course->groupmode = SEPARATEGROUPS;
1911 $course->groupmodeforce = true;
1912 $course = $this->getDataGenerator()->create_course($course);
1913 $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
1914 $generator = self::getDataGenerator()->get_plugin_generator('mod_forum');
1915 $cm = get_coursemodule_from_instance('forum', $forum->id);
1916 $context = context_module::instance($cm->id);
1917
1918 // Create users.
1919 $user1 = $this->getDataGenerator()->create_user();
1920 $user2 = $this->getDataGenerator()->create_user();
1921 $user3 = $this->getDataGenerator()->create_user();
1922 $user4 = $this->getDataGenerator()->create_user();
1923
1924 // Groups and stuff.
1925 $role = $DB->get_record('role', array('shortname' => 'teacher'), '*', MUST_EXIST);
1926 $this->getDataGenerator()->enrol_user($user1->id, $course->id, $role->id);
1927 $this->getDataGenerator()->enrol_user($user2->id, $course->id, $role->id);
1928 $this->getDataGenerator()->enrol_user($user3->id, $course->id, $role->id);
1929 $this->getDataGenerator()->enrol_user($user4->id, $course->id, $role->id);
1930
1931 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1932 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
1933 groups_add_member($group1, $user1);
1934 groups_add_member($group1, $user2);
1935 groups_add_member($group2, $user3);
1936 groups_add_member($group2, $user4);
1937
1938 $record = new stdClass();
1939 $record->course = $forum->course;
1940 $record->forum = $forum->id;
1941 $record->userid = $user1->id;
1942 $record->groupid = $group1->id;
1943 $discussion = $generator->create_discussion($record);
1944
1945 // Retrieve the first post.
1946 $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
1947
1948 $ratingoptions = new stdClass;
1949 $ratingoptions->context = $context;
1950 $ratingoptions->ratingarea = 'post';
1951 $ratingoptions->component = 'mod_forum';
1952 $ratingoptions->itemid = $post->id;
1953 $ratingoptions->scaleid = 2;
1954 $ratingoptions->userid = $user2->id;
1955 $rating = new rating($ratingoptions);
1956 $rating->update_rating(2);
1957
1958 // Now try to access it as various users.
1959 unassign_capability('moodle/site:accessallgroups', $role->id);
1960 $params = array('contextid' => 2,
1961 'component' => 'mod_forum',
1962 'ratingarea' => 'post',
1963 'itemid' => $post->id,
1964 'scaleid' => 2);
1965 $this->setUser($user1);
1966 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1967 $this->setUser($user2);
1968 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1969 $this->setUser($user3);
1970 $this->assertFalse(mod_forum_rating_can_see_item_ratings($params));
1971 $this->setUser($user4);
1972 $this->assertFalse(mod_forum_rating_can_see_item_ratings($params));
1973
1974 // Now try with accessallgroups cap and make sure everything is visible.
1975 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role->id, $context->id);
1976 $this->setUser($user1);
1977 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1978 $this->setUser($user2);
1979 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1980 $this->setUser($user3);
1981 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1982 $this->setUser($user4);
1983 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1984
1985 // Change group mode and verify visibility.
1986 $course->groupmode = VISIBLEGROUPS;
1987 $DB->update_record('course', $course);
1988 unassign_capability('moodle/site:accessallgroups', $role->id);
1989 $this->setUser($user1);
1990 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1991 $this->setUser($user2);
1992 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1993 $this->setUser($user3);
1994 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1995 $this->setUser($user4);
1996 $this->assertTrue(mod_forum_rating_can_see_item_ratings($params));
1997
1998 }
1999
4f3a2d21
JL
2000 /**
2001 * Test forum_get_discussions
2002 */
2003 public function test_forum_get_discussions_with_groups() {
2004 global $DB;
2005
2006 $this->resetAfterTest(true);
2007
2008 // Create course to add the module.
2009 $course = self::getDataGenerator()->create_course(array('groupmode' => VISIBLEGROUPS, 'groupmodeforce' => 0));
2010 $user1 = self::getDataGenerator()->create_user();
2011 $user2 = self::getDataGenerator()->create_user();
2012 $user3 = self::getDataGenerator()->create_user();
2013
2014 $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
2015 self::getDataGenerator()->enrol_user($user1->id, $course->id, $role->id);
2016 self::getDataGenerator()->enrol_user($user2->id, $course->id, $role->id);
2017 self::getDataGenerator()->enrol_user($user3->id, $course->id, $role->id);
2018
2019 // Forum forcing separate gropus.
2020 $record = new stdClass();
2021 $record->course = $course->id;
2022 $forum = self::getDataGenerator()->create_module('forum', $record, array('groupmode' => SEPARATEGROUPS));
2023 $cm = get_coursemodule_from_instance('forum', $forum->id);
2024
2025 // Create groups.
2026 $group1 = self::getDataGenerator()->create_group(array('courseid' => $course->id));
2027 $group2 = self::getDataGenerator()->create_group(array('courseid' => $course->id));
2028 $group3 = self::getDataGenerator()->create_group(array('courseid' => $course->id));
2029
2030 // Add the user1 to g1 and g2 groups.
2031 groups_add_member($group1->id, $user1->id);
2032 groups_add_member($group2->id, $user1->id);
2033
2034 // Add the user 2 and 3 to only one group.
2035 groups_add_member($group1->id, $user2->id);
2036 groups_add_member($group3->id, $user3->id);
2037
2038 // Add a few discussions.
2039 $record = array();
2040 $record['course'] = $course->id;
2041 $record['forum'] = $forum->id;
2042 $record['userid'] = $user1->id;
2043 $record['groupid'] = $group1->id;
2044 $discussiong1u1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2045
2046 $record['groupid'] = $group2->id;
2047 $discussiong2u1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2048
2049 $record['userid'] = $user2->id;
2050 $record['groupid'] = $group1->id;
2051 $discussiong1u2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2052
2053 $record['userid'] = $user3->id;
2054 $record['groupid'] = $group3->id;
2055 $discussiong3u3 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2056
2057 self::setUser($user1);
2058 // Test retrieve discussions not passing the groupid parameter. We will receive only first group discussions.
2059 $discussions = forum_get_discussions($cm);
2060 self::assertCount(2, $discussions);
2061 foreach ($discussions as $discussion) {
2062 self::assertEquals($group1->id, $discussion->groupid);
2063 }
2064
2065 // Get all my discussions.
2066 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, 0);
2067 self::assertCount(3, $discussions);
2068
2069 // Get all my g1 discussions.
2070 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group1->id);
2071 self::assertCount(2, $discussions);
2072 foreach ($discussions as $discussion) {
2073 self::assertEquals($group1->id, $discussion->groupid);
2074 }
2075
2076 // Get all my g2 discussions.
2077 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group2->id);
2078 self::assertCount(1, $discussions);
2079 $discussion = array_shift($discussions);
2080 self::assertEquals($group2->id, $discussion->groupid);
2081 self::assertEquals($user1->id, $discussion->userid);
2082 self::assertEquals($discussiong2u1->id, $discussion->discussion);
2083
2084 // Get all my g3 discussions (I'm not enrolled in that group).
2085 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id);
2086 self::assertCount(0, $discussions);
2087
2088 // This group does not exist.
2089 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id + 1000);
2090 self::assertCount(0, $discussions);
2091
2092 self::setUser($user2);
2093
2094 // Test retrieve discussions not passing the groupid parameter. We will receive only first group discussions.
2095 $discussions = forum_get_discussions($cm);
2096 self::assertCount(2, $discussions);
2097 foreach ($discussions as $discussion) {
2098 self::assertEquals($group1->id, $discussion->groupid);
2099 }
2100
2101 // Get all my viewable discussions.
2102 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, 0);
2103 self::assertCount(2, $discussions);
2104 foreach ($discussions as $discussion) {
2105 self::assertEquals($group1->id, $discussion->groupid);
2106 }
2107
2108 // Get all my g2 discussions (I'm not enrolled in that group).
2109 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group2->id);
2110 self::assertCount(0, $discussions);
2111
2112 // Get all my g3 discussions (I'm not enrolled in that group).
2113 $discussions = forum_get_discussions($cm, '', true, -1, -1, false, -1, 0, $group3->id);
2114 self::assertCount(0, $discussions);
2115
2116 }
04cd8ae3
JL
2117
2118 /**
2119 * Test forum_user_can_post_discussion
2120 */
2121 public function test_forum_user_can_post_discussion() {
2122 global $CFG, $DB;
2123
2124 $this->resetAfterTest(true);
2125
2126 // Create course to add the module.
2127 $course = self::getDataGenerator()->create_course(array('groupmode' => SEPARATEGROUPS, 'groupmodeforce' => 1));
2128 $user = self::getDataGenerator()->create_user();
2129 $this->getDataGenerator()->enrol_user($user->id, $course->id);
2130
2131 // Forum forcing separate gropus.
2132 $record = new stdClass();
2133 $record->course = $course->id;
2134 $forum = self::getDataGenerator()->create_module('forum', $record, array('groupmode' => SEPARATEGROUPS));
2135 $cm = get_coursemodule_from_instance('forum', $forum->id);
2136 $context = context_module::instance($cm->id);
2137
2138 self::setUser($user);
2139
2140 // The user is not enroled in any group, try to post in a forum with separate groups.
2141 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2142 $this->assertFalse($can);
2143
2144 // Create a group.
2145 $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
2146
2147 // Try to post in a group the user is not enrolled.
2148 $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context);
2149 $this->assertFalse($can);
2150
2151 // Add the user to a group.
2152 groups_add_member($group->id, $user->id);
2153
2154 // Try to post in a group the user is not enrolled.
2155 $can = forum_user_can_post_discussion($forum, $group->id + 1, -1, $cm, $context);
2156 $this->assertFalse($can);
2157
2158 // Now try to post in the user group. (null means it will guess the group).
2159 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2160 $this->assertTrue($can);
2161
2162 $can = forum_user_can_post_discussion($forum, $group->id, -1, $cm, $context);
2163 $this->assertTrue($can);
2164
2165 // Test all groups.
2166 $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context);
2167 $this->assertFalse($can);
2168
2169 $this->setAdminUser();
2170 $can = forum_user_can_post_discussion($forum, -1, -1, $cm, $context);
2171 $this->assertTrue($can);
2172
2173 // Change forum type.
2174 $forum->type = 'news';
2175 $DB->update_record('forum', $forum);
2176
2177 // Admin can post news.
2178 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2179 $this->assertTrue($can);
2180
2181 // Normal users don't.
2182 self::setUser($user);
2183 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2184 $this->assertFalse($can);
2185
2186 // Change forum type.
2187 $forum->type = 'eachuser';
2188 $DB->update_record('forum', $forum);
2189
2190 // I didn't post yet, so I should be able to post.
2191 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2192 $this->assertTrue($can);
2193
2194 // Post now.
2195 $record = new stdClass();
2196 $record->course = $course->id;
2197 $record->userid = $user->id;
2198 $record->forum = $forum->id;
c0e3c8ae 2199 $record->groupid = $group->id;
04cd8ae3
JL
2200 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2201
2202 // I already posted, I shouldn't be able to post.
2203 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2204 $this->assertFalse($can);
2205
2206 // Last check with no groups, normal forum and course.
2207 $course->groupmode = NOGROUPS;
2208 $course->groupmodeforce = 0;
2209 $DB->update_record('course', $course);
2210
2211 $forum->type = 'general';
2212 $forum->groupmode = NOGROUPS;
2213 $DB->update_record('forum', $forum);
2214
2215 $can = forum_user_can_post_discussion($forum, null, -1, $cm, $context);
2216 $this->assertTrue($can);
2217 }
bef0d6b0 2218
c0e3c8ae
AN
2219 /**
2220 * Test forum_user_has_posted_discussion with no groups.
2221 */
2222 public function test_forum_user_has_posted_discussion_no_groups() {
2223 global $CFG;
2224
2225 $this->resetAfterTest(true);
2226
2227 $course = self::getDataGenerator()->create_course();
2228 $author = self::getDataGenerator()->create_user();
2229 $other = self::getDataGenerator()->create_user();
2230 $this->getDataGenerator()->enrol_user($author->id, $course->id);
2231 $forum = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]);
2232
2233 self::setUser($author);
2234
2235 // Neither user has posted.
2236 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id));
2237 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $other->id));
2238
2239 // Post in the forum.
2240 $record = new stdClass();
2241 $record->course = $course->id;
2242 $record->userid = $author->id;
2243 $record->forum = $forum->id;
2244 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2245
2246 // The author has now posted, but the other user has not.
2247 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id));
2248 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $other->id));
2249 }
2250
2251 /**
2252 * Test forum_user_has_posted_discussion with multiple forums
2253 */
2254 public function test_forum_user_has_posted_discussion_multiple_forums() {
2255 global $CFG;
2256
2257 $this->resetAfterTest(true);
2258
2259 $course = self::getDataGenerator()->create_course();
2260 $author = self::getDataGenerator()->create_user();
2261 $this->getDataGenerator()->enrol_user($author->id, $course->id);
2262 $forum1 = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]);
2263 $forum2 = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ]);
2264
2265 self::setUser($author);
2266
2267 // No post in either forum.
2268 $this->assertFalse(forum_user_has_posted_discussion($forum1->id, $author->id));
2269 $this->assertFalse(forum_user_has_posted_discussion($forum2->id, $author->id));
2270
2271 // Post in the forum.
2272 $record = new stdClass();
2273 $record->course = $course->id;
2274 $record->userid = $author->id;
2275 $record->forum = $forum1->id;
2276 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2277
2278 // The author has now posted in forum1, but not forum2.
2279 $this->assertTrue(forum_user_has_posted_discussion($forum1->id, $author->id));
2280 $this->assertFalse(forum_user_has_posted_discussion($forum2->id, $author->id));
2281 }
2282
2283 /**
2284 * Test forum_user_has_posted_discussion with multiple groups.
2285 */
2286 public function test_forum_user_has_posted_discussion_multiple_groups() {
2287 global $CFG;
2288
2289 $this->resetAfterTest(true);
2290
2291 $course = self::getDataGenerator()->create_course();
2292 $author = self::getDataGenerator()->create_user();
2293 $this->getDataGenerator()->enrol_user($author->id, $course->id);
2294
2295 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
2296 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
2297 groups_add_member($group1->id, $author->id);
2298 groups_add_member($group2->id, $author->id);
2299
2300 $forum = self::getDataGenerator()->create_module('forum', (object) ['course' => $course->id ], [
2301 'groupmode' => SEPARATEGROUPS,
2302 ]);
2303
2304 self::setUser($author);
2305
2306 // The user has not posted in either group.
2307 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id));
2308 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id));
2309 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id));
2310
2311 // Post in one group.
2312 $record = new stdClass();
2313 $record->course = $course->id;
2314 $record->userid = $author->id;
2315 $record->forum = $forum->id;
2316 $record->groupid = $group1->id;
2317 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2318
2319 // The author has now posted in one group, but the other user has not.
2320 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id));
2321 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id));
2322 $this->assertFalse(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id));
2323
2324 // Post in the other group.
2325 $record = new stdClass();
2326 $record->course = $course->id;
2327 $record->userid = $author->id;
2328 $record->forum = $forum->id;
2329 $record->groupid = $group2->id;
2330 $discussion = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2331
2332 // The author has now posted in one group, but the other user has not.
2333 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id));
2334 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group1->id));
2335 $this->assertTrue(forum_user_has_posted_discussion($forum->id, $author->id, $group2->id));
2336 }
2337
bef0d6b0 2338 /**
be5e0110 2339 * Tests the mod_forum_myprofile_navigation() function.
bef0d6b0
AA
2340 */
2341 public function test_mod_forum_myprofile_navigation() {
be5e0110
MN
2342 $this->resetAfterTest(true);
2343
2344 // Set up the test.
2345 $tree = new \core_user\output\myprofile\tree();
2346 $user = $this->getDataGenerator()->create_user();
2347 $course = $this->getDataGenerator()->create_course();
2348 $iscurrentuser = true;
2349
2350 // Set as the current user.
2351 $this->setUser($user);
2352
2353 // Check the node tree is correct.
2354 mod_forum_myprofile_navigation($tree, $user, $iscurrentuser, $course);
2355 $reflector = new ReflectionObject($tree);
2356 $nodes = $reflector->getProperty('nodes');
2357 $nodes->setAccessible(true);
2358 $this->assertArrayHasKey('forumposts', $nodes->getValue($tree));
2359 $this->assertArrayHasKey('forumdiscussions', $nodes->getValue($tree));
2360 }
2361
2362 /**
2363 * Tests the mod_forum_myprofile_navigation() function as a guest.
2364 */
2365 public function test_mod_forum_myprofile_navigation_as_guest() {
bef0d6b0
AA
2366 global $USER;
2367
be5e0110 2368 $this->resetAfterTest(true);
bef0d6b0 2369
be5e0110
MN
2370 // Set up the test.
2371 $tree = new \core_user\output\myprofile\tree();
bef0d6b0 2372 $course = $this->getDataGenerator()->create_course();
be5e0110
MN
2373 $iscurrentuser = true;
2374
2375 // Set user as guest.
2376 $this->setGuestUser();
bef0d6b0 2377
be5e0110 2378 // Check the node tree is correct.
bef0d6b0 2379 mod_forum_myprofile_navigation($tree, $USER, $iscurrentuser, $course);
be5e0110
MN
2380 $reflector = new ReflectionObject($tree);
2381 $nodes = $reflector->getProperty('nodes');
2382 $nodes->setAccessible(true);
2383 $this->assertArrayNotHasKey('forumposts', $nodes->getValue($tree));
2384 $this->assertArrayNotHasKey('forumdiscussions', $nodes->getValue($tree));
2385 }
bef0d6b0 2386
be5e0110
MN
2387 /**
2388 * Tests the mod_forum_myprofile_navigation() function as a user viewing another user's profile.
2389 */
2390 public function test_mod_forum_myprofile_navigation_different_user() {
2391 $this->resetAfterTest(true);
2392
2393 // Set up the test.
2394 $tree = new \core_user\output\myprofile\tree();
2395 $user = $this->getDataGenerator()->create_user();
2396 $user2 = $this->getDataGenerator()->create_user();
2397 $course = $this->getDataGenerator()->create_course();
bef0d6b0 2398 $iscurrentuser = true;
bef0d6b0 2399
be5e0110 2400 // Set to different user's profile.
bef0d6b0 2401 $this->setUser($user2);
be5e0110
MN
2402
2403 // Check the node tree is correct.
bef0d6b0 2404 mod_forum_myprofile_navigation($tree, $user, $iscurrentuser, $course);
be5e0110
MN
2405 $reflector = new ReflectionObject($tree);
2406 $nodes = $reflector->getProperty('nodes');
2407 $nodes->setAccessible(true);
2408 $this->assertArrayHasKey('forumposts', $nodes->getValue($tree));
2409 $this->assertArrayHasKey('forumdiscussions', $nodes->getValue($tree));
bef0d6b0 2410 }
6667ebb9
AN
2411
2412 public function test_print_overview() {
2413 $this->resetAfterTest();
2414 $course1 = self::getDataGenerator()->create_course();
2415 $course2 = self::getDataGenerator()->create_course();
2416
2417 // Create an author user.
2418 $author = self::getDataGenerator()->create_user();
2419 $this->getDataGenerator()->enrol_user($author->id, $course1->id);
2420 $this->getDataGenerator()->enrol_user($author->id, $course2->id);
2421
2422 // Create a viewer user.
2423 $viewer = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2424 $this->getDataGenerator()->enrol_user($viewer->id, $course1->id);
2425 $this->getDataGenerator()->enrol_user($viewer->id, $course2->id);
2426
2427 // Create two forums - one in each course.
2428 $record = new stdClass();
2429 $record->course = $course1->id;
2430 $forum1 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course1->id));
2431 $forum2 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course2->id));
2432
2433 // A standard post in the forum.
2434 $record = new stdClass();
2435 $record->course = $course1->id;
2436 $record->userid = $author->id;
2437 $record->forum = $forum1->id;
2438 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2439
2440 $this->setUser($viewer->id);
2441 $courses = array(
2442 $course1->id => clone $course1,
2443 $course2->id => clone $course2,
2444 );
2445
2446 foreach ($courses as $courseid => $course) {
2447 $courses[$courseid]->lastaccess = 0;
2448 }
2449 $results = array();
2450 forum_print_overview($courses, $results);
2451
2452 // There should be one entry for course1, and no others.
2453 $this->assertCount(1, $results);
2454
2455 // There should be one entry for a forum in course1.
2456 $this->assertCount(1, $results[$course1->id]);
2457 $this->assertArrayHasKey('forum', $results[$course1->id]);
2458 }
2459
2460 public function test_print_overview_groups() {
6667ebb9
AN
2461 $this->resetAfterTest();
2462 $course1 = self::getDataGenerator()->create_course();
2463 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
2464 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
2465
2466 // Create an author user.
2467 $author = self::getDataGenerator()->create_user();
2468 $this->getDataGenerator()->enrol_user($author->id, $course1->id);
2469
2470 // Create two viewer users - one in each group.
2471 $viewer1 = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2472 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id);
2473 $this->getDataGenerator()->create_group_member(array('userid' => $viewer1->id, 'groupid' => $group1->id));
2474
2475 $viewer2 = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2476 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id);
2477 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group2->id));
2478
2479 // Create a forum.
2480 $record = new stdClass();
2481 $record->course = $course1->id;
2482 $forum1 = self::getDataGenerator()->create_module('forum', (object) array(
2483 'course' => $course1->id,
2484 'groupmode' => SEPARATEGROUPS,
2485 ));
2486
2487 // A post in the forum for group1.
2488 $record = new stdClass();
2489 $record->course = $course1->id;
2490 $record->userid = $author->id;
2491 $record->forum = $forum1->id;
2492 $record->groupid = $group1->id;
2493 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2494
2495 $course1->lastaccess = 0;
2496 $courses = array($course1->id => $course1);
2497
2498 // As viewer1 (same group as post).
2499 $this->setUser($viewer1->id);
2500 $results = array();
2501 forum_print_overview($courses, $results);
2502
2503 // There should be one entry for course1.
2504 $this->assertCount(1, $results);
2505
2506 // There should be one entry for a forum in course1.
2507 $this->assertCount(1, $results[$course1->id]);
2508 $this->assertArrayHasKey('forum', $results[$course1->id]);
2509
6667ebb9
AN
2510 $this->setUser($viewer2->id);
2511 $results = array();
2512 forum_print_overview($courses, $results);
2513
2514 // There should be one entry for course1.
2515 $this->assertCount(0, $results);
2516 }
2517
2518 /**
2519 * @dataProvider print_overview_timed_provider
2520 */
2521 public function test_print_overview_timed($config, $hasresult) {
2522 $this->resetAfterTest();
2523 $course1 = self::getDataGenerator()->create_course();
2524
2525 // Create an author user.
2526 $author = self::getDataGenerator()->create_user();
2527 $this->getDataGenerator()->enrol_user($author->id, $course1->id);
2528
2529 // Create a viewer user.
2530 $viewer = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2531 $this->getDataGenerator()->enrol_user($viewer->id, $course1->id);
2532
2533 // Create a forum.
2534 $record = new stdClass();
2535 $record->course = $course1->id;
2536 $forum1 = self::getDataGenerator()->create_module('forum', (object) array('course' => $course1->id));
2537
2538 // A timed post with a timestart in the past (24 hours ago).
2539 $record = new stdClass();
2540 $record->course = $course1->id;
2541 $record->userid = $author->id;
2542 $record->forum = $forum1->id;
2543 if (isset($config['timestartmodifier'])) {
2544 $record->timestart = time() + $config['timestartmodifier'];
2545 }
2546 if (isset($config['timeendmodifier'])) {
2547 $record->timeend = time() + $config['timeendmodifier'];
2548 }
2549 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2550
2551 $course1->lastaccess = 0;
2552 $courses = array($course1->id => $course1);
2553
2554 // As viewer, check the forum_print_overview result.
2555 $this->setUser($viewer->id);
2556 $results = array();
2557 forum_print_overview($courses, $results);
2558
2559 if ($hasresult) {
2560 // There should be one entry for course1.
2561 $this->assertCount(1, $results);
2562
2563 // There should be one entry for a forum in course1.
2564 $this->assertCount(1, $results[$course1->id]);
2565 $this->assertArrayHasKey('forum', $results[$course1->id]);
2566 } else {
2567 // There should be no entries for any course.
2568 $this->assertCount(0, $results);
2569 }
2570 }
2571
2572 /**
2573 * @dataProvider print_overview_timed_provider
2574 */
2575 public function test_print_overview_timed_groups($config, $hasresult) {
6667ebb9
AN
2576 $this->resetAfterTest();
2577 $course1 = self::getDataGenerator()->create_course();
2578 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
2579 $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
2580
2581 // Create an author user.
2582 $author = self::getDataGenerator()->create_user();
2583 $this->getDataGenerator()->enrol_user($author->id, $course1->id);
2584
2585 // Create two viewer users - one in each group.
2586 $viewer1 = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2587 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id);
2588 $this->getDataGenerator()->create_group_member(array('userid' => $viewer1->id, 'groupid' => $group1->id));
2589
2590 $viewer2 = self::getDataGenerator()->create_user((object) array('trackforums' => 1));
2591 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id);
2592 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group2->id));
2593
2594 // Create a forum.
2595 $record = new stdClass();
2596 $record->course = $course1->id;
2597 $forum1 = self::getDataGenerator()->create_module('forum', (object) array(
2598 'course' => $course1->id,
2599 'groupmode' => SEPARATEGROUPS,
2600 ));
2601
2602 // A post in the forum for group1.
2603 $record = new stdClass();
2604 $record->course = $course1->id;
2605 $record->userid = $author->id;
2606 $record->forum = $forum1->id;
2607 $record->groupid = $group1->id;
2608 if (isset($config['timestartmodifier'])) {
2609 $record->timestart = time() + $config['timestartmodifier'];
2610 }
2611 if (isset($config['timeendmodifier'])) {
2612 $record->timeend = time() + $config['timeendmodifier'];
2613 }
2614 $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
2615
2616 $course1->lastaccess = 0;
2617 $courses = array($course1->id => $course1);
2618
2619 // As viewer1 (same group as post).
2620 $this->setUser($viewer1->id);
2621 $results = array();
2622 forum_print_overview($courses, $results);
2623
2624 if ($hasresult) {
2625 // There should be one entry for course1.
2626 $this->assertCount(1, $results);
2627
2628 // There should be one entry for a forum in course1.
2629 $this->assertCount(1, $results[$course1->id]);
2630 $this->assertArrayHasKey('forum', $results[$course1->id]);
2631 } else {
2632 // There should be no entries for any course.
2633 $this->assertCount(0, $results);
2634 }
2635
6667ebb9
AN
2636 $this->setUser($viewer2->id);
2637 $results = array();
2638 forum_print_overview($courses, $results);
2639
2640 // There should be one entry for course1.
2641 $this->assertCount(0, $results);
2642 }
2643
2644 public function print_overview_timed_provider() {
2645 return array(
2646 'timestart_past' => array(
2647 'discussionconfig' => array(
2648 'timestartmodifier' => -86000,
2649 ),
2650 'hasresult' => true,
2651 ),
2652 'timestart_future' => array(
2653 'discussionconfig' => array(
2654 'timestartmodifier' => 86000,
2655 ),
2656 'hasresult' => false,
2657 ),
2658 'timeend_past' => array(
2659 'discussionconfig' => array(
2660 'timeendmodifier' => -86000,
2661 ),
2662 'hasresult' => false,
2663 ),
2664 'timeend_future' => array(
2665 'discussionconfig' => array(
2666 'timeendmodifier' => 86000,
2667 ),
2668 'hasresult' => true,
2669 ),
2670 );
2671 }
f9621c56
RW
2672
2673 /**
2674 * Test test_pinned_discussion_with_group.
2675 */
2676 public function test_pinned_discussion_with_group() {
2677 global $SESSION;
2678
2679 $this->resetAfterTest();
2680 $course1 = $this->getDataGenerator()->create_course();
2681 $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id));
2682
2683 // Create an author user.
2684 $author = $this->getDataGenerator()->create_user();
2685 $this->getDataGenerator()->enrol_user($author->id, $course1->id);
2686
2687 // Create two viewer users - one in a group, one not.
2688 $viewer1 = $this->getDataGenerator()->create_user((object) array('trackforums' => 1));
2689 $this->getDataGenerator()->enrol_user($viewer1->id, $course1->id);
2690
2691 $viewer2 = $this->getDataGenerator()->create_user((object) array('trackforums' => 1));
2692 $this->getDataGenerator()->enrol_user($viewer2->id, $course1->id);
2693 $this->getDataGenerator()->create_group_member(array('userid' => $viewer2->id, 'groupid' => $group1->id));
2694
2695 $forum1 = $this->getDataGenerator()->create_module('forum', (object) array(
2696 'course' => $course1->id,
2697 'groupmode' => SEPARATEGROUPS,
2698 ));
2699
2700 $coursemodule = get_coursemodule_from_instance('forum', $forum1->id);
2701
2702 $alldiscussions = array();
2703 $group1discussions = array();
2704
2705 // Create 4 discussions in all participants group and group1, where the first
2706 // discussion is pinned in each group.
2707 $allrecord = new stdClass();
2708 $allrecord->course = $course1->id;
2709 $allrecord->userid = $author->id;
2710 $allrecord->forum = $forum1->id;
2711 $allrecord->pinned = FORUM_DISCUSSION_PINNED;
2712
2713 $group1record = new stdClass();
2714 $group1record->course = $course1->id;
2715 $group1record->userid = $author->id;
2716 $group1record->forum = $forum1->id;
2717 $group1record->groupid = $group1->id;
2718 $group1record->pinned = FORUM_DISCUSSION_PINNED;
2719
2720 $alldiscussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($allrecord);
2721 $group1discussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($group1record);
2722
2723 // Create unpinned discussions.
2724 $allrecord->pinned = FORUM_DISCUSSION_UNPINNED;
2725 $group1record->pinned = FORUM_DISCUSSION_UNPINNED;
2726 for ($i = 0; $i < 3; $i++) {
2727 $alldiscussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($allrecord);
2728 $group1discussions[] = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($group1record);
2729 }
2730
2731 // As viewer1 (no group). This user shouldn't see any of group1's discussions
2732 // so their expected discussion order is (where rightmost is highest priority):
2733 // Ad1, ad2, ad3, ad0.
2734 $this->setUser($viewer1->id);
2735
2736 // CHECK 1.
2737 // Take the neighbours of ad3, which should be prev: ad2 and next: ad0.
2738 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[3], $forum1);
2739 // Ad2 check.
2740 $this->assertEquals($alldiscussions[2]->id, $neighbours['prev']->id);
2741 // Ad0 check.
2742 $this->assertEquals($alldiscussions[0]->id, $neighbours['next']->id);
2743
2744 // CHECK 2.
2745 // Take the neighbours of ad0, which should be prev: ad3 and next: null.
2746 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[0], $forum1);
2747 // Ad3 check.
2748 $this->assertEquals($alldiscussions[3]->id, $neighbours['prev']->id);
2749 // Null check.
2750 $this->assertEmpty($neighbours['next']);
2751
2752 // CHECK 3.
2753 // Take the neighbours of ad1, which should be prev: null and next: ad2.
2754 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[1], $forum1);
2755 // Null check.
2756 $this->assertEmpty($neighbours['prev']);
2757 // Ad2 check.
2758 $this->assertEquals($alldiscussions[2]->id, $neighbours['next']->id);
2759
2760 // Temporary hack to workaround for MDL-52656.
2761 $SESSION->currentgroup = null;
2762
2763 // As viewer2 (group1). This user should see all of group1's posts and the all participants group.
2764 // The expected discussion order is (rightmost is highest priority):
2765 // Ad1, gd1, ad2, gd2, ad3, gd3, ad0, gd0.
2766 $this->setUser($viewer2->id);
2767
2768 // CHECK 1.
2769 // Take the neighbours of ad1, which should be prev: null and next: gd1.
2770 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[1], $forum1);
2771 // Null check.
2772 $this->assertEmpty($neighbours['prev']);
2773 // Gd1 check.
2774 $this->assertEquals($group1discussions[1]->id, $neighbours['next']->id);
2775
2776 // CHECK 2.
2777 // Take the neighbours of ad3, which should be prev: gd2 and next: gd3.
2778 $neighbours = forum_get_discussion_neighbours($coursemodule, $alldiscussions[3], $forum1);
2779 // Gd2 check.
2780 $this->assertEquals($group1discussions[2]->id, $neighbours['prev']->id);
2781 // Gd3 check.
2782 $this->assertEquals($group1discussions[3]->id, $neighbours['next']->id);
2783
2784 // CHECK 3.
2785 // Take the neighbours of gd3, which should be prev: ad3 and next: ad0.
2786 $neighbours = forum_get_discussion_neighbours($coursemodule, $group1discussions[3], $forum1);
2787 // Ad3 check.
2788 $this->assertEquals($alldiscussions[3]->id, $neighbours['prev']->id);
2789 // Ad0 check.
2790 $this->assertEquals($alldiscussions[0]->id, $neighbours['next']->id);
2791
2792 // CHECK 4.
2793 // Take the neighbours of gd0, which should be prev: ad0 and next: null.
2794 $neighbours = forum_get_discussion_neighbours($coursemodule, $group1discussions[0], $forum1);
2795 // Ad0 check.
2796 $this->assertEquals($alldiscussions[0]->id, $neighbours['prev']->id);
2797 // Null check.
2798 $this->assertEmpty($neighbours['next']);
2799 }
2800
2801 /**
2802 * Test test_pinned_with_timed_discussions.
2803 */
2804 public function test_pinned_with_timed_discussions() {
2805 global $CFG;
2806
2807 $CFG->forum_enabletimedposts = true;
2808
2809 $this->resetAfterTest();
2810 $course = $this->getDataGenerator()->create_course();
2811
2812 // Create an user.
2813 $user = $this->getDataGenerator()->create_user();
2814 $this->getDataGenerator()->enrol_user($user->id, $course->id);
2815
2816 // Create a forum.
2817 $record = new stdClass();
2818 $record->course = $course->id;
2819 $forum = $this->getDataGenerator()->create_module('forum', (object) array(
2820 'course' => $course->id,
2821 'groupmode' => SEPARATEGROUPS,
2822 ));
2823
2824 $coursemodule = get_coursemodule_from_instance('forum', $forum->id);
2825 $now = time();
2826 $discussions = array();
2827 $discussiongenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
2828
2829 $record = new stdClass();
2830 $record->course = $course->id;
2831 $record->userid = $user->id;
2832 $record->forum = $forum->id;
2833 $record->pinned = FORUM_DISCUSSION_PINNED;
2834 $record->timemodified = $now;
2835
2836 $discussions[] = $discussiongenerator->create_discussion($record);
2837
2838 $record->pinned = FORUM_DISCUSSION_UNPINNED;
2839 $record->timestart = $now + 10;
2840
2841 $discussions[] = $discussiongenerator->create_discussion($record);
2842
2843 $record->timestart = $now;
2844
2845 $discussions[] = $discussiongenerator->create_discussion($record);
2846
2847 // Expected order of discussions:
2848 // D2, d1, d0.
2849 $this->setUser($user->id);
2850
2851 // CHECK 1.
2852 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[2], $forum);
2853 // Null check.
2854 $this->assertEmpty($neighbours['prev']);
2855 // D1 check.
2856 $this->assertEquals($discussions[1]->id, $neighbours['next']->id);
2857
2858 // CHECK 2.
2859 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[1], $forum);
2860 // D2 check.
2861 $this->assertEquals($discussions[2]->id, $neighbours['prev']->id);
2862 // D0 check.
2863 $this->assertEquals($discussions[0]->id, $neighbours['next']->id);
2864
2865 // CHECK 3.
2866 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[0], $forum);
2867 // D2 check.
2868 $this->assertEquals($discussions[1]->id, $neighbours['prev']->id);
2869 // Null check.
2870 $this->assertEmpty($neighbours['next']);
2871 }
2872
2873 /**
2874 * Test test_pinned_timed_discussions_with_timed_discussions.
2875 */
2876 public function test_pinned_timed_discussions_with_timed_discussions() {
2877 global $CFG;
2878
2879 $CFG->forum_enabletimedposts = true;
2880
2881 $this->resetAfterTest();
2882 $course = $this->getDataGenerator()->create_course();
2883
2884 // Create an user.
2885 $user = $this->getDataGenerator()->create_user();
2886 $this->getDataGenerator()->enrol_user($user->id, $course->id);
2887
2888 // Create a forum.
2889 $record = new stdClass();
2890 $record->course = $course->id;
2891 $forum = $this->getDataGenerator()->create_module('forum', (object) array(
2892 'course' => $course->id,
2893 'groupmode' => SEPARATEGROUPS,
2894 ));
2895
2896 $coursemodule = get_coursemodule_from_instance('forum', $forum->id);
2897 $now = time();
2898 $discussions = array();
2899 $discussiongenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
2900
2901 $record = new stdClass();
2902 $record->course = $course->id;
2903 $record->userid = $user->id;
2904 $record->forum = $forum->id;
2905 $record->pinned = FORUM_DISCUSSION_PINNED;
2906 $record->timemodified = $now;
2907 $record->timestart = $now + 10;
2908
2909 $discussions[] = $discussiongenerator->create_discussion($record);
2910
2911 $record->pinned = FORUM_DISCUSSION_UNPINNED;
2912
2913 $discussions[] = $discussiongenerator->create_discussion($record);
2914
2915 $record->timestart = $now;
2916
2917 $discussions[] = $discussiongenerator->create_discussion($record);
2918
2919 $record->pinned = FORUM_DISCUSSION_PINNED;
2920
2921 $discussions[] = $discussiongenerator->create_discussion($record);
2922
2923 // Expected order of discussions:
2924 // D2, d1, d3, d0.
2925 $this->setUser($user->id);
2926
2927 // CHECK 1.
2928 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[2], $forum);
2929 // Null check.
2930 $this->assertEmpty($neighbours['prev']);
2931 // D1 check.
2932 $this->assertEquals($discussions[1]->id, $neighbours['next']->id);
2933
2934 // CHECK 2.
2935 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[1], $forum);
2936 // D2 check.
2937 $this->assertEquals($discussions[2]->id, $neighbours['prev']->id);
2938 // D3 check.
2939 $this->assertEquals($discussions[3]->id, $neighbours['next']->id);
2940
2941 // CHECK 3.
2942 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[3], $forum);
2943 // D1 check.
2944 $this->assertEquals($discussions[1]->id, $neighbours['prev']->id);
2945 // D0 check.
2946 $this->assertEquals($discussions[0]->id, $neighbours['next']->id);
2947
2948 // CHECK 4.
2949 $neighbours = forum_get_discussion_neighbours($coursemodule, $discussions[0], $forum);
2950 // D3 check.
2951 $this->assertEquals($discussions[3]->id, $neighbours['prev']->id);
2952 // Null check.
2953 $this->assertEmpty($neighbours['next']);
2954 }
d6ffb027
AN
2955
2956 /**
2957 * @dataProvider forum_get_unmailed_posts_provider
2958 */
2959 public function test_forum_get_unmailed_posts($discussiondata, $enabletimedposts, $expectedcount, $expectedreplycount) {
2960 global $CFG, $DB;
2961
2962 $this->resetAfterTest();
2963
2964 // Configure timed posts.
2965 $CFG->forum_enabletimedposts = $enabletimedposts;
2966
2967 $course = $this->getDataGenerator()->create_course();
2968 $forum = $this->getDataGenerator()->create_module('forum', ['course' => $course->id]);
2969 $user = $this->getDataGenerator()->create_user();
2970 $forumgen = $this->getDataGenerator()->get_plugin_generator('mod_forum');
2971
985dca60
AN
2972 // Keep track of the start time of the test. Do not use time() after this point to prevent random failures.
2973 $time = time();
2974
d6ffb027
AN
2975 $record = new stdClass();
2976 $record->course = $course->id;
2977 $record->userid = $user->id;
2978 $record->forum = $forum->id;
2979 if (isset($discussiondata['timecreated'])) {
985dca60 2980 $record->timemodified = $time + $discussiondata['timecreated'];
d6ffb027
AN
2981 }
2982 if (isset($discussiondata['timestart'])) {
985dca60 2983 $record->timestart = $time + $discussiondata['timestart'];
d6ffb027
AN
2984 }
2985 if (isset($discussiondata['timeend'])) {
985dca60 2986 $record->timeend = $time + $discussiondata['timeend'];
d6ffb027
AN
2987 }
2988 if (isset($discussiondata['mailed'])) {
2989 $record->mailed = $discussiondata['mailed'];
2990 }
2991
2992 $discussion = $forumgen->create_discussion($record);
2993
2994 // Fetch the unmailed posts.
985dca60 2995 $timenow = $time;
d6ffb027
AN
2996 $endtime = $timenow - $CFG->maxeditingtime;
2997 $starttime = $endtime - 2 * DAYSECS;
2998
2999 $unmailed = forum_get_unmailed_posts($starttime, $endtime, $timenow);
3000 $this->assertCount($expectedcount, $unmailed);
3001
3002 // Add a reply just outside the maxeditingtime.
3003 $replyto = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
3004 $reply = new stdClass();
3005 $reply->userid = $user->id;
3006 $reply->discussion = $discussion->id;
3007 $reply->parent = $replyto->id;
3008 $reply->created = max($replyto->created, $endtime - 1);
985dca60 3009 $forumgen->create_post($reply);
d6ffb027
AN
3010
3011 $unmailed = forum_get_unmailed_posts($starttime, $endtime, $timenow);
3012 $this->assertCount($expectedreplycount, $unmailed);
3013 }
3014
af0fc6a2
JP
3015 /**
3016 * Test for forum_is_author_hidden.
3017 */
3018 public function test_forum_is_author_hidden() {
3019 // First post, different forum type.
3020 $post = (object) ['parent' => 0];
3021 $forum = (object) ['type' => 'standard'];
3022 $this->assertFalse(forum_is_author_hidden($post, $forum));
3023
3024 // Child post, different forum type.
3025 $post->parent = 1;
3026 $this->assertFalse(forum_is_author_hidden($post, $forum));
3027
3028 // First post, single simple discussion forum type.
3029 $post->parent = 0;
3030 $forum->type = 'single';
3031 $this->assertTrue(forum_is_author_hidden($post, $forum));
3032
3033 // Child post, single simple discussion forum type.
3034 $post->parent = 1;
3035 $this->assertFalse(forum_is_author_hidden($post, $forum));
3036
3037 // Incorrect parameters: $post.
52f3e060
RT
3038 $this->expectException('coding_exception');
3039 $this->expectExceptionMessage('$post->parent must be set.');
af0fc6a2
JP
3040 unset($post->parent);
3041 forum_is_author_hidden($post, $forum);
3042
3043 // Incorrect parameters: $forum.
52f3e060
RT
3044 $this->expectException('coding_exception');
3045 $this->expectExceptionMessage('$forum->type must be set.');
af0fc6a2
JP
3046 unset($forum->type);
3047 forum_is_author_hidden($post, $forum);
3048 }
3049
d6ffb027
AN
3050 public function forum_get_unmailed_posts_provider() {
3051 return [
3052 'Untimed discussion; Single post; maxeditingtime not expired' => [
3053 'discussion' => [
3054 ],
3055 'timedposts' => false,
3056 'postcount' => 0,
3057 'replycount' => 0,
3058 ],
3059 'Untimed discussion; Single post; maxeditingtime expired' => [
3060 'discussion' => [
3061 'timecreated' => - DAYSECS,
3062 ],
3063 'timedposts' => false,
3064 'postcount' => 1,
3065 'replycount' => 2,
3066 ],
3067 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime not expired' => [
3068 'discussion' => [
3069 'timecreated' => - WEEKSECS,
3070 'timestart' => 0,
3071 ],
3072 'timedposts' => true,
3073 'postcount' => 0,
3074 'replycount' => 0,
3075 ],
3076 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired' => [
3077 'discussion' => [
3078 'timecreated' => - WEEKSECS,
3079 'timestart' => - DAYSECS,
3080 ],
3081 'timedposts' => true,
3082 'postcount' => 1,
3083 'replycount' => 2,
3084 ],
3085 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend not reached' => [
3086 'discussion' => [
3087 'timecreated' => - WEEKSECS,
3088 'timestart' => - DAYSECS,
3089 'timeend' => + DAYSECS
3090 ],
3091 'timedposts' => true,
3092 'postcount' => 1,
3093 'replycount' => 2,
3094 ],
3095 'Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend passed' => [
3096 'discussion' => [
3097 'timecreated' => - WEEKSECS,
3098 'timestart' => - DAYSECS,
3099 'timeend' => - HOURSECS,
3100 ],
3101 'timedposts' => true,
3102 'postcount' => 0,
3103 'replycount' => 0,
3104 ],
3105 'Timed discussion; Single post; Posted 1 week ago; timeend not reached' => [
3106 'discussion' => [
3107 'timecreated' => - WEEKSECS,
3108 'timeend' => + DAYSECS
3109 ],
3110 'timedposts' => true,
3111 'postcount' => 0,
3112 'replycount' => 1,
3113 ],
3114 'Timed discussion; Single post; Posted 1 week ago; timeend passed' => [
3115 'discussion' => [
3116 'timecreated' => - WEEKSECS,
3117 'timeend' => - DAYSECS,
3118 ],
3119 'timedposts' => true,
3120 'postcount' => 0,
3121 'replycount' => 0,
3122 ],
3123
3124 'Previously mailed; Untimed discussion; Single post; maxeditingtime not expired' => [
3125 'discussion' => [
3126 'mailed' => 1,
3127 ],
3128 'timedposts' => false,
3129 'postcount' => 0,
3130 'replycount' => 0,
3131 ],
3132
3133 'Previously mailed; Untimed discussion; Single post; maxeditingtime expired' => [
3134 'discussion' => [
3135 'timecreated' => - DAYSECS,
3136 'mailed' => 1,
3137 ],
3138 'timedposts' => false,
3139 'postcount' => 0,
3140 'replycount' => 1,
3141 ],
3142 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime not expired' => [
3143 'discussion' => [
3144 'timecreated' => - WEEKSECS,
3145 'timestart' => 0,
3146 'mailed' => 1,
3147 ],
3148 'timedposts' => true,
3149 'postcount' => 0,
3150 'replycount' => 0,
3151 ],
3152 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired' => [
3153 'discussion' => [
3154 'timecreated' => - WEEKSECS,
3155 'timestart' => - DAYSECS,
3156 'mailed' => 1,
3157 ],
3158 'timedposts' => true,
3159 'postcount' => 0,
3160 'replycount' => 1,
3161 ],
3162 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend not reached' => [
3163 'discussion' => [
3164 'timecreated' => - WEEKSECS,
3165 'timestart' => - DAYSECS,
3166 'timeend' => + DAYSECS,
3167 'mailed' => 1,
3168 ],
3169 'timedposts' => true,
3170 'postcount' => 0,
3171 'replycount' => 1,
3172 ],
3173 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timestart maxeditingtime expired; timeend passed' => [
3174 'discussion' => [
3175 'timecreated' => - WEEKSECS,
3176 'timestart' => - DAYSECS,
3177 'timeend' => - HOURSECS,
3178 'mailed' => 1,
3179 ],
3180 'timedposts' => true,
3181 'postcount' => 0,
3182 'replycount' => 0,
3183 ],
3184 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timeend not reached' => [
3185 'discussion' => [
3186 'timecreated' => - WEEKSECS,
3187 'timeend' => + DAYSECS,
3188 'mailed' => 1,
3189 ],
3190 'timedposts' => true,
3191 'postcount' => 0,
3192 'replycount' => 1,
3193 ],
3194 'Previously mailed; Timed discussion; Single post; Posted 1 week ago; timeend passed' => [
3195 'discussion' => [
3196 'timecreated' => - WEEKSECS,
3197 'timeend' => - DAYSECS,
3198 'mailed' => 1,
3199 ],
3200 'timedposts' => true,
3201 'postcount' => 0,
3202 'replycount' => 0,
3203 ],
3204 ];
3205 }
0f3bbfd4
AN
3206
3207 /**
3208 * Test the forum_discussion_is_locked function.
3209 *
3210 * @dataProvider forum_discussion_is_locked_provider
3211 * @param stdClass $forum
3212 * @param stdClass $discussion
3213 * @param bool $expect
3214 */
3215 public function test_forum_discussion_is_locked($forum, $discussion, $expect) {
3216 $this->assertEquals($expect, forum_discussion_is_locked($forum, $discussion));
3217 }
3218
3219 /**
3220 * Dataprovider for forum_discussion_is_locked tests.
3221 *
3222 * @return array
3223 */
3224 public function forum_discussion_is_locked_provider() {
3225 return [
3226 'Unlocked: lockdiscussionafter is unset' => [
3227 (object) [],
3228 (object) [],
3229 false
3230 ],
3231 'Unlocked: lockdiscussionafter is false' => [
3232 (object) ['lockdiscussionafter' => false],
3233 (object) [],
3234 false
3235 ],
3236 'Unlocked: lockdiscussionafter is null' => [
3237 (object) ['lockdiscussionafter' => null],
3238 (object) [],
3239 false
3240 ],
3241 'Unlocked: lockdiscussionafter is set; forum is of type single; post is recent' => [
3242 (object) ['lockdiscussionafter' => DAYSECS, 'type' => 'single'],
3243 (object) ['timemodified' => time()],
3244 false
3245 ],
3246 'Unlocked: lockdiscussionafter is set; forum is of type single; post is old' => [
3247 (object) ['lockdiscussionafter' => MINSECS, 'type' => 'single'],
3248 (object) ['timemodified' => time() - DAYSECS],
3249 false
3250 ],
3251 'Unlocked: lockdiscussionafter is set; forum is of type eachuser; post is recent' => [
3252 (object) ['lockdiscussionafter' => DAYSECS, 'type' => 'eachuser'],
3253 (object) ['timemodified' => time()],
3254 false
3255 ],
3256 'Locked: lockdiscussionafter is set; forum is of type eachuser; post is old' => [
3257 (object) ['lockdiscussionafter' => MINSECS, 'type' => 'eachuser'],
3258 (object) ['timemodified' => time() - DAYSECS],
3259 true
3260 ],
3261 ];
3262 }
62b3b997 3263}