Skip to content

Commit a21daff

Browse files
added behat test to make sure we can retrieve student's answers to a file question
1 parent cedfd38 commit a21daff

File tree

3 files changed

+246
-0
lines changed

3 files changed

+246
-0
lines changed

tests/behat/behat_mod_questionnaire.php

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,4 +389,200 @@ private function add_data(array $data, $datatable, $mapvar = '', array $replvars
389389
}
390390

391391
}
392+
393+
/**
394+
* Uploads a file to the specified filemanager leaving other fields in upload form default. The paths should be relative to moodle codebase.
395+
*
396+
* @When /^I upload "(?P<filepath_string>(?:[^"]|\\")*)" to questionnaire filemanager$/
397+
* @throws DriverException
398+
* @throws ExpectationException Thrown by behat_base::find
399+
* @param string $filepath
400+
*/
401+
public function i_upload_file_to_questionnaire_filemanager($filepath) {
402+
$this->upload_file_to_filemanager_questionnaire($filepath, new TableNode(array()));
403+
}
404+
405+
/**
406+
* Try to get the filemanager node specified by the element
407+
*
408+
* @param string $filepickerelement
409+
* @return \Behat\Mink\Element\NodeElement
410+
* @throws ExpectationException
411+
*/
412+
protected function get_filemanager() {
413+
414+
// If no file picker label is mentioned take the first file picker from the page.
415+
return $this->find(
416+
'xpath',
417+
'//div[contains(concat(" ", normalize-space(@class), " "), " filemanager ")]'
418+
);
419+
}
420+
421+
/**
422+
* Uploads a file to filemanager
423+
*
424+
* @throws DriverException
425+
* @throws ExpectationException Thrown by behat_base::find
426+
* @param string $filepath Normally a path relative to $CFG->dirroot, but can be an absolute path too.
427+
* @param string $filemanagerelement
428+
* @param TableNode $data Data to fill in upload form
429+
* @param false|string $overwriteaction false if we don't expect that file with the same name already exists,
430+
* or button text in overwrite dialogue ("Overwrite", "Rename to ...", "Cancel")
431+
*/
432+
protected function upload_file_to_filemanager_questionnaire($filepath, TableNode $data, $overwriteaction = false) {
433+
global $CFG;
434+
435+
if (!$this->has_tag('_file_upload')) {
436+
throw new DriverException('File upload tests must have the @_file_upload tag on either the scenario or feature.');
437+
}
438+
439+
$filemanagernode = $this->get_filemanager();
440+
441+
// Opening the select repository window and selecting the upload repository.
442+
$this->open_add_file_window($filemanagernode, get_string('pluginname', 'repository_upload'));
443+
444+
// Ensure all the form is ready.
445+
$noformexception = new ExpectationException('The upload file form is not ready', $this->getSession());
446+
$this->find(
447+
'xpath',
448+
"//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" .
449+
"[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" .
450+
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
451+
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
452+
"/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" .
453+
"/descendant::form",
454+
$noformexception
455+
);
456+
// After this we have the elements we want to interact with.
457+
458+
// Form elements to interact with.
459+
$file = $this->find_file('repo_upload_file');
460+
461+
// Attaching specified file to the node.
462+
// Replace 'admin/' if it is in start of path with $CFG->admin .
463+
if (substr($filepath, 0, 6) === 'admin/') {
464+
$filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $CFG->admin .
465+
DIRECTORY_SEPARATOR . substr($filepath, 6);
466+
}
467+
$filepath = str_replace('/', DIRECTORY_SEPARATOR, $filepath);
468+
if (!is_readable($filepath)) {
469+
$filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $filepath;
470+
if (!is_readable($filepath)) {
471+
throw new ExpectationException('The file to be uploaded does not exist.', $this->getSession());
472+
}
473+
}
474+
$file->attachFile($filepath);
475+
476+
// Fill the form in Upload window.
477+
$datahash = $data->getRowsHash();
478+
479+
// The action depends on the field type.
480+
foreach ($datahash as $locator => $value) {
481+
482+
$field = behat_field_manager::get_form_field_from_label($locator, $this);
483+
484+
// Delegates to the field class.
485+
$field->set_value($value);
486+
}
487+
488+
// Submit the file.
489+
$submit = $this->find_button(get_string('upload', 'repository'));
490+
$submit->press();
491+
492+
// We wait for all the JS to finish as it is performing an action.
493+
$this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);
494+
495+
if ($overwriteaction !== false) {
496+
$overwritebutton = $this->find_button($overwriteaction);
497+
$this->ensure_node_is_visible($overwritebutton);
498+
$overwritebutton->click();
499+
500+
// We wait for all the JS to finish.
501+
$this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);
502+
}
503+
504+
}
505+
506+
/**
507+
* Try to get the filemanager node specified by the element
508+
*
509+
* @param string $filepickerelement
510+
* @return \Behat\Mink\Element\NodeElement
511+
* @throws ExpectationException
512+
*/
513+
protected function get_filepicker_node($filepickerelement) {
514+
515+
// More info about the problem (in case there is a problem).
516+
$exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession());
517+
518+
// If no file picker label is mentioned take the first file picker from the page.
519+
if (empty($filepickerelement)) {
520+
$filepickercontainer = $this->find(
521+
'xpath',
522+
"//*[@class=\"form-filemanager\"]",
523+
$exception
524+
);
525+
} else {
526+
// Gets the filemanager node specified by the locator which contains the filepicker container
527+
// either for filepickers created by mform or by admin config.
528+
$filepickerelement = behat_context_helper::escape($filepickerelement);
529+
$filepickercontainer = $this->find(
530+
'xpath',
531+
"//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" .
532+
"//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
533+
$exception
534+
);
535+
}
536+
537+
return $filepickercontainer;
538+
}
539+
/**
540+
* Opens the filepicker modal window and selects the repository.
541+
*
542+
* @throws ExpectationException Thrown by behat_base::find
543+
* @param NodeElement $filemanagernode The filemanager or filepicker form element DOM node.
544+
* @param mixed $repositoryname The repo name.
545+
* @return void
546+
*/
547+
protected function open_add_file_window($filemanagernode, $repositoryname) {
548+
$exception = new ExpectationException('No files can be added to the specified filemanager', $this->getSession());
549+
550+
// We should deal with single-file and multiple-file filemanagers,
551+
// catching the exception thrown by behat_base::find() in case is not multiple
552+
$this->execute('behat_general::i_click_on_in_the', [
553+
'div.fp-btn-add a, input.fp-btn-choose', 'css_element',
554+
$filemanagernode, 'NodeElement'
555+
]);
556+
557+
// Wait for the default repository (if any) to load. This checks that
558+
// the relevant div exists and that it does not include the loading image.
559+
$this->ensure_element_exists(
560+
"//div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
561+
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
562+
"[not(descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content-loading ')])]",
563+
'xpath_element');
564+
565+
// Getting the repository link and opening it.
566+
$repoexception = new ExpectationException('The "' . $repositoryname . '" repository has not been found', $this->getSession());
567+
568+
// Avoid problems with both double and single quotes in the same string.
569+
$repositoryname = behat_context_helper::escape($repositoryname);
570+
571+
// Here we don't need to look inside the selected element because there can only be one modal window.
572+
$repositorylink = $this->find(
573+
'xpath',
574+
"//div[contains(concat(' ', normalize-space(@class), ' '), ' fp-repo-area ')]" .
575+
"//descendant::span[contains(concat(' ', normalize-space(@class), ' '), ' fp-repo-name ')]" .
576+
"[normalize-space(.)=$repositoryname]",
577+
$repoexception
578+
);
579+
580+
// Selecting the repo.
581+
$this->ensure_node_is_visible($repositorylink);
582+
if (!$repositorylink->getParent()->getParent()->hasClass('active')) {
583+
// If the repository link is active, then the repository is already loaded.
584+
// Clicking it while it's active causes issues, so only click it when it isn't (see MDL-51014).
585+
$this->execute('behat_general::i_click_on', [$repositorylink, 'NodeElement']);
586+
}
587+
}
392588
}

