Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.2.x will end 22 April 2024 (12 months).
  • Bug fixes for security issues in 4.2.x will end 7 October 2024 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.1.x is supported too.
   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Steps definitions for the upload repository type.
  19   *
  20   * @package    repository_upload
  21   * @category   test
  22   * @copyright  2013 David MonllaĆ³
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  // NOTE: no MOODLE_INTERNAL test here, this file may be required by behat before including /config.php.
  27  
  28  require_once (__DIR__ . '/../../../../lib/behat/core_behat_file_helper.php');
  29  
  30  use Behat\Mink\Exception\DriverException as DriverException,
  31      Behat\Mink\Exception\ExpectationException as ExpectationException,
  32      Behat\Gherkin\Node\TableNode as TableNode;
  33  
  34  /**
  35   * Steps definitions to deal with the upload repository.
  36   *
  37   * @package    repository_upload
  38   * @category   test
  39   * @copyright  2013 David MonllaĆ³
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class behat_repository_upload extends behat_base {
  43  
  44      use core_behat_file_helper;
  45  
  46      /**
  47       * Uploads a file to the specified filemanager leaving other fields in upload form default. The paths should be relative to moodle codebase.
  48       *
  49       * @When /^I upload "(?P<filepath_string>(?:[^"]|\\")*)" file to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
  50       * @throws DriverException
  51       * @throws ExpectationException Thrown by behat_base::find
  52       * @param string $filepath
  53       * @param string $filemanagerelement
  54       */
  55      public function i_upload_file_to_filemanager($filepath, $filemanagerelement) {
  56          $this->upload_file_to_filemanager($filepath, $filemanagerelement, new TableNode(array()), false);
  57      }
  58  
  59      /**
  60       * Uploads a file to the specified filemanager leaving other fields in upload form default and confirms to overwrite an existing file. The paths should be relative to moodle codebase.
  61       *
  62       * @When /^I upload and overwrite "(?P<filepath_string>(?:[^"]|\\")*)" file to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager$/
  63       * @throws DriverException
  64       * @throws ExpectationException Thrown by behat_base::find
  65       * @param string $filepath
  66       * @param string $filemanagerelement
  67       */
  68      public function i_upload_and_overwrite_file_to_filemanager($filepath, $filemanagerelement) {
  69          $this->upload_file_to_filemanager($filepath, $filemanagerelement, new TableNode(array()),
  70                  get_string('overwrite', 'repository'));
  71      }
  72  
  73      /**
  74       * Uploads a file to the specified filemanager and confirms to overwrite an existing file. The paths should be relative to moodle codebase.
  75       *
  76       * @When /^I upload "(?P<filepath_string>(?:[^"]|\\")*)" file to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager as:$/
  77       * @throws DriverException
  78       * @throws ExpectationException Thrown by behat_base::find
  79       * @param string $filepath
  80       * @param string $filemanagerelement
  81       * @param TableNode $data Data to fill in upload form
  82       */
  83      public function i_upload_file_to_filemanager_as($filepath, $filemanagerelement, TableNode $data) {
  84          $this->upload_file_to_filemanager($filepath, $filemanagerelement, $data, false);
  85      }
  86  
  87      /**
  88       * Uploads a file to the specified filemanager. The paths should be relative to moodle codebase.
  89       *
  90       * @When /^I upload and overwrite "(?P<filepath_string>(?:[^"]|\\")*)" file to "(?P<filemanager_field_string>(?:[^"]|\\")*)" filemanager as:$/
  91       * @throws DriverException
  92       * @throws ExpectationException Thrown by behat_base::find
  93       * @param string $filepath
  94       * @param string $filemanagerelement
  95       * @param TableNode $data Data to fill in upload form
  96       */
  97      public function i_upload_and_overwrite_file_to_filemanager_as($filepath, $filemanagerelement, TableNode $data) {
  98          $this->upload_file_to_filemanager($filepath, $filemanagerelement, $data,
  99                  get_string('overwrite', 'repository'));
 100      }
 101  
 102      /**
 103       * Uploads a file to filemanager
 104       *
 105       * @throws DriverException
 106       * @throws ExpectationException Thrown by behat_base::find
 107       * @param string $filepath Normally a path relative to $CFG->dirroot, but can be an absolute path too.
 108       * @param string $filemanagerelement
 109       * @param TableNode $data Data to fill in upload form
 110       * @param false|string $overwriteaction false if we don't expect that file with the same name already exists,
 111       *     or button text in overwrite dialogue ("Overwrite", "Rename to ...", "Cancel")
 112       */
 113      protected function upload_file_to_filemanager($filepath, $filemanagerelement, TableNode $data, $overwriteaction = false) {
 114          global $CFG;
 115  
 116          if (!$this->has_tag('_file_upload')) {
 117              throw new DriverException('File upload tests must have the @_file_upload tag on either the scenario or feature.');
 118          }
 119  
 120          $filemanagernode = $this->get_filepicker_node($filemanagerelement);
 121  
 122          // Opening the select repository window and selecting the upload repository.
 123          $this->open_add_file_window($filemanagernode, get_string('pluginname', 'repository_upload'));
 124  
 125          // Ensure all the form is ready.
 126          $noformexception = new ExpectationException('The upload file form is not ready', $this->getSession());
 127          $this->find(
 128                  'xpath',
 129                  "//div[contains(concat(' ', normalize-space(@class), ' '), ' container ')]" .
 130                  "[contains(concat(' ', normalize-space(@class), ' '), ' repository_upload ')]" .
 131                  "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' file-picker ')]" .
 132                  "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-content ')]" .
 133                  "/descendant::div[contains(concat(' ', normalize-space(@class), ' '), ' fp-upload-form ')]" .
 134                  "/descendant::form",
 135                  $noformexception
 136          );
 137          // After this we have the elements we want to interact with.
 138  
 139          // Form elements to interact with.
 140          $file = $this->find_file('repo_upload_file');
 141  
 142          // Attaching specified file to the node.
 143          // Replace 'admin/' if it is in start of path with $CFG->admin .
 144          if (substr($filepath, 0, 6) === 'admin/') {
 145              $filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $CFG->admin .
 146                      DIRECTORY_SEPARATOR . substr($filepath, 6);
 147          }
 148          $filepath = str_replace('/', DIRECTORY_SEPARATOR, $filepath);
 149          if (!is_readable($filepath)) {
 150              $filepath = $CFG->dirroot . DIRECTORY_SEPARATOR . $filepath;
 151              if (!is_readable($filepath)) {
 152                  throw new ExpectationException('The file to be uploaded does not exist.', $this->getSession());
 153              }
 154          }
 155          $file->attachFile($filepath);
 156  
 157          // Fill the form in Upload window.
 158          $datahash = $data->getRowsHash();
 159  
 160          // The action depends on the field type.
 161          foreach ($datahash as $locator => $value) {
 162  
 163              $field = behat_field_manager::get_form_field_from_label($locator, $this);
 164  
 165              // Delegates to the field class.
 166              $field->set_value($value);
 167          }
 168  
 169          // Submit the file.
 170          $submit = $this->find_button(get_string('upload', 'repository'));
 171          $submit->press();
 172  
 173          // We wait for all the JS to finish as it is performing an action.
 174          $this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);
 175  
 176          if ($overwriteaction !== false) {
 177              $overwritebutton = $this->find_button($overwriteaction);
 178              $this->ensure_node_is_visible($overwritebutton);
 179              $overwritebutton->click();
 180  
 181              // We wait for all the JS to finish.
 182              $this->getSession()->wait(self::get_timeout(), self::PAGE_READY_JS);
 183          }
 184  
 185      }
 186  
 187      /**
 188       * Try to get the filemanager node specified by the element
 189       *
 190       * @param string $filepickerelement
 191       * @return \Behat\Mink\Element\NodeElement
 192       * @throws ExpectationException
 193       */
 194      protected function get_filepicker_node($filepickerelement) {
 195  
 196          // More info about the problem (in case there is a problem).
 197          $exception = new ExpectationException('"' . $filepickerelement . '" filepicker can not be found', $this->getSession());
 198  
 199          // If no file picker label is mentioned take the first file picker from the page.
 200          if (empty($filepickerelement)) {
 201              $filepickercontainer = $this->find(
 202                      'xpath',
 203                      "//*[@class=\"form-filemanager\"]",
 204                      $exception
 205              );
 206          } else {
 207              // Gets the filemanager node specified by the locator which contains the filepicker container
 208              // either for filepickers created by mform or by admin config.
 209              $filepickerelement = behat_context_helper::escape($filepickerelement);
 210              $filepickercontainer = $this->find(
 211                      'xpath',
 212                      "//input[./@id = substring-before(//p[normalize-space(.)=$filepickerelement]/@id, '_label')]" .
 213                      "//ancestor::*[@data-fieldtype = 'filemanager' or @data-fieldtype = 'filepicker']",
 214                      $exception
 215              );
 216          }
 217  
 218          return $filepickercontainer;
 219      }
 220  
 221  }