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