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 discussion_list vault tests.
19 *
20 * @package    mod_forum
21 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
22 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die();
26
27global $CFG;
28
29require_once($CFG->dirroot . '/mod/forum/externallib.php');
30require_once(__DIR__ . '/generator_trait.php');
31
32/**
33 * The discussion_list vault tests.
34 *
35 * @package    mod_forum
36 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
37 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 */
39class mod_forum_vaults_discussion_list_testcase extends advanced_testcase {
40    // Make use of the test generator trait.
41    use mod_forum_tests_generator_trait;
42
43    /** @var \mod_forum\local\vaults\discussion_list */
44    private $vault;
45
46    /**
47     * Set up function for tests.
48     */
49    public function setUp() {
50        $vaultfactory = \mod_forum\local\container::get_vault_factory();
51        $this->vault = $vaultfactory->get_discussions_in_forum_vault();
52    }
53
54    /**
55     * Test get_from_id.
56     */
57    public function test_get_from_id() {
58        $this->resetAfterTest();
59
60        $datagenerator = $this->getDataGenerator();
61        $vault = $this->vault;
62        $user = $datagenerator->create_user();
63        $course = $datagenerator->create_course();
64        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
65        [$discussion, $post] = $this->helper_post_to_forum($forum, $user);
66
67        $discussionlist = $vault->get_from_id($discussion->id);
68
69        $this->assertEquals($discussion->id, $discussionlist->get_discussion()->get_id());
70        $this->assertEquals($post->id, $discussionlist->get_first_post()->get_id());
71        $this->assertEquals($user->id, $discussionlist->get_first_post_author()->get_id());
72        $this->assertEquals($user->id, $discussionlist->get_latest_post_author()->get_id());
73    }
74
75    /**
76     * Test get_from_forum_id.
77     */
78    public function test_get_from_forum_id() {
79        $this->resetAfterTest();
80
81        $datagenerator = $this->getDataGenerator();
82        $vault = $this->vault;
83        $user = $datagenerator->create_user();
84        self::setUser($user);
85        $course = $datagenerator->create_course();
86        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
87
88        $this->getDataGenerator()->enrol_user($user->id, $course->id, null, 'manual');
89
90        $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, $user->id, null,
91            0, 0));
92
93        $now = time();
94        [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]);
95        [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]);
96        [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]);
97        [$discussion3, $post4] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 8, 'timemodified' => 4]);
98
99        // By default orders the discussions by last post.
100        $summaries = array_values($vault->get_from_forum_id($forum->id, false, null, null,
101            0, 0));
102        $this->assertCount(3, $summaries);
103        $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id());
104        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
105        $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id());
106
107        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null,
108            0, 0));
109        $this->assertCount(4, $summaries);
110        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
111        $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id());
112        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
113        $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id());
114
115        $summaries = array_values($vault->get_from_forum_id($forum->id, false, $user->id, null,
116            0, 0));
117        $this->assertCount(4, $summaries);
118        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
119        $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id());
120        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
121        $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id());
122
123        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null,
124            1, 0));
125        $this->assertCount(1, $summaries);
126        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
127
128        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null,
129            1, 1));
130        $this->assertCount(1, $summaries);
131        $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id());
132
133        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null,
134            1, 2));
135        $this->assertCount(1, $summaries);
136        $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id());
137
138        // Create 2 replies for $post1.
139        $this->helper_reply_to_post($post1, $user);
140        $this->helper_reply_to_post($post1, $user);
141        // Create 3 replies for $post2.
142        $this->helper_reply_to_post($post2, $user);
143        $this->helper_reply_to_post($post2, $user);
144        $this->helper_reply_to_post($post2, $user);
145        // Create 1 reply for $post3.
146        $this->helper_reply_to_post($post3, $user);
147
148        // Sort discussions by last post DESC.
149        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
150            $vault::SORTORDER_LASTPOST_DESC, 0, 0));
151        $this->assertCount(4, $summaries);
152        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
153        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
154        $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id());
155        $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id());
156
157        // Sort discussions by last post ASC.
158        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
159            $vault::SORTORDER_LASTPOST_ASC, 0, 0));
160        $this->assertCount(4, $summaries);
161        $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id());
162        $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id());
163        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
164        $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id());
165
166        // Sort discussions by replies DESC.
167        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
168            $vault::SORTORDER_REPLIES_DESC, 0, 0));
169        $this->assertCount(4, $summaries);
170        $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id());
171        $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id());
172        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
173        $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id());
174
175        // Sort discussions by replies ASC.
176        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
177            $vault::SORTORDER_REPLIES_ASC, 0, 0));
178        $this->assertCount(4, $summaries);
179        $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id());
180        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
181        $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id());
182        $this->assertEquals($discussion2->id, $summaries[3]->get_discussion()->get_id());
183
184        // Sort discussions by discussion created DESC.
185        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
186            $vault::SORTORDER_CREATED_DESC, 0, 0));
187        $this->assertCount(4, $summaries);
188        $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id());
189        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
190        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
191        $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id());
192
193        // Sort discussions by discussion created ASC.
194        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
195            $vault::SORTORDER_CREATED_ASC, 0, 0));
196        $this->assertCount(4, $summaries);
197        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
198        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
199        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
200        $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id());
201
202        // Sort discussions when there is a pinned discussion.
203        $this->pin_discussion($discussion1);
204        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
205            $vault::SORTORDER_LASTPOST_ASC, 0, 0));
206        $this->assertCount(4, $summaries);
207        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
208        $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id());
209        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
210        $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id());
211
212        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
213            $vault::SORTORDER_LASTPOST_DESC, 0, 0));
214        $this->assertCount(4, $summaries);
215        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
216        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
217        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
218        $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id());
219
220        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
221            $vault::SORTORDER_REPLIES_DESC, 0, 0));
222        $this->assertCount(4, $summaries);
223        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
224        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
225        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
226        $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id());
227
228        // Sort discussions where there is a pinned discussion and several starred discussions.
229        $this->star_discussion($discussion3, 1);
230        $this->star_discussion($hiddendiscussion, 1);
231
232        $summaries = array_values($vault->get_from_forum_id($forum->id, true, $user->id,
233            $vault::SORTORDER_REPLIES_DESC, 0, 0));
234        $this->assertCount(4, $summaries);
235        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
236        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
237        $this->assertEquals($discussion3->id, $summaries[2]->get_discussion()->get_id());
238        $this->assertEquals($discussion2->id, $summaries[3]->get_discussion()->get_id());
239
240        $summaries = array_values($vault->get_from_forum_id($forum->id, true, $user->id,
241            $vault::SORTORDER_REPLIES_ASC, 0, 0));
242        $this->assertCount(4, $summaries);
243        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
244        $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id());
245        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
246        $this->assertEquals($discussion2->id, $summaries[3]->get_discussion()->get_id());
247    }
248
249    /**
250     * Test get_from_forum_id_and_group_id.
251     */
252    public function test_get_from_forum_id_and_group_id() {
253        $this->resetAfterTest();
254
255        $datagenerator = $this->getDataGenerator();
256        $vault = $this->vault;
257        $user = $datagenerator->create_user();
258        self::setUser($user);
259        $course = $datagenerator->create_course();
260        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
261        $this->getDataGenerator()->enrol_user($user->id, $course->id, null, 'manual');
262
263        $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, true,
264            null, 0, 0, $user));
265
266        $now = time();
267        [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]);
268        [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]);
269        [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]);
270        [$groupdiscussion1, $post4] = $this->helper_post_to_forum(
271            $forum,
272            $user,
273            ['timestart' => $now - 8, 'timemodified' => 4, 'groupid' => 1]
274        );
275        [$groupdiscussion2, $post5] = $this->helper_post_to_forum(
276            $forum,
277            $user,
278            ['timestart' => $now - 7, 'timemodified' => 5, 'groupid' => 2]
279        );
280        [$hiddengroupdiscussion, $post6] = $this->helper_post_to_forum(
281            $forum,
282            $user,
283            ['timestart' => $now + 11, 'timemodified' => 6, 'groupid' => 3]
284        );
285
286        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
287            null, null, 0, 0));
288        $this->assertCount(6, $summaries);
289        $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id());
290        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
291        $this->assertEquals($groupdiscussion2->id, $summaries[2]->get_discussion()->get_id());
292        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
293        $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id());
294        $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id());
295
296        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false,
297            $user->id, null, 0, 0));
298        $this->assertCount(6, $summaries);
299        $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id());
300        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
301        $this->assertEquals($groupdiscussion2->id, $summaries[2]->get_discussion()->get_id());
302        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
303        $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id());
304        $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id());
305
306        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
307            null, null, 1, 0));
308        $this->assertCount(1, $summaries);
309        $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id());
310
311        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
312            null, null, 1, 1));
313        $this->assertCount(1, $summaries);
314        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
315
316        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
317            null, null, 1, 2));
318        $this->assertCount(1, $summaries);
319        $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id());
320
321        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false,
322            null, null, 0, 0));
323        $this->assertCount(4, $summaries);
324        $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id());
325        $this->assertEquals($groupdiscussion1->id, $summaries[1]->get_discussion()->get_id());
326        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
327        $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id());
328
329        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [], true,
330            null, null, 0, 0));
331        $this->assertCount(3, $summaries);
332        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
333        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
334        $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id());
335
336        // Add 4 replies to $post1.
337        $this->helper_reply_to_post($post1, $user);
338        $this->helper_reply_to_post($post1, $user);
339        $this->helper_reply_to_post($post1, $user);
340        $this->helper_reply_to_post($post1, $user);
341        // Add 5 replies to $post2.
342        $this->helper_reply_to_post($post2, $user);
343        $this->helper_reply_to_post($post2, $user);
344        $this->helper_reply_to_post($post2, $user);
345        $this->helper_reply_to_post($post2, $user);
346        $this->helper_reply_to_post($post2, $user);
347        // Add 3 replies to $post3.
348        $this->helper_reply_to_post($post3, $user);
349        $this->helper_reply_to_post($post3, $user);
350        $this->helper_reply_to_post($post3, $user);
351        // Add 2 replies to $post4.
352        $this->helper_reply_to_post($post4, $user);
353        $this->helper_reply_to_post($post4, $user);
354        // Add 1 reply to $post5.
355        $this->helper_reply_to_post($post5, $user);
356
357        // Sort discussions by last post DESC.
358        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
359            $user->id, $vault::SORTORDER_LASTPOST_DESC, 0, 0));
360        $this->assertCount(6, $summaries);
361        $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id());
362        $this->assertEquals($groupdiscussion1->id, $summaries[1]->get_discussion()->get_id());
363        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
364        $this->assertEquals($hiddengroupdiscussion->id, $summaries[3]->get_discussion()->get_id());
365        $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id());
366        $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id());
367
368        // Sort discussions by last post ASC.
369        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
370            $user->id, $vault::SORTORDER_LASTPOST_ASC, 0, 0));
371        $this->assertCount(6, $summaries);
372        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
373        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
374        $this->assertEquals($hiddengroupdiscussion->id, $summaries[2]->get_discussion()->get_id());
375        $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id());
376        $this->assertEquals($groupdiscussion1->id, $summaries[4]->get_discussion()->get_id());
377        $this->assertEquals($groupdiscussion2->id, $summaries[5]->get_discussion()->get_id());
378
379        // Sort discussions by replies DESC.
380        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
381            $user->id, $vault::SORTORDER_REPLIES_DESC, 0, 0));
382        $this->assertCount(6, $summaries);
383        $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id());
384        $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id());
385        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
386        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
387        $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id());
388        $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id());
389
390        // Sort discussions by replies ASC.
391        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
392            $user->id, $vault::SORTORDER_REPLIES_ASC, 0, 0));
393        $this->assertCount(6, $summaries);
394        $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id());
395        $this->assertEquals($groupdiscussion2->id, $summaries[1]->get_discussion()->get_id());
396        $this->assertEquals($groupdiscussion1->id, $summaries[2]->get_discussion()->get_id());
397        $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id());
398        $this->assertEquals($discussion1->id, $summaries[4]->get_discussion()->get_id());
399        $this->assertEquals($discussion2->id, $summaries[5]->get_discussion()->get_id());
400
401        // Sort discussions by discussion created DESC.
402        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
403            $user->id, $vault::SORTORDER_CREATED_DESC, 0, 0));
404        $this->assertCount(6, $summaries);
405        $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id());
406        $this->assertEquals($groupdiscussion2->id, $summaries[1]->get_discussion()->get_id());
407        $this->assertEquals($groupdiscussion1->id, $summaries[2]->get_discussion()->get_id());
408        $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id());
409        $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id());
410        $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id());
411
412        // Sort discussions by discussion created ASC.
413        $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true,
414            $user->id, $vault::SORTORDER_CREATED_ASC, 0, 0));
415        $this->assertCount(6, $summaries);
416        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
417        $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id());
418        $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id());
419        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
420        $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id());
421        $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id());
422
423        // Sort discussions when there is a pinned discussion.
424        $this->pin_discussion($discussion1);
425        $this->pin_discussion($hiddendiscussion);
426
427        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
428            $vault::SORTORDER_LASTPOST_DESC, 0, 0));
429        $this->assertCount(6, $summaries);
430        $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id());
431        $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id());
432        $this->assertEquals($groupdiscussion2->id, $summaries[2]->get_discussion()->get_id());
433        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
434        $this->assertEquals($hiddengroupdiscussion->id, $summaries[4]->get_discussion()->get_id());
435        $this->assertEquals($discussion2->id, $summaries[5]->get_discussion()->get_id());
436
437        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
438            $vault::SORTORDER_LASTPOST_ASC, 0, 0));
439        $this->assertCount(6, $summaries);
440        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
441        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
442        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
443        $this->assertEquals($hiddengroupdiscussion->id, $summaries[3]->get_discussion()->get_id());
444        $this->assertEquals($groupdiscussion1->id, $summaries[4]->get_discussion()->get_id());
445        $this->assertEquals($groupdiscussion2->id, $summaries[5]->get_discussion()->get_id());
446
447        $summaries = array_values($vault->get_from_forum_id($forum->id, true, null,
448            $vault::SORTORDER_REPLIES_DESC, 0, 0));
449        $this->assertCount(6, $summaries);
450        $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id());
451        $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id());
452        $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id());
453        $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id());
454        $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id());
455        $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id());
456    }
457
458    /**
459     * Test get_total_discussion_count_from_forum_id.
460     */
461    public function test_get_total_discussion_count_from_forum_id() {
462        $this->resetAfterTest();
463
464        $datagenerator = $this->getDataGenerator();
465        $vault = $this->vault;
466        $user = $datagenerator->create_user();
467        $course = $datagenerator->create_course();
468        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
469
470        $this->assertEquals(0, $vault->get_total_discussion_count_from_forum_id($forum->id, true,
471            null));
472
473        $now = time();
474        [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]);
475        [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]);
476        [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]);
477
478        $this->assertEquals(2, $vault->get_total_discussion_count_from_forum_id($forum->id, false,
479            null));
480        $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, true,
481            null));
482        $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, false,
483            $user->id));
484    }
485
486    /**
487     * Test get_total_discussion_count_from_forum_id_and_group_id.
488     */
489    public function test_get_total_discussion_count_from_forum_id_and_group_id() {
490        $this->resetAfterTest();
491
492        $datagenerator = $this->getDataGenerator();
493        $vault = $this->vault;
494        $user = $datagenerator->create_user();
495        self::setUser($user);
496        $course = $datagenerator->create_course();
497        $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
498
499        $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, null,
500            null, 0, 0));
501
502        $now = time();
503        [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]);
504        [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]);
505        [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]);
506        [$groupdiscussion1, $post4] = $this->helper_post_to_forum(
507            $forum,
508            $user,
509            ['timestart' => $now - 8, 'timemodified' => 4, 'groupid' => 1]
510        );
511        [$groupdiscussion2, $post5] = $this->helper_post_to_forum(
512            $forum,
513            $user,
514            ['timestart' => $now - 7, 'timemodified' => 5, 'groupid' => 2]
515        );
516        [$hiddengroupdiscussion, $post6] = $this->helper_post_to_forum(
517            $forum,
518            $user,
519            ['timestart' => $now + 11, 'timemodified' => 6, 'groupid' => 3]
520        );
521
522        $this->assertEquals(6, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3],
523            true, null));
524        $this->assertEquals(6, $vault->get_total_discussion_count_from_forum_id_and_group_id(
525            $forum->id,
526            [1, 2, 3],
527            false,
528            $user->id
529        ));
530        $this->assertEquals(4, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3],
531            false, null));
532        $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [],
533            true, null));
534    }
535
536    /**
537     * Pin a duscussion.
538     *
539     * @param stdClass $discussion
540     */
541    private function pin_discussion(stdClass $discussion) {
542        global $DB;
543
544        $DB->update_record('forum_discussions',
545            (object) array('id' => $discussion->id, 'pinned' => FORUM_DISCUSSION_PINNED));
546    }
547
548    /**
549     * Star a duscussion.
550     *
551     * @param stdClass $discussion
552     * @param bool     $targetstate The new starred state of the discussion (0 => unstar, 1 => star)
553     */
554    private function star_discussion(stdClass $discussion, bool $targetstate) {
555        mod_forum_external::toggle_favourite_state($discussion->id, $targetstate);
556    }
557}
558