Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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_grade; 18 19 /** 20 * Unit tests for the grade condition. 21 * 22 * @package availability_grade 23 * @copyright 2014 The Open University 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class condition_test extends \advanced_testcase { 27 /** 28 * Tests constructing and using grade condition. 29 */ 30 public function test_usage() { 31 global $USER, $CFG; 32 require_once($CFG->dirroot . '/mod/assign/locallib.php'); 33 34 $this->resetAfterTest(); 35 $CFG->enableavailability = true; 36 37 // Make a test course and user. 38 $course = $this->getDataGenerator()->create_course(); 39 $user = $this->getDataGenerator()->create_user(); 40 $this->getDataGenerator()->enrol_user($user->id, $course->id); 41 42 // Make assign module. 43 $assignrow = $this->getDataGenerator()->create_module('assign', array( 44 'course' => $course->id, 'name' => 'Test!')); 45 $assign = new \assign(\context_module::instance($assignrow->cmid), false, false); 46 $modinfo = get_fast_modinfo($course); 47 $cm = $modinfo->get_cm($assignrow->cmid); 48 49 $info = new \core_availability\info_module($cm); 50 51 // Get the actual grade item. 52 $item = $assign->get_grade_item(); 53 54 // Construct tree with grade condition (any grade, specified item). 55 $structure = (object)array('type' => 'grade', 'id' => (int)$item->id); 56 $cond = new condition($structure); 57 58 // Check if available (not available). 59 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 60 $information = $cond->get_description(false, false, $info); 61 $information = \core_availability\info::format_info($information, $course); 62 $this->assertMatchesRegularExpression('~have a grade.*Test!~', $information); 63 $this->assertTrue($cond->is_available(true, $info, true, $user->id)); 64 65 // Add grade and check available. 66 self::set_grade($assignrow, $user->id, 37.2); 67 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 68 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 69 $information = $cond->get_description(false, true, $info); 70 $information = \core_availability\info::format_info($information, $course); 71 $this->assertMatchesRegularExpression('~do not have a grade.*Test!~', $information); 72 73 // Construct directly and test remaining conditions; first, min grade (fail). 74 self::set_grade($assignrow, $user->id, 29.99999); 75 $structure->min = 30.0; 76 $cond = new condition($structure); 77 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 78 $information = $cond->get_description(false, false, $info); 79 $information = \core_availability\info::format_info($information, $course); 80 $this->assertMatchesRegularExpression('~achieve a required score.*Test!~', $information); 81 $this->assertTrue($cond->is_available(true, $info, true, $user->id)); 82 83 // Min grade (success). 84 self::set_grade($assignrow, $user->id, 30); 85 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 86 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 87 $information = $cond->get_description(false, true, $info); 88 $information = \core_availability\info::format_info($information, $course); 89 $this->assertMatchesRegularExpression('~do not get certain scores.*Test!~', $information); 90 91 // Max grade (fail). 92 unset($structure->min); 93 $structure->max = 30.0; 94 $cond = new condition($structure); 95 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 96 $information = $cond->get_description(false, false, $info); 97 $information = \core_availability\info::format_info($information, $course); 98 $this->assertMatchesRegularExpression('~get an appropriate score.*Test!~', $information); 99 $this->assertTrue($cond->is_available(true, $info, true, $user->id)); 100 101 // Max grade (success). 102 self::set_grade($assignrow, $user->id, 29.99999); 103 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 104 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 105 $information = $cond->get_description(false, true, $info); 106 $information = \core_availability\info::format_info($information, $course); 107 $this->assertMatchesRegularExpression('~do not get certain scores.*Test!~', $information); 108 109 // Max and min (fail). 110 $structure->min = 30.0; 111 $structure->max = 34.12345; 112 $cond = new condition($structure); 113 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 114 $information = $cond->get_description(false, false, $info); 115 $information = \core_availability\info::format_info($information, $course); 116 $this->assertMatchesRegularExpression('~get a particular score.*Test!~', $information); 117 $this->assertTrue($cond->is_available(true, $info, true, $user->id)); 118 119 // Still fail (other end). 120 self::set_grade($assignrow, $user->id, 34.12345); 121 $this->assertFalse($cond->is_available(false, $info, true, $user->id)); 122 123 // Success (top end). 124 self::set_grade($assignrow, $user->id, 34.12344); 125 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 126 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 127 $information = $cond->get_description(false, true, $info); 128 $information = \core_availability\info::format_info($information, $course); 129 $this->assertMatchesRegularExpression('~do not get certain scores.*Test!~', $information); 130 131 // Success (bottom end). 132 self::set_grade($assignrow, $user->id, 30.0); 133 $this->assertTrue($cond->is_available(false, $info, true, $user->id)); 134 $this->assertFalse($cond->is_available(true, $info, true, $user->id)); 135 $information = $cond->get_description(false, true, $info); 136 $information = \core_availability\info::format_info($information, $course); 137 $this->assertMatchesRegularExpression('~do not get certain scores.*Test!~', $information); 138 } 139 140 /** 141 * Tests the constructor including error conditions. Also tests the 142 * string conversion feature (intended for debugging only). 143 */ 144 public function test_constructor() { 145 // No parameters. 146 $structure = new \stdClass(); 147 try { 148 $cond = new condition($structure); 149 $this->fail(); 150 } catch (\coding_exception $e) { 151 $this->assertStringContainsString('Missing or invalid ->id', $e->getMessage()); 152 } 153 154 // Invalid id (not int). 155 $structure->id = 'bourne'; 156 try { 157 $cond = new condition($structure); 158 $this->fail(); 159 } catch (\coding_exception $e) { 160 $this->assertStringContainsString('Missing or invalid ->id', $e->getMessage()); 161 } 162 163 // Invalid min (not number). 164 $structure->id = 42; 165 $structure->min = 'ute'; 166 try { 167 $cond = new condition($structure); 168 $this->fail(); 169 } catch (\coding_exception $e) { 170 $this->assertStringContainsString('Missing or invalid ->min', $e->getMessage()); 171 } 172 173 // Invalid max (not number). 174 $structure->min = 3.89; 175 $structure->max = '9000'; 176 try { 177 $cond = new condition($structure); 178 $this->fail(); 179 } catch (\coding_exception $e) { 180 $this->assertStringContainsString('Missing or invalid ->max', $e->getMessage()); 181 } 182 183 // All valid. 184 $structure->max = 4.0; 185 $cond = new condition($structure); 186 $this->assertEquals('{grade:#42 >= 3.89000, < 4.00000}', (string)$cond); 187 188 // No max. 189 unset($structure->max); 190 $cond = new condition($structure); 191 $this->assertEquals('{grade:#42 >= 3.89000}', (string)$cond); 192 193 // No min. 194 unset($structure->min); 195 $structure->max = 32.768; 196 $cond = new condition($structure); 197 $this->assertEquals('{grade:#42 < 32.76800}', (string)$cond); 198 199 // No nothing (only requires that grade exists). 200 unset($structure->max); 201 $cond = new condition($structure); 202 $this->assertEquals('{grade:#42}', (string)$cond); 203 } 204 205 /** 206 * Tests the save() function. 207 */ 208 public function test_save() { 209 $structure = (object)array('id' => 19); 210 $cond = new condition($structure); 211 $structure->type = 'grade'; 212 $this->assertEquals($structure, $cond->save()); 213 214 $structure = (object)array('id' => 19, 'min' => 4.12345, 'max' => 90); 215 $cond = new condition($structure); 216 $structure->type = 'grade'; 217 $this->assertEquals($structure, $cond->save()); 218 } 219 220 /** 221 * Updates the grade of a user in the given assign module instance. 222 * 223 * @param \stdClass $assignrow Assignment row from database 224 * @param int $userid User id 225 * @param float $grade Grade 226 */ 227 protected static function set_grade($assignrow, $userid, $grade) { 228 $grades = array(); 229 $grades[$userid] = (object)array( 230 'rawgrade' => $grade, 'userid' => $userid); 231 $assignrow->cmidnumber = null; 232 assign_grade_item_update($assignrow, $grades); 233 } 234 235 /** 236 * Tests the update_dependency_id() function. 237 */ 238 public function test_update_dependency_id() { 239 $cond = new condition((object)array('id' => 123)); 240 $this->assertFalse($cond->update_dependency_id('frogs', 123, 456)); 241 $this->assertFalse($cond->update_dependency_id('grade_items', 12, 34)); 242 $this->assertTrue($cond->update_dependency_id('grade_items', 123, 456)); 243 $after = $cond->save(); 244 $this->assertEquals(456, $after->id); 245 } 246 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body