Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?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/>./*** Steps definitions related with the forum activity.** @package mod_forum* @category test* @copyright 2013 David Monllaó* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/// NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.require_once(__DIR__ . '/../../../../lib/behat/behat_base.php');use Behat\Gherkin\Node\TableNode;/*** Forum-related steps definitions.** @package mod_forum* @category test* @copyright 2013 David Monllaó* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class behat_mod_forum extends behat_base {/*** Reset forum caches between tests.** @BeforeScenario @mod_forum*/public function reset_forum_caches(): void {\mod_forum\subscriptions::reset_discussion_cache();\mod_forum\subscriptions::reset_forum_cache();}/*** Adds a topic to the forum specified by it's name. Useful for the Announcements and blog-style forums.** @Given /^I add a new topic to "(?P<forum_name_string>(?:[^"]|\\")*)" forum with:$/* @param string $forumname* @param TableNode $table*/public function i_add_a_new_topic_to_forum_with($forumname, TableNode $table) {$this->add_new_discussion($forumname, $table, get_string('addanewdiscussion', 'forum'));}/*** Adds a Q&A discussion to the Q&A-type forum specified by it's name with the provided table data.** @Given /^I add a new question to "(?P<forum_name_string>(?:[^"]|\\")*)" forum with:$/* @param string $forumname* @param TableNode $table*/public function i_add_a_new_question_to_forum_with($forumname, TableNode $table) {$this->add_new_discussion($forumname, $table, get_string('addanewdiscussion', 'forum'));}/*** Adds a discussion to the forum specified by it's name with the provided table data (usually Subject and Message). The step begins from the forum's course page.** @Given /^I add a new discussion to "(?P<forum_name_string>(?:[^"]|\\")*)" forum with:$/* @param string $forumname* @param TableNode $table*/public function i_add_a_forum_discussion_to_forum_with($forumname, TableNode $table) {$this->add_new_discussion($forumname, $table, get_string('addanewdiscussion', 'forum'));}/*** Adds a discussion to the forum specified by it's name with the provided table data (usually Subject and Message).* The step begins from the forum's course page.** @Given /^I add a new discussion to "(?P<forum_name_string>(?:[^"]|\\")*)" forum inline with:$/* @param string $forumname* @param TableNode $table*/public function i_add_a_forum_discussion_to_forum_inline_with($forumname, TableNode $table) {$this->add_new_discussion_inline($forumname, $table, get_string('addanewdiscussion', 'forum'));}/*** Adds a reply to the specified post of the specified forum. The step begins from the forum's page or from the forum's course page.** @Given /^I reply "(?P<post_subject_string>(?:[^"]|\\")*)" post from "(?P<forum_name_string>(?:[^"]|\\")*)" forum with:$/* @param string $postname The subject of the post* @param string $forumname The forum name* @param TableNode $table*/public function i_reply_post_from_forum_with($postsubject, $forumname, TableNode $table) {// Navigate to forum.$this->goto_main_post_reply($postsubject);// Fill form and post.$this->execute('behat_forms::i_set_the_following_fields_to_these_values', $table);$this->execute('behat_forms::press_button', get_string('posttoforum', 'forum'));$this->execute('behat_general::i_wait_to_be_redirected');}/*** Inpage Reply - adds a reply to the specified post of the specified forum. The step begins from the forum's page or from the forum's course page.** @Given /^I reply "(?P<post_subject_string>(?:[^"]|\\")*)" post from "(?P<forum_name_string>(?:[^"]|\\")*)" forum using an inpage reply with:$/* @param string $postsubject The subject of the post* @param string $forumname The forum name* @param TableNode $table*/public function i_reply_post_from_forum_using_an_inpage_reply_with($postsubject, $forumname, TableNode $table) {// Navigate to forum.$this->execute('behat_navigation::i_am_on_page_instance', [$this->escape($forumname), 'forum activity']);$this->execute('behat_general::click_link', $this->escape($postsubject));$this->execute('behat_general::click_link', get_string('reply', 'forum'));// Fill form and post.$this->execute('behat_forms::i_set_the_following_fields_to_these_values', $table);$this->execute('behat_forms::press_button', get_string('posttoforum', 'mod_forum'));}/*** Navigates to a particular discussion page** @Given /^I navigate to post "(?P<post_subject_string>(?:[^"]|\\")*)" in "(?P<forum_name_string>(?:[^"]|\\")*)" forum$/* @param string $postsubject The subject of the post* @param string $forumname The forum name*/public function i_navigate_to_post_in_forum($postsubject, $forumname) {// Navigate to forum discussion.$this->execute('behat_navigation::i_am_on_page_instance', [$this->escape($forumname), 'forum activity']);$this->execute('behat_general::click_link', $this->escape($postsubject));}/*** Opens up the action menu for the discussion** @Given /^I click on "(?P<post_subject_string>(?:[^"]|\\")*)" action menu$/* @param string $discussion The subject of the discussion*/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[contains(concat(' ', normalize-space(@class), ' '), ' discussion ') and contains(.,'$discussion')]","xpath_element"]);}/*** Creates new discussions within forums of a given course.** @Given the following forum discussions exist in course :coursename:* @param string $coursename The full name of the course where the forums exist.* @param TableNode $discussionsdata The discussion posts to be created.*/public function the_following_forum_discussions_exist(string $coursename, TableNode $discussionsdata) {global $DB;$courseid = $this->get_course_id($coursename);$forumgenerator = behat_util::get_data_generator()->get_plugin_generator('mod_forum');// Add the discussions to the relevant forum.foreach ($discussionsdata->getHash() as $discussioninfo) {$discussioninfo['course'] = $courseid;$discussioninfo['forum'] = $this->get_forum_id($courseid, $discussioninfo['forum']);$discussioninfo['userid'] = $this->get_user_id($discussioninfo['user']);// Prepare data for any attachments.if (!empty($discussioninfo['attachments']) || !empty($discussioninfo['inlineattachments'])) {$discussioninfo['attachment'] = 1;$cm = get_coursemodule_from_instance('forum', $discussioninfo['forum']);}// Prepare data for groups if needed.if (!empty($discussioninfo['group'])) {$discussioninfo['groupid'] = $this->get_group_id($courseid, $discussioninfo['group']);unset($discussioninfo['group']);}// Create the discussion post.$discussion = $forumgenerator->create_discussion($discussioninfo);$postid = $DB->get_field('forum_posts', 'id', ['discussion' => $discussion->id]);// Override the creation and modified timestamps as required.if (!empty($discussioninfo['created']) || !empty($discussioninfo['modified'])) {$discussiondata = ['id' => $discussion->id,'timemodified' => empty($discussioninfo['modified']) ? $discussioninfo['created'] : $discussioninfo['modified'],];$DB->update_record('forum_discussions', $discussiondata);$postdata = ['id' => $postid,'modified' => empty($discussioninfo['modified']) ? $discussioninfo['created'] : $discussioninfo['modified'],];if (!empty($discussioninfo['created'])) {$postdata['created'] = $discussioninfo['created'];}$DB->update_record('forum_posts', $postdata);}// Create attachments to the discussion post if required.if (!empty($discussioninfo['attachments'])) {$attachments = array_map('trim', explode(',', $discussioninfo['attachments']));$this->create_post_attachments($postid, $discussioninfo['userid'], $attachments, $cm, 'attachment');}// Create inline attachments to the discussion post if required.if (!empty($discussioninfo['inlineattachments'])) {$inlineattachments = array_map('trim', explode(',', $discussioninfo['inlineattachments']));$this->create_post_attachments($postid, $discussioninfo['userid'], $inlineattachments, $cm, 'post');}}}/*** Creates replies to discussions within forums of a given course.** @Given the following forum replies exist in course :coursename:* @param string $coursename The full name of the course where the forums exist.* @param TableNode $repliesdata The reply posts to be created.*/public function the_following_forum_replies_exist(string $coursename, TableNode $repliesdata) {global $DB;$courseid = $this->get_course_id($coursename);$forumgenerator = behat_util::get_data_generator()->get_plugin_generator('mod_forum');// Add the replies to the relevant discussions.foreach ($repliesdata->getHash() as $replyinfo) {$replyinfo['course'] = $courseid;$replyinfo['forum'] = $this->get_forum_id($courseid, $replyinfo['forum']);$replyinfo['userid'] = $this->get_user_id($replyinfo['user']);['discussionid' => $replyinfo['discussion'],'parentid' => $replyinfo['parent'],] = $this->get_base_discussion($replyinfo['forum'], $replyinfo['discussion']);// Prepare data for any attachments.if (!empty($replyinfo['attachments']) || !empty($replyinfo['inlineattachments'])) {$replyinfo['attachment'] = 1;$cm = get_coursemodule_from_instance('forum', $replyinfo['forum']);}// Get the user id of the user to whom the reply is private.if (!empty($replyinfo['privatereplyto'])) {$replyinfo['privatereplyto'] = $this->get_user_id($replyinfo['privatereplyto']);}// Create the reply post.$reply = $forumgenerator->create_post($replyinfo);// Create attachments to the post if required.if (!empty($replyinfo['attachments'])) {$attachments = array_map('trim', explode(',', $replyinfo['attachments']));$this->create_post_attachments($reply->id, $replyinfo['userid'], $attachments, $cm, 'attachment');}// Create inline attachments to the post if required.if (!empty($replyinfo['inlineattachments'])) {$inlineattachments = array_map('trim', explode(',', $replyinfo['inlineattachments']));$this->create_post_attachments($reply->id, $replyinfo['userid'], $inlineattachments, $cm, 'post');}}}/*** Checks if the user can subscribe to the forum.** @Given /^I can subscribe to this forum$/*/public function i_can_subscribe_to_this_forum() {$this->execute('behat_general::assert_page_contains_text', [get_string('subscribe', 'mod_forum')]);}/*** Checks if the user can unsubscribe from the forum.** @Given /^I can unsubscribe from this forum$/*/public function i_can_unsubscribe_from_this_forum() {$this->execute('behat_general::assert_page_contains_text', [get_string('unsubscribe', 'mod_forum')]);}/*** Subscribes to the forum.** @Given /^I subscribe to this forum$/*/public function i_subscribe_to_this_forum() {$this->execute('behat_general::click_link', [get_string('subscribe', 'mod_forum')]);}/*** Unsubscribes from the forum.** @Given /^I unsubscribe from this forum$/*/public function i_unsubscribe_from_this_forum() {$this->execute('behat_general::click_link', [get_string('unsubscribe', 'mod_forum')]);}/*** Fetch user ID from its username.** @param string $username The username.* @return int The user ID.* @throws Exception*/protected function get_user_id($username) {global $DB;if (!$userid = $DB->get_field('user', 'id', ['username' => $username])) {throw new Exception("A user with username '{$username}' does not exist");}return $userid;}/*** Fetch course ID using course name.** @param string $coursename The name of the course.* @return int The course ID.* @throws Exception*/protected function get_course_id(string $coursename): int {global $DB;if (!$courseid = $DB->get_field('course', 'id', ['fullname' => $coursename])) {throw new Exception("A course with name '{$coursename}' does not exist");}return $courseid;}/*** Fetch forum ID using forum name.** @param int $courseid The course ID the forum exists within.* @param string $forumname The name of the forum.* @return int The forum ID.* @throws Exception*/protected function get_forum_id(int $courseid, string $forumname): int {global $DB;$conditions = ['course' => $courseid,'name' => $forumname,];if (!$forumid = $DB->get_field('forum', 'id', $conditions)) {throw new Exception("A forum with name '{$forumname}' does not exist in the provided course");}return $forumid;}/*** Fetch Group ID using group name.** @param int $courseid The course ID the forum exists within.* @param string $groupname The short name of the group.* @return int The group ID.* @throws Exception*/protected function get_group_id(int $courseid, string $groupname): int {global $DB;if ($groupname === 'All participants') {return -1;}$conditions = ['courseid' => $courseid,'idnumber' => $groupname,];if (!$groupid = $DB->get_field('groups', 'id', $conditions)) {throw new Exception("A group with name '{$groupname}' does not exist in the provided course");}return $groupid;}/*** Fetch discussion ID and first post ID by discussion name.** @param int $forumid The forum ID where the discussion resides.* @param string $name The name of the discussion.* @return array The discussion ID and first post ID.* @throws dml_exception If the discussion name is not unique within the forum (or doesn't exist).*/protected function get_base_discussion(int $forumid, string $name): array {global $DB;$conditions = ['name' => $name,'forum' => $forumid,];$result = $DB->get_record("forum_discussions", $conditions, 'id, firstpost', MUST_EXIST);return ['discussionid' => $result->id,'parentid' => $result->firstpost,];}/*** Create one or more attached or inline attachments to a forum post.** @param int $postid The ID of the forum post.* @param int $userid The user ID creating the attachment.* @param array $attachmentnames Names of all attachments to be created.* @param stdClass $cm The context module of the forum.* @param string $filearea The file area being written to, eg 'attachment' or 'post' (inline).*/protected function create_post_attachments(int $postid, int $userid, array $attachmentnames, stdClass $cm, string $filearea): void {$filestorage = get_file_storage();foreach ($attachmentnames as $attachmentname) {$filestorage->create_file_from_string(['contextid' => context_module::instance($cm->id)->id,'component' => 'mod_forum','filearea' => $filearea,'itemid' => $postid,'filepath' => '/','filename' => $attachmentname,'userid' => $userid,],"File content {$attachmentname}");}}/*** Returns the steps list to add a new discussion to a forum.** Abstracts add a new topic and add a new discussion, as depending* on the forum type the button string changes.** @param string $forumname* @param TableNode $table* @param string $buttonstr*/protected function add_new_discussion($forumname, TableNode $table, $buttonstr) {// Navigate to forum.$this->execute('behat_navigation::i_am_on_page_instance', [$this->escape($forumname), 'forum activity']);$this->execute('behat_general::click_link', $buttonstr);$this->execute('behat_forms::press_button', get_string('showadvancededitor'));$this->fill_new_discussion_form($table);}/*** Returns the steps list to add a new discussion to a forum inline.** Abstracts add a new topic and add a new discussion, as depending* on the forum type the button string changes.** @param string $forumname* @param TableNode $table* @param string $buttonstr*/protected function add_new_discussion_inline($forumname, TableNode $table, $buttonstr) {// Navigate to forum.$this->execute('behat_navigation::i_am_on_page_instance', [$this->escape($forumname), 'forum activity']);$this->execute('behat_general::click_link', $buttonstr);$this->fill_new_discussion_form($table);}/*** Fill in the forum's post form and submit. It assumes you've already navigated and enabled the form for view.** @param TableNode $table* @throws coding_exception*/protected function fill_new_discussion_form(TableNode $table) {// Fill form and post.$this->execute('behat_forms::i_set_the_following_fields_to_these_values', $table);$this->execute('behat_forms::press_button', get_string('posttoforum', 'forum'));$this->execute('behat_general::i_wait_to_be_redirected');}/*** Go to the default reply to post page.* This is used instead of navigating through 4-5 different steps and to solve issues where JS would be required to click* on the advanced button** @param $postsubject* @throws coding_exception* @throws dml_exception* @throws moodle_exception*/protected function goto_main_post_reply($postsubject) {global $DB;$post = $DB->get_record("forum_posts", array("subject" => $postsubject), 'id', MUST_EXIST);$url = new moodle_url('/mod/forum/post.php', ['reply' => $post->id]);$this->execute('behat_general::i_visit', [$url]);}}