Proyectos de Subversion Moodle

Rev

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