Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403]
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 /lib/gradelib.php. 19 * 20 * @package core_grades 21 * @category phpunit 22 * @copyright 2012 Andrew Davis 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 require_once($CFG->libdir . '/gradelib.php'); 30 31 class core_gradelib_testcase extends advanced_testcase { 32 33 public function test_grade_update_mod_grades() { 34 35 $this->resetAfterTest(true); 36 37 // Create a broken module instance. 38 $modinstance = new stdClass(); 39 $modinstance->modname = 'doesntexist'; 40 41 $this->assertFalse(grade_update_mod_grades($modinstance)); 42 // A debug message should have been generated. 43 $this->assertDebuggingCalled(); 44 45 // Create a course and instance of mod_assign. 46 $course = $this->getDataGenerator()->create_course(); 47 48 $assigndata['course'] = $course->id; 49 $assigndata['name'] = 'lightwork assignment'; 50 $modinstance = self::getDataGenerator()->create_module('assign', $assigndata); 51 52 // Function grade_update_mod_grades() requires 2 additional properties, cmidnumber and modname. 53 $cm = get_coursemodule_from_instance('assign', $modinstance->id, 0, false, MUST_EXIST); 54 $modinstance->cmidnumber = $cm->id; 55 $modinstance->modname = 'assign'; 56 57 $this->assertTrue(grade_update_mod_grades($modinstance)); 58 } 59 60 /** 61 * Tests the function remove_grade_letters(). 62 */ 63 public function test_remove_grade_letters() { 64 global $DB; 65 66 $this->resetAfterTest(); 67 68 $course = $this->getDataGenerator()->create_course(); 69 70 $context = context_course::instance($course->id); 71 72 // Add a grade letter to the course. 73 $letter = new stdClass(); 74 $letter->letter = 'M'; 75 $letter->lowerboundary = '100'; 76 $letter->contextid = $context->id; 77 $DB->insert_record('grade_letters', $letter); 78 79 // Pre-warm the cache, ensure that that the letter is cached. 80 $cache = cache::make('core', 'grade_letters'); 81 82 // Check that the cache is empty beforehand. 83 $letters = $cache->get($context->id); 84 $this->assertFalse($letters); 85 86 // Call the function. 87 grade_get_letters($context); 88 89 $letters = $cache->get($context->id); 90 $this->assertEquals(1, count($letters)); 91 $this->assertTrue(in_array($letter->letter, $letters)); 92 93 remove_grade_letters($context, false); 94 95 // Confirm grade letter was deleted. 96 $this->assertEquals(0, $DB->count_records('grade_letters')); 97 98 // Confirm grade letter is also deleted from cache. 99 $letters = $cache->get($context->id); 100 $this->assertFalse($letters); 101 } 102 103 /** 104 * Tests the function grade_course_category_delete(). 105 */ 106 public function test_grade_course_category_delete() { 107 global $DB; 108 109 $this->resetAfterTest(); 110 111 $category = core_course_category::create(array('name' => 'Cat1')); 112 113 // Add a grade letter to the category. 114 $letter = new stdClass(); 115 $letter->letter = 'M'; 116 $letter->lowerboundary = '100'; 117 $letter->contextid = context_coursecat::instance($category->id)->id; 118 $DB->insert_record('grade_letters', $letter); 119 120 grade_course_category_delete($category->id, '', false); 121 122 // Confirm grade letter was deleted. 123 $this->assertEquals(0, $DB->count_records('grade_letters')); 124 } 125 126 /** 127 * Tests the function grade_regrade_final_grades(). 128 */ 129 public function test_grade_regrade_final_grades() { 130 global $DB; 131 132 $this->resetAfterTest(); 133 134 // Setup some basics. 135 $course = $this->getDataGenerator()->create_course(); 136 $user = $this->getDataGenerator()->create_user(); 137 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student'); 138 139 // We need two grade items. 140 $params = ['idnumber' => 'g1', 'courseid' => $course->id]; 141 $g1 = new grade_item($this->getDataGenerator()->create_grade_item($params)); 142 unset($params['idnumber']); 143 $g2 = new grade_item($this->getDataGenerator()->create_grade_item($params)); 144 145 $category = new grade_category($this->getDataGenerator()->create_grade_category($params)); 146 $catitem = $category->get_grade_item(); 147 148 // Now set a calculation. 149 $catitem->set_calculation('=[[g1]]'); 150 151 $catitem->update(); 152 153 // Everything needs updating. 154 $this->assertEquals(4, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1])); 155 156 grade_regrade_final_grades($course->id); 157 158 // See that everything has been updated. 159 $this->assertEquals(0, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1])); 160 161 $g1->delete(); 162 163 // Now there is one that needs updating. 164 $this->assertEquals(1, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1])); 165 166 // This can cause an infinite loop if things go... poorly. 167 grade_regrade_final_grades($course->id); 168 169 // Now because of the failure, two things need updating. 170 $this->assertEquals(2, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1])); 171 } 172 173 /** 174 * Tests for the grade_get_date_for_user_grade function. 175 * 176 * @dataProvider grade_get_date_for_user_grade_provider 177 * @param stdClass $grade 178 * @param stdClass $user 179 * @param int $expected 180 */ 181 public function test_grade_get_date_for_user_grade(stdClass $grade, stdClass $user, ?int $expected): void { 182 $this->assertEquals($expected, grade_get_date_for_user_grade($grade, $user)); 183 } 184 185 /** 186 * Data provider for tests of the grade_get_date_for_user_grade function. 187 * 188 * @return array 189 */ 190 public function grade_get_date_for_user_grade_provider(): array { 191 $u1 = (object) [ 192 'id' => 42, 193 ]; 194 $u2 = (object) [ 195 'id' => 930, 196 ]; 197 198 $d1 = 1234567890; 199 $d2 = 9876543210; 200 201 $g1 = (object) [ 202 'usermodified' => $u1->id, 203 'dategraded' => $d1, 204 'datesubmitted' => $d2, 205 ]; 206 $g2 = (object) [ 207 'usermodified' => $u1->id, 208 'dategraded' => $d1, 209 'datesubmitted' => 0, 210 ]; 211 212 $g3 = (object) [ 213 'usermodified' => $u1->id, 214 'dategraded' => null, 215 'datesubmitted' => $d2, 216 ]; 217 218 return [ 219 'If the user is the last person to have modified the grade_item then show the date that it was graded' => [ 220 $g1, 221 $u1, 222 $d1, 223 ], 224 'If there is no grade and there is no feedback, then show graded date as null' => [ 225 $g3, 226 $u1, 227 null, 228 ], 229 'If the user is not the last person to have modified the grade_item, ' . 230 'and there is no submission date, then show the date that it was submitted' => [ 231 $g1, 232 $u2, 233 $d2, 234 ], 235 'If the user is not the last person to have modified the grade_item, ' . 236 'but there is no submission date, then show the date that it was graded' => [ 237 $g2, 238 $u2, 239 $d1, 240 ], 241 'If the user is the last person to have modified the grade_item, ' . 242 'and there is no submission date, then still show the date that it was graded' => [ 243 $g2, 244 $u1, 245 $d1, 246 ], 247 ]; 248 } 249 250 /** 251 * Test the caching of grade letters. 252 */ 253 public function test_get_grade_letters() { 254 255 $this->resetAfterTest(); 256 257 // Setup some basics. 258 $course = $this->getDataGenerator()->create_course(); 259 $context = context_course::instance($course->id); 260 261 $cache = cache::make('core', 'grade_letters'); 262 $letters = $cache->get($context->id); 263 264 // Make sure the cache is empty. 265 $this->assertFalse($letters); 266 267 // Now check to see if the letters get cached. 268 $actual = grade_get_letters($context); 269 270 $expected = $cache->get($context->id); 271 272 $this->assertEquals($expected, $actual); 273 } 274 275 /** 276 * Test custom letters. 277 */ 278 public function test_get_grade_letters_custom() { 279 global $DB; 280 281 $this->resetAfterTest(); 282 283 $course = $this->getDataGenerator()->create_course(); 284 $context = context_course::instance($course->id); 285 286 $cache = cache::make('core', 'grade_letters'); 287 $letters = $cache->get($context->id); 288 289 // Make sure the cache is empty. 290 $this->assertFalse($letters); 291 292 // Add a grade letter to the course. 293 $letter = new stdClass(); 294 $letter->letter = 'M'; 295 $letter->lowerboundary = '100'; 296 $letter->contextid = $context->id; 297 $DB->insert_record('grade_letters', $letter); 298 299 $actual = grade_get_letters($context); 300 $expected = $cache->get($context->id); 301 302 $this->assertEquals($expected, $actual); 303 } 304 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body