Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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   * Unit tests for forms lib.
  19   *
  20   * This file contains all unit test related to forms library.
  21   *
  22   * @package    core_form
  23   * @category   phpunit
  24   * @copyright  2009 Tim Hunt
  25   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  global $CFG;
  31  require_once($CFG->libdir . '/form/duration.php');
  32  
  33  /**
  34   * Unit tests for MoodleQuickForm_duration
  35   *
  36   * Contains test cases for testing MoodleQuickForm_duration
  37   *
  38   * @package    core_form
  39   * @category   phpunit
  40   * @copyright  2009 Tim Hunt
  41   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   */
  43  class core_form_duration_testcase extends basic_testcase {
  44  
  45      /**
  46       * Get a form that can be used for testing.
  47       *
  48       * @return MoodleQuickForm
  49       */
  50      protected function get_test_form(): MoodleQuickForm {
  51          $form = new temp_form_duration();
  52          return $form->getform();
  53      }
  54  
  55      /**
  56       * Get a form with a duration element that can be used for testing.
  57       *
  58       * @return array with two elements, a MoodleQuickForm and a MoodleQuickForm_duration.
  59       */
  60      protected function get_test_form_and_element(): array {
  61          $mform = $this->get_test_form();
  62          $element = $mform->addElement('duration', 'duration');
  63          return [$mform, $element];
  64      }
  65  
  66      /**
  67       * Test the constructor error handling.
  68       */
  69      public function test_constructor_rejects_invalid_unit(): void {
  70          // Test trying to create with an invalid unit.
  71          $mform = $this->get_test_form();
  72          $this->expectException(coding_exception::class);
  73          $mform->addElement('duration', 'testel', null, ['defaultunit' => 123, 'optional' => false]);
  74      }
  75  
  76      /**
  77       * Test constructor only some units.
  78       */
  79      public function test_constructor_limited_units(): void {
  80          $mform = $this->get_test_form();
  81          $mform->addElement('duration', 'testel', null, ['units' => [MINSECS, 1], 'optional' => false]);
  82          $html = $mform->toHtml();
  83          $html = preg_replace('~ +>~', '>', $html); // Clean HTML to avoid spurious errors.
  84          $this->assertStringContainsString('<option value="60" selected>minutes</option>', $html);
  85          $this->assertStringContainsString('<option value="1">seconds</option>', $html);
  86          $this->assertStringNotContainsString('value="3600"', $html);
  87      }
  88  
  89      /**
  90       * Testcase for testing units (seconds, minutes, hours and days)
  91       */
  92      public function test_get_units(): void {
  93          [$mform, $element] = $this->get_test_form_and_element();
  94          $units = $element->get_units();
  95          $this->assertEquals($units, [1 => get_string('seconds'), 60 => get_string('minutes'),
  96                  3600 => get_string('hours'), 86400 => get_string('days'), 604800 => get_string('weeks')]);
  97      }
  98  
  99      /**
 100       * Data provider for {@see test_seconds_to_unit()}.
 101       *
 102       * @return array test cases.
 103       */
 104      public function seconds_to_unit_cases(): array {
 105          return [
 106              [[0, MINSECS], 0], // Zero minutes, for a nice default unit.
 107              [[1, 1], 1],
 108              [[3601, 1], 3601],
 109              [[1, MINSECS], 60],
 110              [[3, MINSECS], 180],
 111              [[1, HOURSECS], 3600],
 112              [[2, HOURSECS], 7200],
 113              [[1, DAYSECS], 86400],
 114              [[25, HOURSECS], 90000],
 115          ];
 116      }
 117  
 118      /**
 119       * Testcase for testing conversion of seconds to the best possible unit.
 120       *
 121       * @dataProvider seconds_to_unit_cases
 122       * @param array $expected expected return value from seconds_to_unit
 123       * @param int $seconds value to pass to seconds_to_unit
 124       */
 125      public function test_seconds_to_unit(array $expected, int $seconds): void {
 126          [, $element] = $this->get_test_form_and_element();
 127          $this->assertEquals($expected, $element->seconds_to_unit($seconds));
 128      }
 129  
 130      /**
 131       * Testcase for testing conversion of seconds to the best possible unit with a non-default default unit.
 132       */
 133      public function test_seconds_to_unit_different_default_unit() {
 134          $mform = $this->get_test_form();
 135          $element = $mform->addElement('duration', 'testel', null,
 136                  ['defaultunit' => DAYSECS, 'optional' => false]);
 137          $this->assertEquals([0, DAYSECS], $element->seconds_to_unit(0));
 138      }
 139  
 140      /**
 141       * Data provider for {@see test_export_value()}.
 142       *
 143       * @return array test cases.
 144       */
 145      public function export_value_cases(): array {
 146          return [
 147              [10, '10', 1],
 148              [9, '9.3', 1],
 149              [10, '9.5', 1],
 150              [180, '3', MINSECS],
 151              [90, '1.5', MINSECS],
 152              [7200, '2', HOURSECS],
 153              [86400, '1', DAYSECS],
 154              [0, '0', HOURSECS],
 155              [0, '10', 1, 0, true],
 156              [20, '20', 1, 1, true],
 157              [0, '10', 1, 0, true, ''],
 158              [20, '20', 1, 1, true, ''],
 159          ];
 160      }
 161  
 162      /**
 163       * Testcase to check generated timestamp
 164       *
 165       * @dataProvider export_value_cases
 166       * @param int $expected Expected value returned by the element.
 167       * @param string $number Number entered into the element.
 168       * @param int $unit Unit selected in the element.
 169       * @param int $enabled Whether the enabled checkbox on the form was selected. (Only used if $optional is true.)
 170       * @param bool $optional Whether the element has the optional option on.
 171       * @param string|null $label The element's label.
 172       */
 173      public function test_export_value(int $expected, string $number, int $unit, int $enabled = 0,
 174              bool $optional = false, ?string $label = null): void {
 175  
 176          // Create the test element.
 177          $mform = $this->get_test_form();
 178          $el = $mform->addElement('duration', 'testel', $label, $optional ? ['optional' => true] : []);
 179  
 180          // Prepare the submitted values.
 181          $values = ['testel' => ['number' => $number, 'timeunit' => $unit]];
 182          if ($optional) {
 183              $values['testel']['enabled'] = $enabled;
 184          }
 185  
 186          // Test.
 187          $this->assertEquals(['testel' => $expected], $el->exportValue($values, true));
 188          $this->assertEquals($expected, $el->exportValue($values));
 189      }
 190  }
 191  
 192  /**
 193   * Form object to be used in test case.
 194   */
 195  class temp_form_duration extends moodleform {
 196      /**
 197       * Form definition.
 198       */
 199      public function definition() {
 200          // No definition required.
 201      }
 202  
 203      /**
 204       * Returns form reference
 205       * @return MoodleQuickForm
 206       */
 207      public function getform() {
 208          $mform = $this->_form;
 209          // Set submitted flag, to simulate submission.
 210          $mform->_flagSubmitted = true;
 211          return $mform;
 212      }
 213  }