From 3f9ed16e56ad22f5711277cbacda93c9fc0c6b86 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Tue, 30 Apr 2019 10:36:29 +0800 Subject: [PATCH] MDL-65071 forum: Add unit tests --- mod/forum/tests/exporters_forum_test.php | 3 +- mod/forum/tests/externallib_test.php | 344 ++++++++++++++++++ .../tests/vaults_discussion_list_test.php | 329 +++++++++++++++-- mod/forum/tests/vaults_post_test.php | 65 ++++ 4 files changed, 700 insertions(+), 41 deletions(-) diff --git a/mod/forum/tests/exporters_forum_test.php b/mod/forum/tests/exporters_forum_test.php index 6f41f8c5d8f..3cd8af43263 100644 --- a/mod/forum/tests/exporters_forum_test.php +++ b/mod/forum/tests/exporters_forum_test.php @@ -60,7 +60,8 @@ class mod_forum_exporters_forum_testcase extends advanced_testcase { 'urlfactory' => \mod_forum\local\container::get_url_factory(), 'capabilitymanager' => (\mod_forum\local\container::get_manager_factory())->get_capability_manager($forum), 'user' => $user, - 'currentgroup' => null + 'currentgroup' => null, + 'vaultfactory' => \mod_forum\local\container::get_vault_factory() ]); $exportedforum = $exporter->export($renderer); diff --git a/mod/forum/tests/externallib_test.php b/mod/forum/tests/externallib_test.php index 5277bb015ee..f1b5a85e462 100644 --- a/mod/forum/tests/externallib_test.php +++ b/mod/forum/tests/externallib_test.php @@ -1180,6 +1180,350 @@ class mod_forum_external_testcase extends externallib_advanced_testcase { } + /** + * Test get forum discussions + */ + public function test_mod_forum_get_forum_discussions() { + global $CFG, $DB, $PAGE; + + $this->resetAfterTest(true); + + // Set the CFG variable to allow track forums. + $CFG->forum_trackreadposts = true; + + // Create a user who can track forums. + $record = new stdClass(); + $record->trackforums = true; + $user1 = self::getDataGenerator()->create_user($record); + // Create a bunch of other users to post. + $user2 = self::getDataGenerator()->create_user(); + $user3 = self::getDataGenerator()->create_user(); + $user4 = self::getDataGenerator()->create_user(); + + // Set the first created user to the test user. + self::setUser($user1); + + // Create courses to add the modules. + $course1 = self::getDataGenerator()->create_course(); + + // First forum with tracking off. + $record = new stdClass(); + $record->course = $course1->id; + $record->trackingtype = FORUM_TRACKING_OFF; + $forum1 = self::getDataGenerator()->create_module('forum', $record); + + // Add discussions to the forums. + $record = new stdClass(); + $record->course = $course1->id; + $record->userid = $user1->id; + $record->forum = $forum1->id; + $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + + // Add three replies to the discussion 1 from different users. + $record = new stdClass(); + $record->discussion = $discussion1->id; + $record->parent = $discussion1->firstpost; + $record->userid = $user2->id; + $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + + $record->parent = $discussion1reply1->id; + $record->userid = $user3->id; + $discussion1reply2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + + $record->userid = $user4->id; + $discussion1reply3 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + + // Enrol the user in the first course. + $enrol = enrol_get_plugin('manual'); + + // We don't use the dataGenerator as we need to get the $instance2 to unenrol later. + $enrolinstances = enrol_get_instances($course1->id, true); + foreach ($enrolinstances as $courseenrolinstance) { + if ($courseenrolinstance->enrol == "manual") { + $instance1 = $courseenrolinstance; + break; + } + } + $enrol->enrol_user($instance1, $user1->id); + + // Delete one user. + delete_user($user4); + + // Assign capabilities to view discussions for forum 1. + $cm = get_coursemodule_from_id('forum', $forum1->cmid, 0, false, MUST_EXIST); + $context = context_module::instance($cm->id); + $newrole = create_role('Role 2', 'role2', 'Role 2 description'); + $this->assignUserCapability('mod/forum:viewdiscussion', $context->id, $newrole); + + // Create what we expect to be returned when querying the forums. + + $post1 = $DB->get_record('forum_posts', array('id' => $discussion1->firstpost), '*', MUST_EXIST); + + // User pictures are initially empty, we should get the links once the external function is called. + $expecteddiscussions = array( + 'id' => $discussion1->firstpost, + 'name' => $discussion1->name, + 'groupid' => (int) $discussion1->groupid, + 'timemodified' => (int) $discussion1reply3->created, + 'usermodified' => (int) $discussion1reply3->userid, + 'timestart' => (int) $discussion1->timestart, + 'timeend' => (int) $discussion1->timeend, + 'discussion' => (int) $discussion1->id, + 'parent' => 0, + 'userid' => (int) $discussion1->userid, + 'created' => (int) $post1->created, + 'modified' => (int) $post1->modified, + 'mailed' => (int) $post1->mailed, + 'subject' => $post1->subject, + 'message' => $post1->message, + 'messageformat' => (int) $post1->messageformat, + 'messagetrust' => (int) $post1->messagetrust, + 'attachment' => $post1->attachment, + 'totalscore' => (int) $post1->totalscore, + 'mailnow' => (int) $post1->mailnow, + 'userfullname' => fullname($user1), + 'usermodifiedfullname' => fullname($user4), + 'userpictureurl' => '', + 'usermodifiedpictureurl' => '', + 'numreplies' => 3, + 'numunread' => 0, + 'pinned' => (bool) FORUM_DISCUSSION_UNPINNED, + 'locked' => false, + 'canreply' => false, + 'canlock' => false, + ); + + // Call the external function passing forum id. + $discussions = mod_forum_external::get_forum_discussions($forum1->id); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + $expectedreturn = array( + 'discussions' => array($expecteddiscussions), + 'warnings' => array() + ); + + // Wait the theme to be loaded (the external_api call does that) to generate the user profiles. + $userpicture = new user_picture($user1); + $userpicture->size = 2; // Size f2. + $expectedreturn['discussions'][0]['userpictureurl'] = $userpicture->get_url($PAGE)->out(false); + + $userpicture = new user_picture($user4); + $userpicture->size = 2; // Size f2. + $expectedreturn['discussions'][0]['usermodifiedpictureurl'] = $userpicture->get_url($PAGE)->out(false); + + $this->assertEquals($expectedreturn, $discussions); + + // Call without required view discussion capability. + $this->unassignUserCapability('mod/forum:viewdiscussion', $context->id, $newrole); + try { + mod_forum_external::get_forum_discussions($forum1->id); + $this->fail('Exception expected due to missing capability.'); + } catch (moodle_exception $e) { + $this->assertEquals('noviewdiscussionspermission', $e->errorcode); + } + + // Unenrol user from second course. + $enrol->unenrol_user($instance1, $user1->id); + + // Call for the second course we unenrolled the user from, make sure exception thrown. + try { + mod_forum_external::get_forum_discussions($forum1->id); + $this->fail('Exception expected due to being unenrolled from the course.'); + } catch (moodle_exception $e) { + $this->assertEquals('requireloginerror', $e->errorcode); + } + + $this->setAdminUser(); + $discussions = mod_forum_external::get_forum_discussions($forum1->id); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + $this->assertTrue($discussions['discussions'][0]['canlock']); + } + + /** + * Test the sorting in get forum discussions + */ + public function test_mod_forum_get_forum_discussions_sorting() { + global $CFG, $DB, $PAGE; + + $this->resetAfterTest(true); + + // Set the CFG variable to allow track forums. + $CFG->forum_trackreadposts = true; + + // Create a user who can track forums. + $record = new stdClass(); + $record->trackforums = true; + $user1 = self::getDataGenerator()->create_user($record); + // Create a bunch of other users to post. + $user2 = self::getDataGenerator()->create_user(); + $user3 = self::getDataGenerator()->create_user(); + $user4 = self::getDataGenerator()->create_user(); + + // Set the first created user to the test user. + self::setUser($user1); + + // Create courses to add the modules. + $course1 = self::getDataGenerator()->create_course(); + + // Enrol the user in the first course. + $enrol = enrol_get_plugin('manual'); + + // We don't use the dataGenerator as we need to get the $instance2 to unenrol later. + $enrolinstances = enrol_get_instances($course1->id, true); + foreach ($enrolinstances as $courseenrolinstance) { + if ($courseenrolinstance->enrol == "manual") { + $instance1 = $courseenrolinstance; + break; + } + } + $enrol->enrol_user($instance1, $user1->id); + + // First forum with tracking off. + $record = new stdClass(); + $record->course = $course1->id; + $record->trackingtype = FORUM_TRACKING_OFF; + $forum1 = self::getDataGenerator()->create_module('forum', $record); + + // Assign capabilities to view discussions for forum 1. + $cm = get_coursemodule_from_id('forum', $forum1->cmid, 0, false, MUST_EXIST); + $context = context_module::instance($cm->id); + $newrole = create_role('Role 2', 'role2', 'Role 2 description'); + $this->assignUserCapability('mod/forum:viewdiscussion', $context->id, $newrole); + + // Add discussions to the forums. + $record = new stdClass(); + $record->course = $course1->id; + $record->userid = $user1->id; + $record->forum = $forum1->id; + $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + sleep(1); + + // Add three replies to the discussion 1 from different users. + $record = new stdClass(); + $record->discussion = $discussion1->id; + $record->parent = $discussion1->firstpost; + $record->userid = $user2->id; + $discussion1reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + sleep(1); + + $record->parent = $discussion1reply1->id; + $record->userid = $user3->id; + $discussion1reply2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + sleep(1); + + $record->userid = $user4->id; + $discussion1reply3 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + sleep(1); + + // Create discussion2. + $record2 = new stdClass(); + $record2->course = $course1->id; + $record2->userid = $user1->id; + $record2->forum = $forum1->id; + $discussion2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record2); + sleep(1); + + // Add one reply to the discussion 2. + $record2 = new stdClass(); + $record2->discussion = $discussion2->id; + $record2->parent = $discussion2->firstpost; + $record2->userid = $user2->id; + $discussion2reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record2); + sleep(1); + + // Create discussion 3. + $record3 = new stdClass(); + $record3->course = $course1->id; + $record3->userid = $user1->id; + $record3->forum = $forum1->id; + $discussion3 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record3); + sleep(1); + + // Add two replies to the discussion 3. + $record3 = new stdClass(); + $record3->discussion = $discussion3->id; + $record3->parent = $discussion3->firstpost; + $record3->userid = $user2->id; + $discussion3reply1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record3); + sleep(1); + + $record3->parent = $discussion3reply1->id; + $record3->userid = $user3->id; + $discussion3reply2 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record3); + + // Call the external function passing forum id. + $discussions = mod_forum_external::get_forum_discussions($forum1->id); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by last post date in descending order by default. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion3->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion1->id); + + $vaultfactory = \mod_forum\local\container::get_vault_factory(); + $discussionlistvault = $vaultfactory->get_discussions_in_forum_vault(); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_LASTPOST_ASC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by last post date in ascending order. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion1->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion3->id); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_CREATED_DESC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by discussion creation date in descending order. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion3->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion1->id); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_CREATED_ASC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by discussion creation date in ascending order. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion1->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion3->id); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_REPLIES_DESC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by the number of replies in descending order. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion1->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion3->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion2->id); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_REPLIES_ASC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by the number of replies in ascending order. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion3->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion1->id); + + // Pin discussion2. + $DB->update_record('forum_discussions', + (object) array('id' => $discussion2->id, 'pinned' => FORUM_DISCUSSION_PINNED)); + + // Call the external function passing forum id. + $discussions = mod_forum_external::get_forum_discussions($forum1->id); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by last post date in descending order by default. + // Pinned discussions should be at the top of the list. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion3->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion1->id); + + // Call the external function passing forum id and sort order parameter. + $discussions = mod_forum_external::get_forum_discussions($forum1->id, $discussionlistvault::SORTORDER_LASTPOST_ASC); + $discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions); + // Discussions should be ordered by last post date in ascending order. + // Pinned discussions should be at the top of the list. + $this->assertEquals($discussions['discussions'][0]['discussion'], $discussion2->id); + $this->assertEquals($discussions['discussions'][1]['discussion'], $discussion1->id); + $this->assertEquals($discussions['discussions'][2]['discussion'], $discussion3->id); + } + /** * Test add_discussion_post */ diff --git a/mod/forum/tests/vaults_discussion_list_test.php b/mod/forum/tests/vaults_discussion_list_test.php index 510ff1929af..58c09d93285 100644 --- a/mod/forum/tests/vaults_discussion_list_test.php +++ b/mod/forum/tests/vaults_discussion_list_test.php @@ -82,41 +82,143 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $course = $datagenerator->create_course(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); - $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, $user->id, null, 0, 0, $user)); + $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, $user->id, null, + 0, 0, $user)); $now = time(); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]); [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]); [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]); + [$discussion3, $post4] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 8, 'timemodified' => 4]); - $summaries = array_values($vault->get_from_forum_id($forum->id, false, null, null, 0, 0, $user)); - $this->assertCount(2, $summaries); + // By default orders the discussions by last post. + $summaries = array_values($vault->get_from_forum_id($forum->id, false, null, null, + 0, 0, $user)); + $this->assertCount(3, $summaries); + $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, + 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, false, $user->id, null, + 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, + 1, 0, $user)); + $this->assertCount(1, $summaries); + $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, + 1, 1, $user)); + $this->assertCount(1, $summaries); + $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, + 1, 2, $user)); + $this->assertCount(1, $summaries); + $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id()); + + // Create 2 replies for $post1. + $this->helper_reply_to_post($post1, $user); + $this->helper_reply_to_post($post1, $user); + // Create 3 replies for $post2. + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + // Create 1 reply for $post3. + $this->helper_reply_to_post($post3, $user); + + // Sort discussions by last post DESC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_DESC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id()); + + // Sort discussions by last post ASC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_ASC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id()); + + // Sort discussions by replies DESC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_REPLIES_DESC, 0, 0, $user)); + $this->assertCount(4, $summaries); $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, 0, 0, $user)); - $this->assertCount(3, $summaries); - $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); - $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + // Sort discussions by replies ASC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_REPLIES_ASC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[3]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id($forum->id, false, $user->id, null, 0, 0, $user)); - $this->assertCount(3, $summaries); - $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); - $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); - $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id()); + // Sort discussions by discussion created DESC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_CREATED_DESC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion3->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, 1, 0, $user)); - $this->assertCount(1, $summaries); - $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); - - $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, 1, 1, $user)); - $this->assertCount(1, $summaries); - $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id()); - - $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, null, 1, 2, $user)); - $this->assertCount(1, $summaries); + // Sort discussions by discussion created ASC. + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_CREATED_ASC, 0, 0, $user)); + $this->assertCount(4, $summaries); $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id()); + + // Sort discussions when there is a pinned discussion. + $this->pin_discussion($discussion1); + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_ASC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_DESC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_REPLIES_DESC, 0, 0, $user)); + $this->assertCount(4, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($discussion3->id, $summaries[3]->get_discussion()->get_id()); } /** @@ -132,7 +234,8 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $course = $datagenerator->create_course(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); - $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, true, null, 0, 0, $user)); + $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, true, + null, 0, 0, $user)); $now = time(); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]); @@ -154,7 +257,8 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { ['timestart' => $now + 11, 'timemodified' => 6, 'groupid' => 3] ); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, null, null, 0, 0, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + null, null, 0, 0, $user)); $this->assertCount(6, $summaries); $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id()); $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); @@ -163,7 +267,8 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false, $user->id, null, 0, 0, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false, + $user->id, null, 0, 0, $user)); $this->assertCount(6, $summaries); $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id()); $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); @@ -172,32 +277,157 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, null, null, 1, 0, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + null, null, 1, 0, $user)); $this->assertCount(1, $summaries); $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, null, null, 1, 1, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + null, null, 1, 1, $user)); $this->assertCount(1, $summaries); $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, null, null, 1, 2, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + null, null, 1, 2, $user)); $this->assertCount(1, $summaries); $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false, null, null, 0, 0, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], false, + null, null, 0, 0, $user)); $this->assertCount(4, $summaries); $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id()); $this->assertEquals($groupdiscussion1->id, $summaries[1]->get_discussion()->get_id()); $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[3]->get_discussion()->get_id()); - $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [], true, null, null, 0, 0, $user)); + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [], true, + null, null, 0, 0, $user)); $this->assertCount(3, $summaries); $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); $this->assertEquals($discussion1->id, $summaries[2]->get_discussion()->get_id()); - } + // Add 4 replies to $post1. + $this->helper_reply_to_post($post1, $user); + $this->helper_reply_to_post($post1, $user); + $this->helper_reply_to_post($post1, $user); + $this->helper_reply_to_post($post1, $user); + // Add 5 replies to $post2. + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + $this->helper_reply_to_post($post2, $user); + // Add 3 replies to $post3. + $this->helper_reply_to_post($post3, $user); + $this->helper_reply_to_post($post3, $user); + $this->helper_reply_to_post($post3, $user); + // Add 2 replies to $post4. + $this->helper_reply_to_post($post4, $user); + $this->helper_reply_to_post($post4, $user); + // Add 1 reply to $post5. + $this->helper_reply_to_post($post5, $user); + + // Sort discussions by last post DESC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_LASTPOST_DESC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($groupdiscussion2->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions by last post ASC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_LASTPOST_ASC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions by replies DESC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_REPLIES_DESC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($discussion2->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions by replies ASC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_REPLIES_ASC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions by discussion created DESC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_CREATED_DESC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions by discussion created ASC. + $summaries = array_values($vault->get_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, + $user->id, $vault::SORTORDER_CREATED_ASC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id()); + + // Sort discussions when there is a pinned discussion. + $this->pin_discussion($discussion1); + $this->pin_discussion($hiddendiscussion); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_DESC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($hiddendiscussion->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($discussion1->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[5]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_LASTPOST_ASC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[5]->get_discussion()->get_id()); + + $summaries = array_values($vault->get_from_forum_id($forum->id, true, null, + $vault::SORTORDER_REPLIES_DESC, 0, 0, $user)); + $this->assertCount(6, $summaries); + $this->assertEquals($discussion1->id, $summaries[0]->get_discussion()->get_id()); + $this->assertEquals($hiddendiscussion->id, $summaries[1]->get_discussion()->get_id()); + $this->assertEquals($discussion2->id, $summaries[2]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion1->id, $summaries[3]->get_discussion()->get_id()); + $this->assertEquals($groupdiscussion2->id, $summaries[4]->get_discussion()->get_id()); + $this->assertEquals($hiddengroupdiscussion->id, $summaries[5]->get_discussion()->get_id()); + } /** * Test get_total_discussion_count_from_forum_id. @@ -211,19 +441,22 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $course = $datagenerator->create_course(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); - $this->assertEquals(0, $vault->get_total_discussion_count_from_forum_id($forum->id, true, null)); + $this->assertEquals(0, $vault->get_total_discussion_count_from_forum_id($forum->id, true, + null)); $now = time(); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]); [$discussion2, $post2] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 9, 'timemodified' => 2]); [$hiddendiscussion, $post3] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now + 10, 'timemodified' => 3]); - $this->assertEquals(2, $vault->get_total_discussion_count_from_forum_id($forum->id, false, null)); - $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, true, null)); - $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, false, $user->id)); + $this->assertEquals(2, $vault->get_total_discussion_count_from_forum_id($forum->id, false, + null)); + $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, true, + null)); + $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id($forum->id, false, + $user->id)); } - /** * Test get_total_discussion_count_from_forum_id_and_group_id. */ @@ -237,7 +470,8 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { $course = $datagenerator->create_course(); $forum = $datagenerator->create_module('forum', ['course' => $course->id]); - $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, true, null, 0, 0, $user)); + $this->assertEquals([], $vault->get_from_forum_id($forum->id, true, true, + null, 0, 0, $user)); $now = time(); [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user, ['timestart' => $now - 10, 'timemodified' => 1]); @@ -259,14 +493,29 @@ class mod_forum_vaults_discussion_list_testcase extends advanced_testcase { ['timestart' => $now + 11, 'timemodified' => 6, 'groupid' => 3] ); - $this->assertEquals(6, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3], true, null)); + $this->assertEquals(6, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3], + true, null)); $this->assertEquals(6, $vault->get_total_discussion_count_from_forum_id_and_group_id( $forum->id, [1, 2, 3], false, $user->id )); - $this->assertEquals(4, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3], false, null)); - $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [], true, null)); + $this->assertEquals(4, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [1, 2, 3], + false, null)); + $this->assertEquals(3, $vault->get_total_discussion_count_from_forum_id_and_group_id($forum->id, [], + true, null)); + } + + /** + * Pin a duscussion. + * + * @param stdClass $discussion + */ + private function pin_discussion(stdClass $discussion) { + global $DB; + + $DB->update_record('forum_discussions', + (object) array('id' => $discussion->id, 'pinned' => FORUM_DISCUSSION_PINNED)); } } diff --git a/mod/forum/tests/vaults_post_test.php b/mod/forum/tests/vaults_post_test.php index 2f083fa759d..2f24eb3f1dc 100644 --- a/mod/forum/tests/vaults_post_test.php +++ b/mod/forum/tests/vaults_post_test.php @@ -799,4 +799,69 @@ class mod_forum_vaults_post_testcase extends advanced_testcase { $this->assertEquals([], $this->vault->get_latest_post_id_for_discussion_ids($user, [], false)); } + + /** + * Test get_first_post_for_discussion_ids. + * + * @covers ::get_first_post_for_discussion_ids + * @covers :: + */ + public function test_get_first_post_for_discussion_ids() { + $this->resetAfterTest(); + + $datagenerator = $this->getDataGenerator(); + $user = $datagenerator->create_user(); + $course = $datagenerator->create_course(); + $forum = $datagenerator->create_module('forum', ['course' => $course->id]); + [$discussion1, $post1] = $this->helper_post_to_forum($forum, $user); + $post2 = $this->helper_reply_to_post($post1, $user); + $post3 = $this->helper_reply_to_post($post1, $user); + $post4 = $this->helper_reply_to_post($post2, $user); + [$discussion2, $post5] = $this->helper_post_to_forum($forum, $user); + $post6 = $this->helper_reply_to_post($post5, $user); + [$discussion3, $post7] = $this->helper_post_to_forum($forum, $user); + + $firstposts = $this->vault->get_first_post_for_discussion_ids([$discussion1->id]); + $this->assertCount(1, $firstposts); + $this->assertEquals($post1->id, reset($firstposts)->id); + + $firstposts = $this->vault->get_first_post_for_discussion_ids([$discussion1->id, $discussion2->id]); + $this->assertCount(2, $firstposts); + $this->assertEquals($post1->id, $firstposts[$post1->id]->id); + $this->assertEquals($post5->id, $firstposts[$post5->id]->id); + + $firstposts = $this->vault->get_first_post_for_discussion_ids([$discussion1->id, $discussion2->id, $discussion3->id]); + $this->assertCount(3, $firstposts); + $this->assertEquals($post1->id, $firstposts[$post1->id]->id); + $this->assertEquals($post5->id, $firstposts[$post5->id]->id); + $this->assertEquals($post7->id, $firstposts[$post7->id]->id); + + $firstposts = $this->vault->get_first_post_for_discussion_ids([ + $discussion1->id, + $discussion2->id, + $discussion3->id, + $discussion3->id + 1000 + ]); + $this->assertCount(3, $firstposts); + $this->assertEquals($post1->id, $firstposts[$post1->id]->id); + $this->assertEquals($post5->id, $firstposts[$post5->id]->id); + $this->assertEquals($post7->id, $firstposts[$post7->id]->id); + } + + /** + * Test get_first_post_for_discussion_ids when no discussion ids were provided. + * + * @covers ::get_first_post_for_discussion_ids + * @covers :: + */ + public function test_get_first_post_for_discussion_ids_empty() { + $this->resetAfterTest(); + + $datagenerator = $this->getDataGenerator(); + $user = $datagenerator->create_user(); + $course = $datagenerator->create_course(); + $forum = $datagenerator->create_module('forum', ['course' => $course->id]); + + $this->assertEquals([], $this->vault->get_first_post_for_discussion_ids([])); + } }