Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace availability_date;
18
 
19
use core_availability\tree;
20
 
21
/**
22
 * Unit tests for the date condition.
23
 *
24
 * @package availability_date
25
 * @copyright 2014 The Open University
26
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
27
 */
1441 ariadna 28
final class condition_test extends \advanced_testcase {
1 efrain 29
    /**
30
     * Load required classes.
31
     */
32
    public function setUp(): void {
33
        // Load the mock info class so that it can be used.
34
        global $CFG;
35
        require_once($CFG->dirroot . '/availability/tests/fixtures/mock_info.php');
1441 ariadna 36
        parent::setUp();
1 efrain 37
    }
38
 
39
    /**
40
     * Tests constructing and using date condition as part of tree.
41
     */
11 efrain 42
    public function test_in_tree(): void {
1 efrain 43
        global $SITE, $USER, $CFG;
44
        $this->resetAfterTest();
45
        $this->setAdminUser();
46
 
47
        // Set server timezone for test. (Important as otherwise the timezone
48
        // could be anything - this is modified by other unit tests, too.)
49
        $this->setTimezone('UTC');
50
 
51
        // SEt user to GMT+5.
52
        $USER->timezone = 5;
53
 
54
        // Construct tree with date condition.
55
        $time = strtotime('2014-02-18 14:20:00 GMT');
56
        $structure = (object)array('op' => '|', 'show' => true, 'c' => array(
57
                (object)array('type' => 'date', 'd' => '>=', 't' => $time)));
58
        $tree = new \core_availability\tree($structure);
59
        $info = new \core_availability\mock_info();
60
 
61
        // Check if available (when not available).
62
        condition::set_current_time_for_test($time - 1);
63
        $information = '';
64
        $result = $tree->check_available(false, $info, true, $USER->id);
65
        $this->assertFalse($result->is_available());
66
        $information = $tree->get_result_information($info, $result);
67
 
68
        // Note: PM is normally upper-case, but an issue with PHP on Mac means
69
        // that on that platform, it is reported lower-case.
70
        $this->assertMatchesRegularExpression('~from.*18 February 2014, 7:20 (PM|pm)~', $information);
71
 
72
        // Check if available (when available).
73
        condition::set_current_time_for_test($time);
74
        $result = $tree->check_available(false, $info, true, $USER->id);
75
        $this->assertTrue($result->is_available());
76
        $information = $tree->get_result_information($info, $result);
77
        $this->assertEquals('', $information);
78
    }
79
 
80
    /**
81
     * Tests the constructor including error conditions. Also tests the
82
     * string conversion feature (intended for debugging only).
83
     */
11 efrain 84
    public function test_constructor(): void {
1 efrain 85
        // No parameters.
86
        $structure = (object)array();
87
        try {
88
            $date = new condition($structure);
89
            $this->fail();
90
        } catch (\coding_exception $e) {
91
            $this->assertStringContainsString('Missing or invalid ->d', $e->getMessage());
92
        }
93
 
94
        // Invalid ->d.
95
        $structure->d = 'woo hah!!';
96
        try {
97
            $date = new condition($structure);
98
            $this->fail();
99
        } catch (\coding_exception $e) {
100
            $this->assertStringContainsString('Missing or invalid ->d', $e->getMessage());
101
        }
102
 
103
        // Missing ->t.
104
        $structure->d = '>=';
105
        try {
106
            $date = new condition($structure);
107
            $this->fail();
108
        } catch (\coding_exception $e) {
109
            $this->assertStringContainsString('Missing or invalid ->t', $e->getMessage());
110
        }
111
 
112
        // Invalid ->t.
113
        $structure->t = 'got you all in check';
114
        try {
115
            $date = new condition($structure);
116
            $this->fail();
117
        } catch (\coding_exception $e) {
118
            $this->assertStringContainsString('Missing or invalid ->t', $e->getMessage());
119
        }
120
 
121
        // Valid conditions of both types.
122
        $structure = (object)array('d' => '>=', 't' => strtotime('2014-02-18 14:43:17 GMT'));
123
        $date = new condition($structure);
124
        $this->assertEquals('{date:>= 2014-02-18 14:43:17}', (string)$date);
125
        $structure->d = '<';
126
        $date = new condition($structure);
127
        $this->assertEquals('{date:< 2014-02-18 14:43:17}', (string)$date);
128
    }
129
 
130
    /**
131
     * Tests the save() function.
132
     */
11 efrain 133
    public function test_save(): void {
1 efrain 134
        $structure = (object)array('d' => '>=', 't' => 12345);
135
        $cond = new condition($structure);
136
        $structure->type = 'date';
137
        $this->assertEquals($structure, $cond->save());
138
    }
139
 
140
    /**
141
     * Tests the is_available() and is_available_to_all() functions.
142
     */
11 efrain 143
    public function test_is_available(): void {
1 efrain 144
        global $SITE, $USER;
145
 
146
        $time = strtotime('2014-02-18 14:50:10 GMT');
147
        $info = new \core_availability\mock_info();
148
 
149
        // Test with >=.
150
        $date = new condition((object)array('d' => '>=', 't' => $time));
151
        condition::set_current_time_for_test($time - 1);
152
        $this->assertFalse($date->is_available(false, $info, true, $USER->id));
153
        condition::set_current_time_for_test($time);
154
        $this->assertTrue($date->is_available(false, $info, true, $USER->id));
155
 
156
        // Test with <.
157
        $date = new condition((object)array('d' => '<', 't' => $time));
158
        condition::set_current_time_for_test($time);
159
        $this->assertFalse($date->is_available(false, $info, true, $USER->id));
160
        condition::set_current_time_for_test($time - 1);
161
        $this->assertTrue($date->is_available(false, $info, true, $USER->id));
162
 
163
        // Repeat this test with is_available_to_all() - it should be the same.
164
        $date = new condition((object)array('d' => '<', 't' => $time));
165
        condition::set_current_time_for_test($time);
166
        $this->assertFalse($date->is_available_for_all(false));
167
        condition::set_current_time_for_test($time - 1);
168
        $this->assertTrue($date->is_available_for_all(false));
169
    }
170
 
171
    /**
172
     * Tests the get_description and get_standalone_description functions.
173
     */
11 efrain 174
    public function test_get_description(): void {
1 efrain 175
        global $SITE, $CFG;
176
 
177
        $this->resetAfterTest();
178
        $this->setTimezone('UTC');
179
 
180
        $modinfo = get_fast_modinfo($SITE);
181
        $info = new \core_availability\mock_info();
182
        $time = strtotime('2014-02-18 14:55:01 GMT');
183
 
184
        // Test with >=.
185
        $date = new condition((object)array('d' => '>=', 't' => $time));
186
        $information = $date->get_description(true, false, $info);
187
        $this->assertMatchesRegularExpression('~after.*18 February 2014, 2:55 (PM|pm)~', $information);
188
        $information = $date->get_description(true, true, $info);
189
        $this->assertMatchesRegularExpression('~before.*18 February 2014, 2:55 (PM|pm)~', $information);
190
        $information = $date->get_standalone_description(true, false, $info);
191
        $this->assertMatchesRegularExpression('~from.*18 February 2014, 2:55 (PM|pm)~', $information);
192
        $information = $date->get_standalone_description(true, true, $info);
193
        $this->assertMatchesRegularExpression('~until.*18 February 2014, 2:55 (PM|pm)~', $information);
194
 
195
        // Test with <.
196
        $date = new condition((object)array('d' => '<', 't' => $time));
197
        $information = $date->get_description(true, false, $info);
198
        $this->assertMatchesRegularExpression('~before.*18 February 2014, 2:55 (PM|pm)~', $information);
199
        $information = $date->get_description(true, true, $info);
200
        $this->assertMatchesRegularExpression('~after.*18 February 2014, 2:55 (PM|pm)~', $information);
201
        $information = $date->get_standalone_description(true, false, $info);
202
        $this->assertMatchesRegularExpression('~until.*18 February 2014, 2:55 (PM|pm)~', $information);
203
        $information = $date->get_standalone_description(true, true, $info);
204
        $this->assertMatchesRegularExpression('~from.*18 February 2014, 2:55 (PM|pm)~', $information);
205
 
206
        // Test special case for dates that are midnight.
207
        $date = new condition((object)array('d' => '>=',
208
                't' => strtotime('2014-03-05 00:00 GMT')));
209
        $information = $date->get_description(true, false, $info);
210
        $this->assertMatchesRegularExpression('~on or after.*5 March 2014([^0-9]*)$~', $information);
211
        $information = $date->get_description(true, true, $info);
212
        $this->assertMatchesRegularExpression('~before.*end of.*4 March 2014([^0-9]*)$~', $information);
213
        $information = $date->get_standalone_description(true, false, $info);
214
        $this->assertMatchesRegularExpression('~from.*5 March 2014([^0-9]*)$~', $information);
215
        $information = $date->get_standalone_description(true, true, $info);
216
        $this->assertMatchesRegularExpression('~until end of.*4 March 2014([^0-9]*)$~', $information);
217
 
218
        // In the 'until' case for midnight, it shows the previous day. (I.e.
219
        // if the date is 5 March 00:00, then we show it as available until 4
220
        // March, implying 'the end of'.)
221
        $date = new condition((object)array('d' => '<',
222
                't' => strtotime('2014-03-05 00:00 GMT')));
223
        $information = $date->get_description(true, false, $info);
224
        $this->assertMatchesRegularExpression('~before end of.*4 March 2014([^0-9]*)$~', $information);
225
        $information = $date->get_description(true, true, $info);
226
        $this->assertMatchesRegularExpression('~on or after.*5 March 2014([^0-9]*)$~', $information);
227
        $information = $date->get_standalone_description(true, false, $info);
228
        $this->assertMatchesRegularExpression('~until end of.*4 March 2014([^0-9]*)$~', $information);
229
        $information = $date->get_standalone_description(true, true, $info);
230
        $this->assertMatchesRegularExpression('~from.*5 March 2014([^0-9]*)$~', $information);
231
    }
232
 
233
    /**
234
     * Tests the update_all_dates function.
235
     */
11 efrain 236
    public function test_update_all_dates(): void {
1 efrain 237
        global $DB;
238
        $this->resetAfterTest();
239
 
240
        // Create a course with 3 pages.
241
        $generator = $this->getDataGenerator();
242
        $course = $generator->create_course();
243
        $rec = array('course' => $course);
244
        $page1 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
245
        $page2 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
246
        $page3 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
247
 
248
        // Set the availability page 2 to a simple date condition. You can access
249
        // it from 1337 onwards.
250
        $simplecondition = tree::get_root_json(array(
251
                condition::get_json(condition::DIRECTION_FROM, 1337)));
252
        $DB->set_field('course_modules', 'availability',
253
                json_encode($simplecondition), array('id' => $page2->cmid));
254
 
255
        // Set page 3 to a complex set of conditions including a nested date condition.
256
        // You can access it until 1459, *or* after 2810 if you belong to a group.
257
        $complexcondition = tree::get_root_json(array(
258
                condition::get_json(condition::DIRECTION_UNTIL, 1459),
259
                tree::get_nested_json(array(
260
                    condition::get_json(condition::DIRECTION_FROM, 2810),
261
                    \availability_group\condition::get_json()))),
262
                tree::OP_OR);
263
        $DB->set_field('course_modules', 'availability',
264
                json_encode($complexcondition), array('id' => $page3->cmid));
265
 
266
        // Now use the update_all_dates function to move date forward 100000.
267
        condition::update_all_dates($course->id, 100000);
268
 
269
        // Get the expected conditions after adjusting time, and compare to database.
270
        $simplecondition->c[0]->t = 101337;
271
        $complexcondition->c[0]->t = 101459;
272
        $complexcondition->c[1]->c[0]->t = 102810;
273
        $this->assertEquals($simplecondition, json_decode(
274
                $DB->get_field('course_modules', 'availability', array('id' => $page2->cmid))));
275
        $this->assertEquals($complexcondition, json_decode(
276
                $DB->get_field('course_modules', 'availability', array('id' => $page3->cmid))));
277
 
278
        // The one without availability conditions should still be null.
279
        $this->assertNull($DB->get_field('course_modules', 'availability', array('id' => $page1->cmid)));
280
    }
281
}