See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body