MDL-64820 forum: fix up issues from review
[moodle.git] / mod / forum / tests / vaults_post_test.php
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/>.
17 /**
18  * The post 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  */
25 defined('MOODLE_INTERNAL') || die();
27 require_once(__DIR__ . '/generator_trait.php');
29 /**
30  * The post vault tests.
31  *
32  * @package    mod_forum
33  * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
34  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35  * @coversDefaultClass \mod_forum\local\vaults\post
36  */
37 class mod_forum_vaults_post_testcase extends advanced_testcase {
38     // Make use of the test generator trait.
39     use mod_forum_tests_generator_trait;
41     /** @var \mod_forum\local\vaults\post */
42     private $vault;
44     /**
45      * Set up function for tests.
46      */
47     public function setUp() {
48         $vaultfactory = \mod_forum\local\container::get_vault_factory();
49         $this->vault = $vaultfactory->get_post_vault();
50     }
52     /**
53      * Teardown for all tests.
54      */
55     public function tearDown() {
56         unset($this->vault);
57     }
59     /**
60      * Test get_from_id.
61      */
62     public function test_get_from_id() {
63         $this->resetAfterTest();
65         $datagenerator = $this->getDataGenerator();
66         $user = $datagenerator->create_user();
67         $course = $datagenerator->create_course();
68         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
69         [$discussion, $post] = $this->helper_post_to_forum($forum, $user);
71         $postentity = $this->vault->get_from_id($post->id);
73         $this->assertEquals($post->id, $postentity->get_id());
74     }
76     /**
77      * Test get_from_discussion_id.
78      *
79      * @covers ::get_from_discussion_id
80      * @covers ::<!public>
81      */
82     public function test_get_from_discussion_id() {
83         $this->resetAfterTest();
85         $datagenerator = $this->getDataGenerator();
86         $user = $datagenerator->create_user();
87         $course = $datagenerator->create_course();
88         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
89         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
90         $post2 = $this->helper_reply_to_post($post1, $user);
91         $post3 = $this->helper_reply_to_post($post1, $user);
92         [$discussion2, $post4] = $this->helper_post_to_forum($forum, $user);
94         $entities = array_values($this->vault->get_from_discussion_id($discussion1->id));
96         $this->assertCount(3, $entities);
97         $this->assertEquals($post1->id, $entities[0]->get_id());
98         $this->assertEquals($post2->id, $entities[1]->get_id());
99         $this->assertEquals($post3->id, $entities[2]->get_id());
101         $entities = array_values($this->vault->get_from_discussion_id($discussion1->id + 1000));
102         $this->assertCount(0, $entities);
103     }
105     /**
106      * Test get_from_discussion_ids when no discussion ids were provided.
107      *
108      * @covers ::get_from_discussion_ids
109      */
110     public function test_get_from_discussion_ids_empty() {
111         $this->resetAfterTest();
113         $datagenerator = $this->getDataGenerator();
114         $user = $datagenerator->create_user();
115         $course = $datagenerator->create_course();
116         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
118         $this->assertEquals([], $this->vault->get_from_discussion_ids([]));
119     }
121     /**
122      * Test get_from_discussion_ids.
123      *
124      * @covers ::get_from_discussion_ids
125      * @covers ::<!public>
126      */
127     public function test_get_from_discussion_ids() {
128         $this->resetAfterTest();
130         $datagenerator = $this->getDataGenerator();
131         $user = $datagenerator->create_user();
132         $course = $datagenerator->create_course();
133         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
134         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
135         $post2 = $this->helper_reply_to_post($post1, $user);
136         $post3 = $this->helper_reply_to_post($post1, $user);
137         [$discussion2, $post4] = $this->helper_post_to_forum($forum, $user);
139         $entities = array_values($this->vault->get_from_discussion_ids([$discussion1->id]));
140         usort($entities, function($a, $b) {
141             return $a <=> $b;
142         });
143         $this->assertCount(3, $entities);
144         $this->assertEquals($post1->id, $entities[0]->get_id());
145         $this->assertEquals($post2->id, $entities[1]->get_id());
146         $this->assertEquals($post3->id, $entities[2]->get_id());
148         $entities = array_values($this->vault->get_from_discussion_ids([$discussion1->id, $discussion2->id]));
149         usort($entities, function($a, $b) {
150             return $a <=> $b;
151         });
152         $this->assertCount(4, $entities);
153         $this->assertEquals($post1->id, $entities[0]->get_id());
154         $this->assertEquals($post2->id, $entities[1]->get_id());
155         $this->assertEquals($post3->id, $entities[2]->get_id());
156         $this->assertEquals($post4->id, $entities[3]->get_id());
157     }
159     /**
160      * Test get_replies_to_post.
161      *
162      * @covers ::get_replies_to_post
163      * @covers ::<!public>
164      */
165     public function test_get_replies_to_post() {
166         $this->resetAfterTest();
168         $datagenerator = $this->getDataGenerator();
169         $forumgenerator = $datagenerator->get_plugin_generator('mod_forum');
170         $user = $datagenerator->create_user();
171         $course = $datagenerator->create_course();
172         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
173         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
174         // Create a post with the same created time as the parent post to ensure
175         // we've covered every possible scenario.
176         $post2 = $forumgenerator->create_post((object) [
177             'discussion' => $post1->discussion,
178             'parent' => $post1->id,
179             'userid' => $user->id,
180             'mailnow' => 1,
181             'subject' => 'Some subject',
182             'created' => $post1->created
183         ]);
184         $post3 = $this->helper_reply_to_post($post1, $user);
185         $post4 = $this->helper_reply_to_post($post2, $user);
186         [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user);
188         $entityfactory = \mod_forum\local\container::get_entity_factory();
189         $post1 = $entityfactory->get_post_from_stdclass($post1);
190         $post2 = $entityfactory->get_post_from_stdclass($post2);
191         $post3 = $entityfactory->get_post_from_stdclass($post3);
192         $post4 = $entityfactory->get_post_from_stdclass($post4);
194         $entities = $this->vault->get_replies_to_post($post1);
195         $this->assertCount(3, $entities);
196         $this->assertEquals($post2->get_id(), $entities[0]->get_id());
197         $this->assertEquals($post3->get_id(), $entities[1]->get_id());
198         $this->assertEquals($post4->get_id(), $entities[2]->get_id());
200         $entities = $this->vault->get_replies_to_post($post2);
201         $this->assertCount(1, $entities);
202         $this->assertEquals($post4->get_id(), $entities[0]->get_id());
204         $entities = $this->vault->get_replies_to_post($post3);
205         $this->assertCount(0, $entities);
206     }
208     /**
209      * Test get_reply_count_for_discussion_ids when no discussion ids were provided.
210      *
211      * @covers ::get_reply_count_for_discussion_ids
212      */
213     public function test_get_reply_count_for_discussion_ids_empty() {
214         $this->resetAfterTest();
216         $datagenerator = $this->getDataGenerator();
217         $user = $datagenerator->create_user();
218         $course = $datagenerator->create_course();
219         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
221         $counts = $this->vault->get_reply_count_for_discussion_ids([]);
222         $this->assertCount(0, $counts);
223     }
225     /**
226      * Test get_reply_count_for_discussion_ids.
227      *
228      * @covers ::get_reply_count_for_discussion_ids
229      * @covers ::<!public>
230      */
231     public function test_get_reply_count_for_discussion_ids() {
232         $this->resetAfterTest();
234         $datagenerator = $this->getDataGenerator();
235         $user = $datagenerator->create_user();
236         $course = $datagenerator->create_course();
237         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
238         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
239         $post2 = $this->helper_reply_to_post($post1, $user);
240         $post3 = $this->helper_reply_to_post($post1, $user);
241         $post4 = $this->helper_reply_to_post($post2, $user);
242         [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user);
243         $post6 = $this->helper_reply_to_post($post5, $user);
244         [$discussion3, $post7] = $this->helper_post_to_forum($forum, $user);
246         $counts = $this->vault->get_reply_count_for_discussion_ids([$discussion1->id]);
247         $this->assertCount(1, $counts);
248         $this->assertEquals(3, $counts[$discussion1->id]);
250         $counts = $this->vault->get_reply_count_for_discussion_ids([$discussion1->id, $discussion2->id]);
251         $this->assertCount(2, $counts);
252         $this->assertEquals(3, $counts[$discussion1->id]);
253         $this->assertEquals(1, $counts[$discussion2->id]);
255         $counts = $this->vault->get_reply_count_for_discussion_ids([$discussion1->id, $discussion2->id, $discussion3->id]);
256         $this->assertCount(2, $counts);
257         $this->assertEquals(3, $counts[$discussion1->id]);
258         $this->assertEquals(1, $counts[$discussion2->id]);
260         $counts = $this->vault->get_reply_count_for_discussion_ids([
261             $discussion1->id,
262             $discussion2->id,
263             $discussion3->id,
264             $discussion3->id + 1000
265         ]);
266         $this->assertCount(2, $counts);
267         $this->assertEquals(3, $counts[$discussion1->id]);
268         $this->assertEquals(1, $counts[$discussion2->id]);
269     }
271     /**
272      * Test get_unread_count_for_discussion_ids.
273      *
274      * @covers ::get_unread_count_for_discussion_ids
275      * @covers ::<!public>
276      */
277     public function test_get_unread_count_for_discussion_ids() {
278         global $CFG;
279         $this->resetAfterTest();
281         $datagenerator = $this->getDataGenerator();
282         $user = $datagenerator->create_user();
283         $otheruser = $datagenerator->create_user();
284         $course = $datagenerator->create_course();
285         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
286         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
287         $post2 = $this->helper_reply_to_post($post1, $user);
288         $post3 = $this->helper_reply_to_post($post1, $user);
289         $post4 = $this->helper_reply_to_post($post2, $user);
290         [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user);
291         $post6 = $this->helper_reply_to_post($post5, $user);
293         $modgenerator = $this->getDataGenerator()->get_plugin_generator('mod_forum');
294         $post7 = $modgenerator->create_post((object) [
295             'discussion' => $post5->discussion,
296             'parent' => $post5->id,
297             'userid' => $user->id,
298             'mailnow' => 1,
299             'subject' => 'old post',
300             // Two days ago which makes it an "old post".
301             'modified' => time() - 172800
302         ]);
304         forum_tp_add_read_record($user->id, $post1->id);
305         forum_tp_add_read_record($user->id, $post4->id);
306         $CFG->forum_oldpostdays = 1;
308         $counts = $this->vault->get_unread_count_for_discussion_ids($user, [$discussion1->id]);
309         $this->assertCount(1, $counts);
310         $this->assertEquals(2, $counts[$discussion1->id]);
312         $counts = $this->vault->get_unread_count_for_discussion_ids($user, [$discussion1->id, $discussion2->id]);
313         $this->assertCount(2, $counts);
314         $this->assertEquals(2, $counts[$discussion1->id]);
315         $this->assertEquals(2, $counts[$discussion2->id]);
317         $counts = $this->vault->get_unread_count_for_discussion_ids($user, [
318             $discussion1->id,
319             $discussion2->id,
320             $discussion2->id + 1000
321         ]);
322         $this->assertCount(2, $counts);
323         $this->assertEquals(2, $counts[$discussion1->id]);
324         $this->assertEquals(2, $counts[$discussion2->id]);
326         $counts = $this->vault->get_unread_count_for_discussion_ids($otheruser, [$discussion1->id, $discussion2->id]);
327         $this->assertCount(2, $counts);
328         $this->assertEquals(4, $counts[$discussion1->id]);
329         $this->assertEquals(2, $counts[$discussion2->id]);
330     }
332     /**
333      * Test get_unread_count_for_discussion_ids when no discussion ids were provided.
334      *
335      * @covers ::get_unread_count_for_discussion_ids
336      */
337     public function test_get_unread_count_for_discussion_ids_empty() {
338         $this->resetAfterTest();
340         $datagenerator = $this->getDataGenerator();
341         $user = $datagenerator->create_user();
342         $course = $datagenerator->create_course();
343         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
345         $this->assertEquals([], $this->vault->get_unread_count_for_discussion_ids($user, [], false));
346     }
348     /**
349      * Test get_latest_post_id_for_discussion_ids.
350      *
351      * @covers ::get_latest_post_id_for_discussion_ids
352      * @covers ::<!public>
353      */
354     public function test_get_latest_post_id_for_discussion_ids() {
355         $this->resetAfterTest();
357         $datagenerator = $this->getDataGenerator();
358         $user = $datagenerator->create_user();
359         $course = $datagenerator->create_course();
360         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
361         [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user);
362         $post2 = $this->helper_reply_to_post($post1, $user);
363         $post3 = $this->helper_reply_to_post($post1, $user);
364         $post4 = $this->helper_reply_to_post($post2, $user);
365         [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user);
366         $post6 = $this->helper_reply_to_post($post5, $user);
367         [$discussion3, $post7] = $this->helper_post_to_forum($forum, $user);
369         $ids = $this->vault->get_latest_post_id_for_discussion_ids([$discussion1->id]);
370         $this->assertCount(1, $ids);
371         $this->assertEquals($post4->id, $ids[$discussion1->id]);
373         $ids = $this->vault->get_latest_post_id_for_discussion_ids([$discussion1->id, $discussion2->id]);
374         $this->assertCount(2, $ids);
375         $this->assertEquals($post4->id, $ids[$discussion1->id]);
376         $this->assertEquals($post6->id, $ids[$discussion2->id]);
378         $ids = $this->vault->get_latest_post_id_for_discussion_ids([$discussion1->id, $discussion2->id, $discussion3->id]);
379         $this->assertCount(3, $ids);
380         $this->assertEquals($post4->id, $ids[$discussion1->id]);
381         $this->assertEquals($post6->id, $ids[$discussion2->id]);
382         $this->assertEquals($post7->id, $ids[$discussion3->id]);
384         $ids = $this->vault->get_latest_post_id_for_discussion_ids([
385             $discussion1->id,
386             $discussion2->id,
387             $discussion3->id,
388             $discussion3->id + 1000
389         ]);
390         $this->assertCount(3, $ids);
391         $this->assertEquals($post4->id, $ids[$discussion1->id]);
392         $this->assertEquals($post6->id, $ids[$discussion2->id]);
393         $this->assertEquals($post7->id, $ids[$discussion3->id]);
394     }
396     /**
397      * Test get_latest_post_id_for_discussion_ids when no discussion ids were provided.
398      *
399      * @covers ::get_latest_post_id_for_discussion_ids
400      * @covers ::<!public>
401      */
402     public function test_get_latest_post_id_for_discussion_ids_empty() {
403         $this->resetAfterTest();
405         $datagenerator = $this->getDataGenerator();
406         $user = $datagenerator->create_user();
407         $course = $datagenerator->create_course();
408         $forum = $datagenerator->create_module('forum', ['course' => $course->id]);
410         $this->assertEquals([], $this->vault->get_latest_post_id_for_discussion_ids([]));
411     }