MDL-65033 mod_forum: Externallib tests
authorPeter <peter@moodle.com>
Wed, 20 Mar 2019 23:11:57 +0000 (07:11 +0800)
committerPeter <peterrolanddias@gmail.com>
Mon, 29 Apr 2019 08:22:04 +0000 (16:22 +0800)
mod/forum/classes/local/entities/discussion.php
mod/forum/classes/local/factories/url.php
mod/forum/classes/local/renderers/discussion.php
mod/forum/classes/local/renderers/discussion_list.php
mod/forum/classes/local/vaults/discussion_list.php
mod/forum/externallib.php
mod/forum/lang/en/forum.php
mod/forum/tests/behat/behat_mod_forum.php
mod/forum/tests/entities_discussion_test.php
mod/forum/tests/externallib_test.php

index 6e4e689..e50bffa 100644 (file)
@@ -300,6 +300,12 @@ class discussion {
         return $this->get_group_id() > 0;
     }
 
+    /**
+     * Set the pinned value for this entity
+     *
+     * @param int $targetstate The state to change the pin to
+     * @return bool
+     */
     public function set_pinned(int $targetstate): bool {
         if ($targetstate != $this->pinned) {
             $this->pinned = $targetstate;
@@ -308,7 +314,6 @@ class discussion {
         return true;
     }
 
-
     /**
      * Check if the discussion is timed.
      *
@@ -336,6 +341,8 @@ class discussion {
      * @param discussion $discussion The discussion record
      * @param context $forumcontext Forum context
      * @param \stdClass $user The user to check the favourite against
+     *
+     * @return bool Whether or not the user has favourited the discussion
      */
     public static function is_favourited(discussion $discussion, \context_module $forumcontext, \stdClass $user) {
         $usercontext = \context_user::instance($user->id);
index 6c3d20d..2d9f7a7 100644 (file)
@@ -455,6 +455,7 @@ class url {
             'sesskey' => sesskey(),
             'id' => $discussion->get_forum_id(),
             'd' => $discussion->get_id()
+        ]);
     }
 
     /**
index a5fbd14..3eb42e5 100644 (file)
@@ -201,10 +201,6 @@ class discussion {
             $exporteddiscussion['html']['pindiscussion'] = $this->get_pin_discussion_html();
         }
 
-        if ($capabilities['favourite']) {
-            $exporteddiscussion['html']['favouritediscussion'] = $this->get_favourite_discussion_html($exporteddiscussion);
-        }
-
         return $this->renderer->render_from_template('mod_forum/forum_discussion', $exporteddiscussion);
     }
 
@@ -355,10 +351,6 @@ class discussion {
         return $this->renderer->render($link);
     }
 
-    private function get_favourite_discussion_html($exporteddiscussion) : string {
-        return $this->renderer->render_from_template('mod_forum/discussion_favourite_toggle', $exporteddiscussion);
-    }
-
     /**
      * Get the HTML to render the export discussion button.
      *
index 6731987..c4db64d 100644 (file)
@@ -171,7 +171,6 @@ class discussion_list {
             ),
             'hasmore' => ($alldiscussionscount > $pagesize),
             'notifications' => $this->get_notifications($user, $groupid),
-            'notifications' => $this->get_notifications($user, $groupid)
             'settings' => [
                 'excludetext' => true,
                 'togglemoreicon' => true
index 58ed8ad..e1b059c 100644 (file)
@@ -74,6 +74,11 @@ class discussion_list extends db_table_vault {
         return 'd';
     }
 
+    /**
+     * Get the favourite table alias
+     *
+     * @return string
+     */
     protected function get_favourite_alias() : string {
         return 'favalias';
     }
@@ -83,6 +88,8 @@ class discussion_list extends db_table_vault {
      *
      * @param string|null $wheresql Where conditions for the SQL
      * @param string|null $sortsql Order by conditions for the SQL
+     * @param  string|null $joinsql Additional join conditions for the sql
+     *
      * @return string
      */
     protected function generate_get_records_sql(string $wheresql = null, ?string $sortsql = null, ?string $joinsql = null) : string {
@@ -188,15 +195,20 @@ class discussion_list extends db_table_vault {
 
         $alias = $this->get_table_alias();
 
-        $keyfield = "{$alias}.timemodified";
-        $direction = "DESC";
+        if ($sortmethod == self::SORTORDER_CREATED_DESC) {
+            $keyfield = "fp.created";
+            $direction = "DESC";
+        } else {
+            $keyfield = "{$alias}.timemodified";
+            $direction = "DESC";
 
-        if ($sortmethod == self::SORTORDER_OLDEST_FIRST) {
-            $direction = "ASC";
-        }
+            if ($sortmethod == self::SORTORDER_OLDEST_FIRST) {
+                $direction = "ASC";
+            }
 
-        if (!empty($CFG->forum_enabletimedposts)) {
-            $keyfield = "CASE WHEN {$keyfield} < {$alias}.timestart THEN {$alias}.timestart ELSE {$keyfield} END";
+            if (!empty($CFG->forum_enabletimedposts)) {
+                $keyfield = "CASE WHEN {$keyfield} < {$alias}.timestart THEN {$alias}.timestart ELSE {$keyfield} END";
+            }
         }
 
         return "{$alias}.pinned DESC, {$this->get_favourite_alias()}.id DESC, {$keyfield} {$direction}";
@@ -404,7 +416,8 @@ class discussion_list extends db_table_vault {
         $usercontext = \context_user::instance($USER->id);
         $alias = $this->get_table_alias();
         $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
-        list($favsql, $favparams) = $ufservice->get_join_sql_by_type('mod_forum', 'discussions', $this->get_favourite_alias(), "$alias.id");
+        list($favsql, $favparams) = $ufservice->get_join_sql_by_type('mod_forum', 'discussions',
+            $this->get_favourite_alias(), "$alias.id");
 
         return [$favsql, $favparams];
     }
index 0066f3c..76925e2 100644 (file)
@@ -1097,6 +1097,14 @@ class mod_forum_external extends external_api {
         );
     }
 
+    /**
+     * Toggle the favouriting value for the discussion provided
+     *
+     * @param int $forumid The forum id
+     * @param int $discussionid The discussion we need to favourite
+     * @param bool $targetstate The state of the favourite value
+     * @return array The exported discussion
+     */
     public static function toggle_favourite_state($forumid, $discussionid, $targetstate) {
         global $DB, $PAGE, $USER;
 
@@ -1149,6 +1157,11 @@ class mod_forum_external extends external_api {
         return discussion_exporter::get_read_structure();
     }
 
+    /**
+     * Defines the parameters for the toggle_favourite_state method
+     *
+     * @return external_function_parameters
+     */
     public static function toggle_favourite_state_parameters() {
         return new external_function_parameters(
             [
@@ -1638,17 +1651,19 @@ class mod_forum_external extends external_api {
             'targetstate' => $targetstate,
         ]);
         $vaultfactory = mod_forum\local\container::get_vault_factory();
+        $managerfactory = mod_forum\local\container::get_manager_factory();
         $forumvault = $vaultfactory->get_forum_vault();
         $discussionvault = $vaultfactory->get_discussion_vault();
         $forum = $forumvault->get_from_id($params['forumid']);
+        $capabilitymanager = $managerfactory->get_capability_manager($forum);
 
         self::validate_context($forum->get_context());
 
         $legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory();
         $forumrecord = $legacydatamapperfactory->get_forum_data_mapper()->to_legacy_object($forum);
-        if (!\mod_forum\subscriptions::is_subscribable($forumrecord)) {
+        if (!$capabilitymanager->can_pin_discussions($USER)) {
             // Nothing to do. We won't actually output any content here though.
-            throw new \moodle_exception('cannotsubscribe', 'mod_forum');
+            throw new \moodle_exception('cannotpindiscussions', 'mod_forum');
         }
 
         $discussion = $discussionvault->get_from_id($params['discussionid']);
@@ -1684,9 +1699,12 @@ class mod_forum_external extends external_api {
     public static function set_pin_state_parameters() {
         return new external_function_parameters(
             [
-                'forumid' => new external_value(PARAM_INT, 'Forum that the discussion is in', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
-                'discussionid' => new external_value(PARAM_INT, 'The discussion to pin or unpin', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
-                'targetstate' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED, null, NULL_NOT_ALLOWED),
+                'forumid' => new external_value(PARAM_INT, 'Forum that the discussion is in', VALUE_REQUIRED,
+                    null, NULL_NOT_ALLOWED),
+                'discussionid' => new external_value(PARAM_INT, 'The discussion to pin or unpin', VALUE_REQUIRED,
+                    null, NULL_NOT_ALLOWED),
+                'targetstate' => new external_value(PARAM_INT, 'The target state', VALUE_REQUIRED,
+                    null, NULL_NOT_ALLOWED),
             ]
         );
     }
index 4b1fe2e..81cbeff 100644 (file)
@@ -75,6 +75,7 @@ $string['cannotmovenotvisible'] = 'Forum not visible';
 $string['cannotmovetonotexist'] = 'You can\'t move to that forum - it doesn\'t exist!';
 $string['cannotmovetonotfound'] = 'Target forum not found in this course.';
 $string['cannotmovetosingleforum'] = 'Cannot move discussion to a simple single discussion forum';
+$string['cannotpindiscussions'] = 'Sorry, you do not have the permission to pin discussions.';
 $string['cannotpurgecachedrss'] = 'Could not purge the cached RSS feeds for the source and/or destination forum(s) - check your file permissionsforums';
 $string['cannotremovesubscriber'] = 'Could not remove subscriber with id {$a} from this forum!';
 $string['cannotreply'] = 'You cannot reply to this post';
index c8eae10..b5cb276 100644 (file)
@@ -136,7 +136,7 @@ class behat_mod_forum extends behat_base {
     public function i_click_on_action_menu($discussion) {
         $this->execute('behat_general::i_click_on_in_the', [
             "[data-container='discussion-tools'] [data-toggle='dropdown']", "css_element",
-            "//tr[@class='discussion-row' and contains(.,'$discussion')]", "xpath_element"
+            "//tr[@class='discussion' and contains(.,'$discussion')]", "xpath_element"
         ]);
     }
 
index 40b393a..9e6d46b 100644 (file)
@@ -198,7 +198,7 @@ class mod_forum_entities_discussion_testcase extends advanced_testcase {
 
         $this->assertFalse(\mod_forum\local\entities\discussion::is_favourited($discussion, $contextmodule, $user));
 
-        // Toggle the favourite for discussion
+        // Toggle the favourite for discussion.
         $usercontext = \context_user::instance($user->id);
         $ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
         $ufservice->create_favourite('mod_forum', 'discussions', $discussion->get_id(), $contextmodule);
index 9fd0f8f..9549f30 100644 (file)
@@ -221,6 +221,52 @@ class mod_forum_external_testcase extends externallib_advanced_testcase {
         $this->assertFalse($response['userstate']['favourited']);
     }
 
+    /**
+     * Test the toggle pin state
+     */
+    public function test_mod_forum_set_pin_state() {
+        $this->resetAfterTest(true);
+
+        // Create a user.
+        $user = self::getDataGenerator()->create_user(array('trackforums' => 1));
+
+        // Set to the user.
+        self::setUser($user);
+
+        // Create courses to add the modules.
+        $course1 = self::getDataGenerator()->create_course();
+        $this->getDataGenerator()->enrol_user($user->id, $course1->id);
+
+        $record = new stdClass();
+        $record->introformat = FORMAT_HTML;
+        $record->course = $course1->id;
+        $record->trackingtype = FORUM_TRACKING_OFF;
+        $forum1 = self::getDataGenerator()->create_module('forum', $record);
+        $forum1->introfiles = [];
+
+        // Add discussions to the forums.
+        $record = new stdClass();
+        $record->course = $course1->id;
+        $record->userid = $user->id;
+        $record->forum = $forum1->id;
+        $discussion1 = self::getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);
+
+        try {
+            $response = mod_forum_external::set_pin_state($forum1->id, $discussion1->id, 1);
+        } catch (Exception $e) {
+            $this->assertEquals('cannotpindiscussions', $e->errorcode);
+        }
+
+        self::setAdminUser();
+        $response = mod_forum_external::set_pin_state($forum1->id, $discussion1->id, 1);
+        $response = external_api::clean_returnvalue(mod_forum_external::set_pin_state_returns(), $response);
+        $this->assertTrue($response['pinned']);
+
+        $response = mod_forum_external::set_pin_state($forum1->id, $discussion1->id, 0);
+        $response = external_api::clean_returnvalue(mod_forum_external::set_pin_state_returns(), $response);
+        $this->assertFalse($response['pinned']);
+    }
+
     /**
      * Test get forum posts
      */