9a5a1a66090245c914f4253e3dd076249d766c1d
[moodle.git] / lib / form / tests / duration_test.php
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/>.
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  */
28 defined('MOODLE_INTERNAL') || die();
30 global $CFG;
31 require_once($CFG->libdir . '/form/duration.php');
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 {
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     }
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     }
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');
73         $mform->addElement('duration', 'testel', null, ['defaultunit' => 123, 'optional' => false]);
74     }
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->assertContains('<option value="60" selected>minutes</option>', $html);
85         $this->assertContains('<option value="1">seconds</option>', $html);
86         $this->assertNotContains('value="3600"', $html);
87     }
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     }
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     }
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     }
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     }
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             [180, '3', MINSECS],
149             [90, '1.5', MINSECS],
150             [7200, '2', HOURSECS],
151             [86400, '1', DAYSECS],
152             [0, '0', HOURSECS],
153             [0, '10', 1, 0, true],
154             [20, '20', 1, 1, true],
155             [0, '10', 1, 0, true, ''],
156             [20, '20', 1, 1, true, ''],
157         ];
158     }
160     /**
161      * Testcase to check generated timestamp
162      *
163      * @dataProvider export_value_cases
164      * @param int $expected Expected value returned by the element.
165      * @param string $number Number entered into the element.
166      * @param int $unit Unit selected in the element.
167      * @param int $enabled Whether the enabled checkbox on the form was selected. (Only used if $optional is true.)
168      * @param bool $optional Whether the element has the optional option on.
169      * @param string|null $label The element's label.
170      */
171     public function test_export_value(int $expected, string $number, int $unit, int $enabled = 0,
172             bool $optional = false, ?string $label = null): void {
174         // Create the test element.
175         $mform = $this->get_test_form();
176         $el = $mform->addElement('duration', 'testel', $label, $optional ? ['optional' => true] : []);
178         // Prepare the submitted values.
179         $values = ['testel' => ['number' => $number, 'timeunit' => $unit]];
180         if ($optional) {
181             $values['testel']['enabled'] = $enabled;
182         }
184         // Test.
185         $this->assertEquals(['testel' => $expected], $el->exportValue($values, true));
186         $this->assertEquals($expected, $el->exportValue($values));
187     }
190 /**
191  * Form object to be used in test case.
192  */
193 class temp_form_duration extends moodleform {
194     /**
195      * Form definition.
196      */
197     public function definition() {
198         // No definition required.
199     }
201     /**
202      * Returns form reference
203      * @return MoodleQuickForm
204      */
205     public function getform() {
206         $mform = $this->_form;
207         // Set submitted flag, to simulate submission.
208         $mform->_flagSubmitted = true;
209         return $mform;
210     }