tests/behat/file_question.feature

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@mod @mod_questionnaire
2+
Feature: In questionnaire, we can add a question requiring a file upload.
3+
4+
@javascript @_file_upload
5+
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.
6+
Given the following "users" exist:
7+
| username | firstname | lastname | email |
8+
| teacher1 | Teacher | 1 | teacher1@example.com |
9+
| student1 | Student | 1 | student1@example.com |
10+
And the following "courses" exist:
11+
| fullname | shortname | category |
12+
| Course 1 | C1 | 0 |
13+
And the following "course enrolments" exist:
14+
| user | course | role |
15+
| teacher1 | C1 | editingteacher |
16+
| student1 | C1 | student |
17+
And the following "activities" exist:
18+
| activity | name | description | course | idnumber | resume | navigate |
19+
| questionnaire | Test questionnaire | Test questionnaire description | C1 | questionnaire0 | 1 | 1 |
20+
21+
When I log in as "teacher1"
22+
And I am on "Course 1" course homepage
23+
And I follow "Test questionnaire"
24+
And I navigate to "Questions" in current page administration
25+
Then I should see "Add questions"
26+
And I add a "File" question and I fill the form with:
27+
| Question Name | File question |
28+
| Yes | Yes |
29+
| Question Text | Add a file as an answer |
30+
And I log out
31+
32+
Given I log in as "student1"
33+
And I am on "Course 1" course homepage
34+
And I follow "Test questionnaire"
35+
And I navigate to "Answer the questions..." in current page administration
36+
When I upload "mod/questionnaire/tests/fixtures/testfilequestion.pdf" to questionnaire filemanager
37+
And I press "Submit questionnaire"
38+
Then I should see "Thank you for completing this Questionnaire."
39+
And I press "Continue"
40+
And I should see "Your response"
41+
And I log out
42+
43+
Given I log in as "teacher1"
44+
And I am on "Course 1" course homepage
45+
And I follow "Test questionnaire"
46+
When I navigate to "View All Responses" in current page administration
47+
Then I should see "testfilequestion.pdf"
48+
And I follow "student1"
49+
# Todo find how to check if the pdf viewer is there.
50+
And I log out
145 KB
Binary file not shown.

0 commit comments

Comments
 (0)