diff --git a/classes/question/file.php b/classes/question/file.php index 023433c1..baaa546b 100644 --- a/classes/question/file.php +++ b/classes/question/file.php @@ -90,21 +90,19 @@ protected function question_survey_display($formdata, $descendantsdata, $blankqu // Filemanager form element implementation is far from optimal, we need to rework this if we ever fix it... require_once("$CFG->dirroot/lib/form/filemanager.php"); - $fmoptions = array_merge( - $options, - [ - 'client_id' => uniqid(), - 'itemid' => $draftitemid, - 'target' => $this->id, - 'name' => $elname - ] - ); - $fm = new form_filemanager((object) $fmoptions); + $options->client_id = uniqid(); + $options->itemid = $draftitemid; + $options->target = $this->id; + $options->name = $elname; + $fm = new form_filemanager($options); $output = $PAGE->get_renderer('core', 'files'); - $html = $output->render($fm); + $html = '
' . + $output->render($fm) . + '
'; - $html .= ''; +/* $html .= ''; $html .= ''; +*/ return $html; } @@ -115,12 +113,12 @@ protected function question_survey_display($formdata, $descendantsdata, $blankqu * @return array */ public static function get_file_manager_option() { - return [ - 'mainfile' => '', - 'subdirs' => false, - 'accepted_types' => array('image', '.pdf'), - 'maxfiles' => 1, - ]; + $options = new \stdClass(); + $options->mainfile = ''; + $options->subdirs = false; + $options->accepted_types = ['image', '.pdf']; + $options->maxfiles = 1; + return $options; } /** diff --git a/tests/behat/behat_mod_questionnaire.php b/tests/behat/behat_mod_questionnaire.php index bdd5b68e..a91879ca 100644 --- a/tests/behat/behat_mod_questionnaire.php +++ b/tests/behat/behat_mod_questionnaire.php @@ -30,7 +30,6 @@ use Behat\Behat\Context\Step\Given as Given, Behat\Behat\Context\Step\When as When, Behat\Gherkin\Node\TableNode as TableNode, - Behat\Mink\Exception\ExpectationException as ExpectationException, Behat\Mink\Element\NodeElement, Behat\Mink\Exception\DriverException, Behat\Gherkin\Node\PyStringNode as PyStringNode, @@ -475,45 +474,57 @@ protected function get_cm_by_questionnaire_name(string $name): stdClass { * * The paths should be relative to moodle codebase. * - * @When /^I upload "(?P(?:[^"]|\\")*)" to questionnaire filemanager$/ + * @When /^I upload "(?P(?:[^"]|\\")*)" to questionnaire "(?P(?:[^"]|\\")*)" filemanager$/ * @param string $filepath + * @param string $question */ - public function i_upload_file_to_questionnaire_filemanager($filepath) { - $this->upload_file_to_filemanager_questionnaire($filepath, new TableNode(array())); + public function i_upload_file_to_questionnaire_question_filemanager($filepath, $question) { + $this->upload_file_to_question_filemanager_questionnaire($filepath, $question, new TableNode([]), false); } /** - * Try to get the filemanager node. + * Try to get the filemanager node of a given question. * - * @return NodeElement + * @param $question + * @return \Behat\Mink\Element\NodeElement|null */ - protected function get_filemanager() { + protected function get_filepicker_node($question) { + // More info about the problem (in case there is a problem). + $exception = new ExpectationException('The filepicker for the question with text "' . $question . + '" can not be found', $this->getSession()); - // If no file picker label is mentioned take the first file picker from the page. - return $this->find( + $filepickercontainer = $this->find( 'xpath', - '//div[contains(concat(" ", normalize-space(@class), " "), " filemanager ")]' + "//p[contains(.,'" . $question . "')]" . + "//parent::div[contains(concat(' ', normalize-space(@class), ' '), ' no-overflow ')]" . + "//parent::div[contains(concat(' ', normalize-space(@class), ' '), ' qn-question ')]" . + "//following::div[contains(concat(' ', normalize-space(@class), ' '), ' qn-answer ')]" . + "//descendant::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']", + $exception ); + + return $filepickercontainer; } /** * Uploads a file to filemanager * * @param string $filepath Normally a path relative to $CFG->dirroot, but can be an absolute path too. + * @param string $question A question text. * @param TableNode $data Data to fill in upload form * @param false|string $overwriteaction false if we don't expect that file with the same name already exists, * or button text in overwrite dialogue ("Overwrite", "Rename to ...", "Cancel") * @throws DriverException * @throws ExpectationException Thrown by behat_base::find */ - protected function upload_file_to_filemanager_questionnaire($filepath, TableNode $data, $overwriteaction = false) { + protected function upload_file_to_question_filemanager_questionnaire($filepath, $question, TableNode $data, $overwriteaction = false) { global $CFG; if (!$this->has_tag('_file_upload')) { throw new DriverException('File upload tests must have the @_file_upload tag on either the scenario or feature.'); } - $filemanagernode = $this->get_filemanager(); + $filemanagernode = $this->get_filepicker_node($question); // Opening the select repository window and selecting the upload repository. $this->open_add_file_window($filemanagernode, get_string('pluginname', 'repository_upload')); @@ -580,40 +591,6 @@ protected function upload_file_to_filemanager_questionnaire($filepath, TableNode } - /** - * Try to get the filemanager node specified by the element - * - * @param string $filepickerelement - * @return NodeElement - * @throws ExpectationException - */ - protected function get_filepicker_node($filepickerelement) { - - // More info about the problem (in case there is a problem). - $exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession()); - - // If no file picker label is mentioned take the first file picker from the page. - if (empty($filepickerelement)) { - $filepickercontainer = $this->find( - 'xpath', - "//*[@class=\"form-filemanager\"]", - $exception - ); - } else { - // Gets the filemanager node specified by the locator which contains the filepicker container - // either for filepickers created by mform or by admin config. - $filepickerelement = behat_context_helper::escape($filepickerelement); - $filepickercontainer = $this->find( - 'xpath', - "//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" . - "//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']", - $exception - ); - } - - return $filepickercontainer; - } - /** * Opens the filepicker modal window and selects the repository. * diff --git a/tests/behat/file_question.feature b/tests/behat/file_question.feature index 07573a7f..855d8350 100644 --- a/tests/behat/file_question.feature +++ b/tests/behat/file_question.feature @@ -22,7 +22,7 @@ Feature: Add a question requiring a file upload in questionnaire. | questionnaire | Test questionnaire | Test questionnaire description | C1 | questionnaire0 | 1 | 1 | @javascript @_file_upload - Scenario: As a teacher, I create a questionnaire in my course with a file question and a student answers to it. Then the file has to be accessible. + Scenario: Add a single file question to a questionnaire and view an answer with an uploaded file. Given I log in as "teacher1" When I am on the "Test questionnaire" "questionnaire activity" page And I navigate to "Questions" in current page administration @@ -35,7 +35,7 @@ Feature: Add a question requiring a file upload in questionnaire. And I log in as "student1" And I am on the "Test questionnaire" "questionnaire activity" page And I navigate to "Answer the questions..." in current page administration - And I upload "mod/questionnaire/tests/fixtures/testfilequestion.pdf" to questionnaire filemanager + And I upload "mod/questionnaire/tests/fixtures/testfilequestion.pdf" to questionnaire "Add a file as an answer" filemanager And I press "Submit questionnaire" And I should see "Thank you for completing this Questionnaire" And I press "Continue" diff --git a/tests/fixtures/testfilequestion2.pdf b/tests/fixtures/testfilequestion2.pdf new file mode 100644 index 00000000..90588c30 Binary files /dev/null and b/tests/fixtures/testfilequestion2.pdf differ