See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 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 * @package core_grades 19 * @category phpunit 20 * @copyright nicolas@moodle.com 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 */ 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 require_once (__DIR__.'/fixtures/lib.php'); 27 28 class core_grade_item_testcase extends grade_base_testcase { 29 public function test_grade_item() { 30 $this->sub_test_grade_item_construct(); 31 $this->sub_test_grade_item_insert(); 32 $this->sub_test_grade_item_delete(); 33 $this->sub_test_grade_item_update(); 34 $this->sub_test_grade_item_load_scale(); 35 $this->sub_test_grade_item_load_outcome(); 36 $this->sub_test_grade_item_qualifies_for_regrading(); 37 $this->sub_test_grade_item_force_regrading(); 38 $this->sub_test_grade_item_fetch(); 39 $this->sub_test_grade_item_fetch_all(); 40 $this->sub_test_grade_item_get_all_finals(); 41 $this->sub_test_grade_item_get_final(); 42 $this->sub_test_grade_item_get_sortorder(); 43 $this->sub_test_grade_item_set_sortorder(); 44 $this->sub_test_grade_item_move_after_sortorder(); 45 $this->sub_test_grade_item_get_name(); 46 $this->sub_test_grade_item_set_parent(); 47 $this->sub_test_grade_item_get_parent_category(); 48 $this->sub_test_grade_item_load_parent_category(); 49 $this->sub_test_grade_item_get_item_category(); 50 $this->sub_test_grade_item_load_item_category(); 51 $this->sub_test_grade_item_regrade_final_grades(); 52 $this->sub_test_grade_item_adjust_raw_grade(); 53 $this->sub_test_grade_item_rescale_grades_keep_percentage(); 54 $this->sub_test_grade_item_set_locked(); 55 $this->sub_test_grade_item_is_locked(); 56 $this->sub_test_grade_item_set_hidden(); 57 $this->sub_test_grade_item_is_hidden(); 58 $this->sub_test_grade_item_is_category_item(); 59 $this->sub_test_grade_item_is_course_item(); 60 $this->sub_test_grade_item_fetch_course_item(); 61 $this->sub_test_grade_item_depends_on(); 62 $this->sub_test_refresh_grades(); 63 $this->sub_test_grade_item_is_calculated(); 64 $this->sub_test_grade_item_set_calculation(); 65 $this->sub_test_grade_item_get_calculation(); 66 $this->sub_test_grade_item_compute(); 67 $this->sub_test_update_final_grade(); 68 $this->sub_test_grade_item_can_control_visibility(); 69 $this->sub_test_grade_item_fix_sortorder(); 70 $this->sub_test_grade_item_created_event(); 71 $this->sub_test_grade_item_updated_event(); 72 } 73 74 protected function sub_test_grade_item_construct() { 75 $params = new stdClass(); 76 77 $params->courseid = $this->courseid; 78 $params->categoryid = $this->grade_categories[1]->id; 79 $params->itemname = 'unittestgradeitem4'; 80 $params->itemtype = 'mod'; 81 $params->itemmodule = 'database'; 82 $params->iteminfo = 'Grade item used for unit testing'; 83 84 $grade_item = new grade_item($params, false); 85 86 $this->assertEquals($params->courseid, $grade_item->courseid); 87 $this->assertEquals($params->categoryid, $grade_item->categoryid); 88 $this->assertEquals($params->itemmodule, $grade_item->itemmodule); 89 } 90 91 protected function sub_test_grade_item_insert() { 92 $grade_item = new grade_item(); 93 $this->assertTrue(method_exists($grade_item, 'insert')); 94 95 $grade_item->courseid = $this->courseid; 96 $grade_item->categoryid = $this->grade_categories[1]->id; 97 $grade_item->itemname = 'unittestgradeitem4'; 98 $grade_item->itemtype = 'mod'; 99 $grade_item->itemmodule = 'quiz'; 100 $grade_item->iteminfo = 'Grade item used for unit testing'; 101 102 $grade_item->insert(); 103 104 $last_grade_item = end($this->grade_items); 105 106 $this->assertEquals($grade_item->id, $last_grade_item->id + 1); 107 $this->assertEquals(18, $grade_item->sortorder); 108 109 // Keep our reference collection the same as what is in the database. 110 $this->grade_items[] = $grade_item; 111 } 112 113 protected function sub_test_grade_item_delete() { 114 global $DB; 115 $grade_item = new grade_item($this->grade_items[7], false); // Use a grade item not touched by previous (or future) tests. 116 $this->assertTrue(method_exists($grade_item, 'delete')); 117 118 // Add two files. 119 $dummy = array( 120 'contextid' => $grade_item->get_context()->id, 121 'component' => GRADE_FILE_COMPONENT, 122 'filearea' => GRADE_HISTORY_FEEDBACK_FILEAREA, 123 'itemid' => 1, 124 'filepath' => '/', 125 'filename' => 'feedback1.txt' 126 ); 127 128 $fs = get_file_storage(); 129 $fs->create_file_from_string($dummy, ''); 130 131 $dummy['itemid'] = 2; 132 $fs->create_file_from_string($dummy, ''); 133 134 $files = $fs->get_area_files($grade_item->get_context()->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 135 // Includes directories. 136 $this->assertCount(4, $files); 137 138 $this->assertTrue($grade_item->delete()); 139 140 $this->assertFalse($DB->get_record('grade_items', array('id' => $grade_item->id))); 141 142 $files = $fs->get_area_files($grade_item->get_context()->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 143 $this->assertEmpty($files); 144 145 // Keep our reference collection the same as the database. 146 unset($this->grade_items[7]); 147 } 148 149 protected function sub_test_grade_item_update() { 150 global $DB; 151 $grade_item = new grade_item($this->grade_items[0], false); 152 $this->assertTrue(method_exists($grade_item, 'update')); 153 154 $grade_item->iteminfo = 'Updated info for this unittest grade_item'; 155 156 $this->assertTrue($grade_item->update()); 157 158 $grade_item->grademin = 14; 159 $this->assertTrue($grade_item->qualifies_for_regrading()); 160 $this->assertTrue($grade_item->update()); 161 162 $iteminfo = $DB->get_field('grade_items', 'iteminfo', array('id' => $this->grade_items[0]->id)); 163 $this->assertEquals($grade_item->iteminfo, $iteminfo); 164 } 165 166 protected function sub_test_grade_item_load_scale() { 167 $grade_item = new grade_item($this->grade_items[2], false); 168 $this->assertTrue(method_exists($grade_item, 'load_scale')); 169 $scale = $grade_item->load_scale(); 170 $this->assertFalse(empty($grade_item->scale)); 171 $this->assertEquals($scale->id, $this->grade_items[2]->scaleid); 172 } 173 174 protected function sub_test_grade_item_load_outcome() { 175 $grade_item = new grade_item($this->grade_items[0], false); 176 $this->assertTrue(method_exists($grade_item, 'load_outcome')); 177 // TODO: add tests. 178 } 179 180 protected function sub_test_grade_item_qualifies_for_regrading() { 181 $grade_item = new grade_item($this->grade_items[3], false); // Use a grade item not touched by previous tests. 182 $this->assertTrue(method_exists($grade_item, 'qualifies_for_regrading')); 183 184 $this->assertFalse($grade_item->qualifies_for_regrading()); 185 186 $grade_item->iteminfo = 'Updated info for this unittest grade_item'; 187 188 $this->assertFalse($grade_item->qualifies_for_regrading()); 189 190 $grade_item->grademin = 14; 191 192 $this->assertTrue($grade_item->qualifies_for_regrading()); 193 } 194 195 protected function sub_test_grade_item_force_regrading() { 196 $grade_item = new grade_item($this->grade_items[3], false); // Use a grade item not touched by previous tests. 197 $this->assertTrue(method_exists($grade_item, 'force_regrading')); 198 199 $this->assertEquals(0, $grade_item->needsupdate); 200 201 $grade_item->force_regrading(); 202 $this->assertEquals(1, $grade_item->needsupdate); 203 $grade_item->update_from_db(); 204 $this->assertEquals(1, $grade_item->needsupdate); 205 } 206 207 protected function sub_test_grade_item_fetch() { 208 $grade_item = new grade_item(); 209 $this->assertTrue(method_exists($grade_item, 'fetch')); 210 211 // Not using $this->grade_items[0] as it's iteminfo was modified by sub_test_grade_item_qualifies_for_regrading(). 212 $grade_item = grade_item::fetch(array('id'=>$this->grade_items[1]->id)); 213 $this->assertEquals($this->grade_items[1]->id, $grade_item->id); 214 $this->assertEquals($this->grade_items[1]->iteminfo, $grade_item->iteminfo); 215 216 $grade_item = grade_item::fetch(array('itemtype'=>$this->grade_items[1]->itemtype, 'itemmodule'=>$this->grade_items[1]->itemmodule)); 217 $this->assertEquals($this->grade_items[1]->id, $grade_item->id); 218 $this->assertEquals($this->grade_items[1]->iteminfo, $grade_item->iteminfo); 219 } 220 221 protected function sub_test_grade_item_fetch_all() { 222 $grade_item = new grade_item(); 223 $this->assertTrue(method_exists($grade_item, 'fetch_all')); 224 225 $grade_items = grade_item::fetch_all(array('courseid'=>$this->courseid)); 226 $this->assertEquals(count($this->grade_items), count($grade_items)-1); // -1 to account for the course grade item. 227 } 228 229 // Retrieve all final scores for a given grade_item. 230 protected function sub_test_grade_item_get_all_finals() { 231 $grade_item = new grade_item($this->grade_items[0], false); 232 $this->assertTrue(method_exists($grade_item, 'get_final')); 233 234 $final_grades = $grade_item->get_final(); 235 $this->assertEquals(3, count($final_grades)); 236 } 237 238 239 // Retrieve all final scores for a specific userid. 240 protected function sub_test_grade_item_get_final() { 241 $grade_item = new grade_item($this->grade_items[0], false); 242 $this->assertTrue(method_exists($grade_item, 'get_final')); 243 $final_grade = $grade_item->get_final($this->user[1]->id); 244 $this->assertEquals($this->grade_grades[0]->finalgrade, $final_grade->finalgrade); 245 } 246 247 protected function sub_test_grade_item_get_sortorder() { 248 $grade_item = new grade_item($this->grade_items[0], false); 249 $this->assertTrue(method_exists($grade_item, 'get_sortorder')); 250 $sortorder = $grade_item->get_sortorder(); 251 $this->assertEquals($this->grade_items[0]->sortorder, $sortorder); 252 } 253 254 protected function sub_test_grade_item_set_sortorder() { 255 $grade_item = new grade_item($this->grade_items[0], false); 256 $this->assertTrue(method_exists($grade_item, 'set_sortorder')); 257 $grade_item->set_sortorder(999); 258 $this->assertEquals($grade_item->sortorder, 999); 259 } 260 261 protected function sub_test_grade_item_move_after_sortorder() { 262 $grade_item = new grade_item($this->grade_items[0], false); 263 $this->assertTrue(method_exists($grade_item, 'move_after_sortorder')); 264 $grade_item->move_after_sortorder(5); 265 $this->assertEquals($grade_item->sortorder, 6); 266 267 $grade_item = grade_item::fetch(array('id'=>$this->grade_items[0]->id)); 268 $this->assertEquals($grade_item->sortorder, 6); 269 270 $after = grade_item::fetch(array('id'=>$this->grade_items[6]->id)); 271 $this->assertEquals($after->sortorder, 8); 272 } 273 274 protected function sub_test_grade_item_get_name() { 275 $grade_item = new grade_item($this->grade_items[0], false); 276 $this->assertTrue(method_exists($grade_item, 'get_name')); 277 278 $name = $grade_item->get_name(); 279 $this->assertEquals($this->grade_items[0]->itemname, $name); 280 } 281 282 protected function sub_test_grade_item_set_parent() { 283 $grade_item = new grade_item($this->grade_items[0], false); 284 $this->assertTrue(method_exists($grade_item, 'set_parent')); 285 286 $old = $grade_item->get_parent_category(); 287 $new = new grade_category($this->grade_categories[3], false); 288 $new_item = $new->get_grade_item(); 289 290 $this->assertTrue($grade_item->set_parent($new->id)); 291 292 $new_item->update_from_db(); 293 $grade_item->update_from_db(); 294 295 $this->assertEquals($grade_item->categoryid, $new->id); 296 } 297 298 protected function sub_test_grade_item_get_parent_category() { 299 $grade_item = new grade_item($this->grade_items[0], false); 300 $this->assertTrue(method_exists($grade_item, 'get_parent_category')); 301 302 $category = $grade_item->get_parent_category(); 303 $this->assertEquals($this->grade_categories[1]->fullname, $category->fullname); 304 } 305 306 protected function sub_test_grade_item_load_parent_category() { 307 $grade_item = new grade_item($this->grade_items[0], false); 308 $this->assertTrue(method_exists($grade_item, 'load_parent_category')); 309 310 $category = $grade_item->load_parent_category(); 311 $this->assertEquals($this->grade_categories[1]->fullname, $category->fullname); 312 $this->assertEquals($this->grade_categories[1]->fullname, $grade_item->parent_category->fullname); 313 } 314 315 protected function sub_test_grade_item_get_item_category() { 316 $grade_item = new grade_item($this->grade_items[3], false); 317 $this->assertTrue(method_exists($grade_item, 'get_item_category')); 318 319 $category = $grade_item->get_item_category(); 320 $this->assertEquals($this->grade_categories[0]->fullname, $category->fullname); 321 } 322 323 protected function sub_test_grade_item_load_item_category() { 324 $grade_item = new grade_item($this->grade_items[3], false); 325 $this->assertTrue(method_exists($grade_item, 'load_item_category')); 326 327 $category = $grade_item->load_item_category(); 328 $this->assertEquals($this->grade_categories[0]->fullname, $category->fullname); 329 $this->assertEquals($this->grade_categories[0]->fullname, $grade_item->item_category->fullname); 330 } 331 332 protected function sub_test_grade_item_regrade_final_grades() { 333 $grade_item = new grade_item($this->grade_items[0], false); 334 $this->assertTrue(method_exists($grade_item, 'regrade_final_grades')); 335 $this->assertEquals(true, $grade_item->regrade_final_grades()); 336 // TODO: add more tests. 337 } 338 339 protected function sub_test_grade_item_adjust_raw_grade() { 340 $grade_item = new grade_item($this->grade_items[2], false); // Anything but assignment module! 341 $this->assertTrue(method_exists($grade_item, 'adjust_raw_grade')); 342 343 $grade_raw = new stdClass(); 344 $grade_raw->rawgrade = 40; 345 $grade_raw->grademax = 100; 346 $grade_raw->grademin = 0; 347 348 $grade_item->gradetype = GRADE_TYPE_VALUE; 349 $grade_item->multfactor = 1; 350 $grade_item->plusfactor = 0; 351 $grade_item->grademax = 50; 352 $grade_item->grademin = 0; 353 354 $original_grade_raw = clone($grade_raw); 355 $original_grade_item = clone($grade_item); 356 357 $this->assertEquals(20, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 358 359 // Try a larger maximum grade. 360 $grade_item->grademax = 150; 361 $grade_item->grademin = 0; 362 $this->assertEquals(60, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 363 364 // Try larger minimum grade. 365 $grade_item->grademin = 50; 366 367 $this->assertEquals(90, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 368 369 // Rescaling from a small scale (0-50) to a larger scale (0-100). 370 $grade_raw->grademax = 50; 371 $grade_raw->grademin = 0; 372 $grade_item->grademax = 100; 373 $grade_item->grademin = 0; 374 375 $this->assertEquals(80, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 376 377 // Rescaling from a small scale (0-50) to a larger scale with offset (40-100). 378 $grade_item->grademax = 100; 379 $grade_item->grademin = 40; 380 381 $this->assertEquals(88, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 382 383 // Try multfactor and plusfactor. 384 $grade_raw = clone($original_grade_raw); 385 $grade_item = clone($original_grade_item); 386 $grade_item->multfactor = 1.23; 387 $grade_item->plusfactor = 3; 388 389 $this->assertEquals(27.6, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 390 391 // Try multfactor below 0 and a negative plusfactor. 392 $grade_raw = clone($original_grade_raw); 393 $grade_item = clone($original_grade_item); 394 $grade_item->multfactor = 0.23; 395 $grade_item->plusfactor = -3; 396 397 $this->assertEquals(round(1.6), round($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax))); 398 } 399 400 protected function sub_test_grade_item_rescale_grades_keep_percentage() { 401 global $DB; 402 $gradeitem = new grade_item($this->grade_items[10], false); // 10 is the manual grade item. 403 404 // Create some grades to go with the grade item. 405 $gradeids = array(); 406 $grade = new stdClass(); 407 $grade->itemid = $gradeitem->id; 408 $grade->userid = $this->user[2]->id; 409 $grade->finalgrade = 10; 410 $grade->rawgrademax = $gradeitem->grademax; 411 $grade->rawgrademin = $gradeitem->grademin; 412 $grade->timecreated = time(); 413 $grade->timemodified = time(); 414 $gradeids[] = $DB->insert_record('grade_grades', $grade); 415 416 $grade->userid = $this->user[3]->id; 417 $grade->finalgrade = 50; 418 $grade->rawgrademax = $gradeitem->grademax; 419 $grade->rawgrademin = $gradeitem->grademin; 420 $gradeids[] = $DB->insert_record('grade_grades', $grade); 421 422 // Run the function. 423 $gradeitem->grademax = 33; 424 $gradeitem->grademin = 3; 425 $gradeitem->update(); 426 $gradeitem->rescale_grades_keep_percentage(0, 100, 3, 33, 'test'); 427 428 // Check that the grades were updated to match the grade item. 429 $grade = $DB->get_record('grade_grades', array('id' => $gradeids[0])); 430 $this->assertEquals($gradeitem->grademax, $grade->rawgrademax, 'Max grade mismatch', 0.0001); 431 $this->assertEquals($gradeitem->grademin, $grade->rawgrademin, 'Min grade mismatch', 0.0001); 432 $this->assertEquals(6, $grade->finalgrade, 'Min grade mismatch', 0.0001); 433 434 $grade = $DB->get_record('grade_grades', array('id' => $gradeids[1])); 435 $this->assertEquals($gradeitem->grademax, $grade->rawgrademax, 'Max grade mismatch', 0.0001); 436 $this->assertEquals($gradeitem->grademin, $grade->rawgrademin, 'Min grade mismatch', 0.0001); 437 $this->assertEquals(18, $grade->finalgrade, 'Min grade mismatch', 0.0001); 438 } 439 440 protected function sub_test_grade_item_set_locked() { 441 // Getting a grade_item from the DB as set_locked() will fail if the grade items needs to be updated 442 // also needs to have at least one grade_grade or $grade_item->get_final(1) returns null. 443 // $grade_item = new grade_item($this->grade_items[8]); 444 $grade_item = grade_item::fetch(array('id'=>$this->grade_items[8]->id)); 445 446 $this->assertTrue(method_exists($grade_item, 'set_locked')); 447 448 $grade_grade = new grade_grade($grade_item->get_final($this->user[1]->id), false); 449 $this->assertTrue(empty($grade_item->locked));// Not locked. 450 $this->assertTrue(empty($grade_grade->locked));// Not locked. 451 452 $this->assertTrue($grade_item->set_locked(true, true, false)); 453 $grade_grade = new grade_grade($grade_item->get_final($this->user[1]->id), false); 454 455 $this->assertFalse(empty($grade_item->locked));// Locked. 456 $this->assertFalse(empty($grade_grade->locked)); // Individual grades should be locked too. 457 458 $this->assertTrue($grade_item->set_locked(false, true, false)); 459 $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false); 460 461 $this->assertTrue(empty($grade_item->locked)); 462 $this->assertTrue(empty($grade->locked)); // Individual grades should be unlocked too. 463 } 464 465 protected function sub_test_grade_item_is_locked() { 466 $grade_item = new grade_item($this->grade_items[10], false); 467 $this->assertTrue(method_exists($grade_item, 'is_locked')); 468 469 $this->assertFalse($grade_item->is_locked()); 470 $this->assertFalse($grade_item->is_locked($this->user[1]->id)); 471 $this->assertTrue($grade_item->set_locked(true, true, false)); 472 $this->assertTrue($grade_item->is_locked()); 473 $this->assertTrue($grade_item->is_locked($this->user[1]->id)); 474 } 475 476 protected function sub_test_grade_item_set_hidden() { 477 $grade_item = new grade_item($this->grade_items[0], false); 478 $this->assertTrue(method_exists($grade_item, 'set_hidden')); 479 480 $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false); 481 $this->assertEquals(0, $grade_item->hidden); 482 $this->assertEquals(0, $grade->hidden); 483 484 $grade_item->set_hidden(666, true); 485 $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false); 486 487 $this->assertEquals(666, $grade_item->hidden); 488 $this->assertEquals(666, $grade->hidden); 489 } 490 491 protected function sub_test_grade_item_is_hidden() { 492 $grade_item = new grade_item($this->grade_items[0], false); 493 $this->assertTrue(method_exists($grade_item, 'is_hidden')); 494 495 $this->assertFalse($grade_item->is_hidden()); 496 $this->assertFalse($grade_item->is_hidden(1)); 497 498 $grade_item->set_hidden(1); 499 $this->assertTrue($grade_item->is_hidden()); 500 $this->assertTrue($grade_item->is_hidden(1)); 501 502 $grade_item->set_hidden(666); 503 $this->assertFalse($grade_item->is_hidden()); 504 $this->assertFalse($grade_item->is_hidden(1)); 505 506 $grade_item->set_hidden(time()+666); 507 $this->assertTrue($grade_item->is_hidden()); 508 $this->assertTrue($grade_item->is_hidden(1)); 509 } 510 511 protected function sub_test_grade_item_is_category_item() { 512 $grade_item = new grade_item($this->grade_items[3], false); 513 $this->assertTrue(method_exists($grade_item, 'is_category_item')); 514 $this->assertTrue($grade_item->is_category_item()); 515 } 516 517 protected function sub_test_grade_item_is_course_item() { 518 $grade_item = grade_item::fetch_course_item($this->courseid); 519 $this->assertTrue(method_exists($grade_item, 'is_course_item')); 520 $this->assertTrue($grade_item->is_course_item()); 521 } 522 523 protected function sub_test_grade_item_fetch_course_item() { 524 $grade_item = grade_item::fetch_course_item($this->courseid); 525 $this->assertTrue(method_exists($grade_item, 'fetch_course_item')); 526 $this->assertEquals($grade_item->itemtype, 'course'); 527 } 528 529 protected function sub_test_grade_item_depends_on() { 530 global $CFG; 531 532 $origenableoutcomes = $CFG->enableoutcomes; 533 $CFG->enableoutcomes = 0; 534 $grade_item = new grade_item($this->grade_items[1], false); 535 536 // Calculated grade dependency. 537 $deps = $grade_item->depends_on(); 538 sort($deps, SORT_NUMERIC); // For comparison. 539 $this->assertEquals(array($this->grade_items[0]->id), $deps); 540 541 // Simulate depends on returns none when locked. 542 $grade_item->locked = time(); 543 $grade_item->update(); 544 $deps = $grade_item->depends_on(); 545 sort($deps, SORT_NUMERIC); // For comparison. 546 $this->assertEquals(array(), $deps); 547 548 // Category dependency. 549 $grade_item = new grade_item($this->grade_items[3], false); 550 $deps = $grade_item->depends_on(); 551 sort($deps, SORT_NUMERIC); // For comparison. 552 $res = array($this->grade_items[4]->id, $this->grade_items[5]->id); 553 $this->assertEquals($res, $deps); 554 } 555 556 protected function scales_outcomes_test_grade_item_depends_on() { 557 $CFG->enableoutcomes = 1; 558 $origgradeincludescalesinaggregation = $CFG->grade_includescalesinaggregation; 559 $CFG->grade_includescalesinaggregation = 1; 560 561 // Scale item in category with $CFG->grade_includescalesinaggregation = 1. 562 $grade_item = new grade_item($this->grade_items[14], false); 563 $deps = $grade_item->depends_on(); 564 sort($deps, SORT_NUMERIC); 565 $res = array($this->grade_items[16]->id); 566 $this->assertEquals($res, $deps); 567 568 // Scale item in category with $CFG->grade_includescalesinaggregation = 0. 569 $CFG->grade_includescalesinaggregation = 0; 570 $grade_item = new grade_item($this->grade_items[14], false); 571 $deps = $grade_item->depends_on(); 572 $res = array(); 573 $this->assertEquals($res, $deps); 574 $CFG->grade_includescalesinaggregation = 1; 575 576 // Outcome item in category with outcomes disabled. 577 $CFG->enableoutcomes = 0; 578 $grade_item = new grade_item($this->grade_items[14], false); 579 $deps = $grade_item->depends_on(); 580 sort($deps, SORT_NUMERIC); 581 $res = array($this->grade_items[16]->id, $this->grade_items[17]->id); 582 $this->assertEquals($res, $deps); 583 584 $CFG->enableoutcomes = $origenableoutcomes; 585 $CFG->grade_includescalesinaggregation = $origgradeincludescalesinaggregation; 586 } 587 588 protected function sub_test_refresh_grades() { 589 // Testing with the grade item for a mod_assignment instance. 590 $grade_item = new grade_item($this->grade_items[0], false); 591 $this->assertTrue(method_exists($grade_item, 'refresh_grades')); 592 $this->assertTrue($grade_item->refresh_grades()); 593 594 // Break the grade item and check error handling. 595 $grade_item->iteminstance = 123456789; 596 $this->assertFalse($grade_item->refresh_grades()); 597 $this->assertDebuggingCalled(); 598 } 599 600 protected function sub_test_grade_item_is_calculated() { 601 $grade_item = new grade_item($this->grade_items[1], false); 602 $this->assertTrue(method_exists($grade_item, 'is_calculated')); 603 $this->assertTrue($grade_item->is_calculated()); 604 605 $grade_item = new grade_item($this->grade_items[0], false); 606 $this->assertFalse($grade_item->is_calculated()); 607 } 608 609 protected function sub_test_grade_item_set_calculation() { 610 $grade_item = new grade_item($this->grade_items[1], false); 611 $this->assertTrue(method_exists($grade_item, 'set_calculation')); 612 $grade_itemsource = new grade_item($this->grade_items[0], false); 613 614 $grade_item->set_calculation('=[['.$grade_itemsource->idnumber.']]'); 615 616 $this->assertTrue(!empty($grade_item->needsupdate)); 617 $this->assertEquals('=##gi'.$grade_itemsource->id.'##', $grade_item->calculation); 618 } 619 620 protected function sub_test_grade_item_get_calculation() { 621 $grade_item = new grade_item($this->grade_items[1], false); 622 $this->assertTrue(method_exists($grade_item, 'get_calculation')); 623 $grade_itemsource = new grade_item($this->grade_items[0], false); 624 625 $denormalizedformula = str_replace('##gi'.$grade_itemsource->id.'##', '[['.$grade_itemsource->idnumber.']]', $this->grade_items[1]->calculation); 626 627 $formula = $grade_item->get_calculation(); 628 $this->assertTrue(!empty($grade_item->needsupdate)); 629 $this->assertEquals($denormalizedformula, $formula); 630 } 631 632 public function sub_test_grade_item_compute() { 633 $grade_item = grade_item::fetch(array('id'=>$this->grade_items[1]->id)); 634 $this->assertTrue(method_exists($grade_item, 'compute')); 635 636 // Check the grade_grades in the array match those in the DB then delete $this->grade_items[1]'s grade_grades. 637 $this->grade_grades[3] = grade_grade::fetch(array('id'=>$this->grade_grades[3]->id)); 638 $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[3]->id)); 639 $grade_grade->delete(); 640 641 $this->grade_grades[4] = grade_grade::fetch(array('id'=>$this->grade_grades[4]->id)); 642 $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[4]->id)); 643 $grade_grade->delete(); 644 645 $this->grade_grades[5] = grade_grade::fetch(array('id'=>$this->grade_grades[5]->id)); 646 $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[5]->id)); 647 $grade_grade->delete(); 648 649 // Recalculate the grades (its a calculation so pulls values from other grade_items) and reinsert them. 650 $grade_item->compute(); 651 652 $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[3]->userid, 'itemid'=>$this->grade_grades[3]->itemid)); 653 $this->assertEquals($this->grade_grades[3]->finalgrade, $grade_grade->finalgrade); 654 655 $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[4]->userid, 'itemid'=>$this->grade_grades[4]->itemid)); 656 $this->assertEquals($this->grade_grades[4]->finalgrade, $grade_grade->finalgrade); 657 658 $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[5]->userid, 'itemid'=>$this->grade_grades[5]->itemid)); 659 $this->assertEquals($this->grade_grades[5]->finalgrade, $grade_grade->finalgrade); 660 } 661 662 protected function sub_test_update_final_grade() { 663 664 // MDL-31713 Check that min and max are set on the grade_grade instance 665 // if the grade is overridden before the activity has supplied a grade. 666 $min = 2; 667 $max = 8; 668 669 // Create a brand new grade item. 670 $grade_item = new grade_item(); 671 $this->assertTrue(method_exists($grade_item, 'insert')); 672 673 $grade_item->courseid = $this->courseid; 674 $grade_item->categoryid = $this->grade_categories[1]->id; 675 $grade_item->itemname = 'brand new unit test grade item'; 676 $grade_item->itemtype = 'mod'; 677 $grade_item->itemmodule = 'quiz'; 678 $grade_item->iteminfo = 'Grade item used for unit testing'; 679 $grade_item->iteminstance = $this->activities[7]->id; 680 $grade_item->grademin = $min; 681 $grade_item->grademax = $max; 682 $grade_item->insert(); 683 684 // Override the student grade. 685 $grade_item->update_final_grade($this->user[1]->id, 7, 'gradebook', '', FORMAT_MOODLE); 686 687 // Check the student's grade has the correct min and max grade. 688 $grade_grade = grade_grade::fetch(array('userid'=>$this->user[1]->id, 'itemid'=>$grade_item->id)); 689 $this->assertEquals($min, $grade_grade->rawgrademin); 690 $this->assertEquals($max, $grade_grade->rawgrademax); 691 } 692 693 protected function sub_test_grade_item_can_control_visibility() { 694 // Grade item 0 == Course module 0 == Assignment. 695 $grade_item = new grade_item($this->grade_items[0], false); 696 $this->assertTrue($grade_item->can_control_visibility()); 697 698 // Grade item == Course module 7 == Quiz. 699 $grade_item = new grade_item($this->grade_items[11], false); 700 $this->assertFalse($grade_item->can_control_visibility()); 701 } 702 703 /** 704 * Test the {@link grade_item::fix_duplicate_sortorder() function with 705 * faked duplicate sortorder data. 706 */ 707 public function sub_test_grade_item_fix_sortorder() { 708 global $DB; 709 710 $this->resetAfterTest(true); 711 712 // Each set is used for filling the db with fake data and will be representing the result of query: 713 // "SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id". 714 $testsets = array( 715 // Items that need no action. 716 array(1,2,3), 717 array(5,6,7), 718 array(7,6,1,3,2,5), 719 // Items with sortorder duplicates 720 array(1,2,2,3,3,4,5), 721 // Only one sortorder duplicate. 722 array(1,1), 723 array(3,3), 724 // Non-sequential sortorders with one or multiple duplicates. 725 array(3,3,7,5,6,6,9,10,8,3), 726 array(7,7,3), 727 array(3,4,5,3,5,4,7,1) 728 ); 729 $origsequence = array(); 730 731 // Generate the data and remember the initial sequence or items. 732 foreach ($testsets as $testset) { 733 $course = $this->getDataGenerator()->create_course(); 734 foreach ($testset as $sortorder) { 735 $this->insert_fake_grade_item_sortorder($course->id, $sortorder); 736 } 737 $DB->get_records('grade_items'); 738 $origsequence[$course->id] = $DB->get_fieldset_sql("SELECT id FROM {grade_items} ". 739 "WHERE courseid = ? ORDER BY sortorder, id", array($course->id)); 740 } 741 742 $duplicatedetectionsql = "SELECT courseid, sortorder 743 FROM {grade_items} 744 WHERE courseid = :courseid 745 GROUP BY courseid, sortorder 746 HAVING COUNT(id) > 1"; 747 748 // Do the work. 749 foreach ($origsequence as $courseid => $ignore) { 750 grade_item::fix_duplicate_sortorder($courseid); 751 // Verify that no duplicates are left in the database. 752 $dupes = $DB->record_exists_sql($duplicatedetectionsql, array('courseid' => $courseid)); 753 $this->assertFalse($dupes); 754 } 755 756 // Verify that sequences are exactly the same as they were before upgrade script. 757 $idx = 0; 758 foreach ($origsequence as $courseid => $sequence) { 759 if (count(($testsets[$idx])) == count(array_unique($testsets[$idx]))) { 760 // If there were no duplicates for this course verify that sortorders are not modified. 761 $newsortorders = $DB->get_fieldset_sql("SELECT sortorder from {grade_items} WHERE courseid=? ORDER BY id", array($courseid)); 762 $this->assertEquals($testsets[$idx], $newsortorders); 763 } 764 $newsequence = $DB->get_fieldset_sql("SELECT id FROM {grade_items} ". 765 "WHERE courseid = ? ORDER BY sortorder, id", array($courseid)); 766 $this->assertEquals($sequence, $newsequence, 767 "Sequences do not match for test set $idx : ".join(',', $testsets[$idx])); 768 $idx++; 769 } 770 } 771 772 /** 773 * Populate some fake grade items into the database with specified 774 * sortorder and course id. 775 * 776 * NOTE: This function doesn't make much attempt to respect the 777 * gradebook internals, its simply used to fake some data for 778 * testing the upgradelib function. Please don't use it for other 779 * purposes. 780 * 781 * @param int $courseid id of course 782 * @param int $sortorder numeric sorting order of item 783 * @return stdClass grade item object from the database. 784 */ 785 private function insert_fake_grade_item_sortorder($courseid, $sortorder) { 786 global $DB, $CFG; 787 require_once($CFG->libdir.'/gradelib.php'); 788 789 $item = new stdClass(); 790 $item->courseid = $courseid; 791 $item->sortorder = $sortorder; 792 $item->gradetype = GRADE_TYPE_VALUE; 793 $item->grademin = 30; 794 $item->grademax = 110; 795 $item->itemnumber = 1; 796 $item->iteminfo = ''; 797 $item->timecreated = time(); 798 $item->timemodified = time(); 799 800 $item->id = $DB->insert_record('grade_items', $item); 801 802 return $DB->get_record('grade_items', array('id' => $item->id)); 803 } 804 805 public function test_set_aggregation_fields_for_aggregation() { 806 $course = $this->getDataGenerator()->create_course(); 807 $gi = new grade_item(array('courseid' => $course->id, 'itemtype' => 'manual'), false); 808 809 $methods = array(GRADE_AGGREGATE_MEAN, GRADE_AGGREGATE_MEDIAN, GRADE_AGGREGATE_MIN, GRADE_AGGREGATE_MAX, 810 GRADE_AGGREGATE_MODE, GRADE_AGGREGATE_WEIGHTED_MEAN, GRADE_AGGREGATE_WEIGHTED_MEAN2, 811 GRADE_AGGREGATE_EXTRACREDIT_MEAN, GRADE_AGGREGATE_SUM); 812 813 // Switching from and to the same aggregation using the defaults. 814 foreach ($methods as $method) { 815 $defaults = grade_category::get_default_aggregation_coefficient_values($method); 816 $gi->aggregationcoef = $defaults['aggregationcoef']; 817 $gi->aggregationcoef2 = $defaults['aggregationcoef2']; 818 $gi->weightoverride = $defaults['weightoverride']; 819 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($method, $method)); 820 $this->assertEquals($defaults['aggregationcoef'], $gi->aggregationcoef); 821 $this->assertEquals($defaults['aggregationcoef2'], $gi->aggregationcoef2); 822 $this->assertEquals($defaults['weightoverride'], $gi->weightoverride); 823 } 824 825 // Extra credit is kept across aggregation methods that support it. 826 foreach ($methods as $from) { 827 $fromsupportsec = grade_category::aggregation_uses_extracredit($from); 828 $fromdefaults = grade_category::get_default_aggregation_coefficient_values($from); 829 830 foreach ($methods as $to) { 831 $tosupportsec = grade_category::aggregation_uses_extracredit($to); 832 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 833 834 // Set the item to be extra credit, if supported. 835 if ($fromsupportsec) { 836 $gi->aggregationcoef = 1; 837 } else { 838 $gi->aggregationcoef = $fromdefaults['aggregationcoef']; 839 } 840 841 // We ignore those fields, we know it is never used for extra credit. 842 $gi->aggregationcoef2 = $todefaults['aggregationcoef2']; 843 $gi->weightoverride = $todefaults['weightoverride']; 844 845 if ($fromsupportsec && $tosupportsec) { 846 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 847 $this->assertEquals(1, $gi->aggregationcoef); 848 849 } else if ($fromsupportsec && !$tosupportsec) { 850 if ($to == GRADE_AGGREGATE_WEIGHTED_MEAN) { 851 // Special case, aggregationcoef is used but for weights. 852 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 853 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 854 } else { 855 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 856 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 857 } 858 } else { 859 // The source does not support extra credit, everything will be reset. 860 if (($from == GRADE_AGGREGATE_WEIGHTED_MEAN || $to == GRADE_AGGREGATE_WEIGHTED_MEAN) && $from != $to) { 861 // Special case, aggregationcoef is used but for weights. 862 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 863 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 864 } else { 865 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 866 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 867 } 868 } 869 } 870 } 871 872 // Extra credit can be higher than one for GRADE_AGGREGATE_EXTRACREDIT_MEAN, but will be normalised for others. 873 $from = GRADE_AGGREGATE_EXTRACREDIT_MEAN; 874 $fromdefaults = grade_category::get_default_aggregation_coefficient_values($from); 875 876 foreach ($methods as $to) { 877 if (!grade_category::aggregation_uses_extracredit($to)) { 878 continue; 879 } 880 881 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 882 $gi->aggregationcoef = 8; 883 884 // Ignore those fields, they are not used for extra credit. 885 $gi->aggregationcoef2 = $todefaults['aggregationcoef2']; 886 $gi->weightoverride = $todefaults['weightoverride']; 887 888 if ($to == $from) { 889 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 890 $this->assertEquals(8, $gi->aggregationcoef); 891 } else { 892 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 893 $this->assertEquals(1, $gi->aggregationcoef); 894 } 895 } 896 897 // Weights are reset. 898 $from = GRADE_AGGREGATE_SUM; 899 $fromdefaults = grade_category::get_default_aggregation_coefficient_values($from); 900 901 $gi->aggregationcoef = $fromdefaults['aggregationcoef']; 902 $gi->aggregationcoef2 = 0.321; 903 $gi->weightoverride = $fromdefaults['weightoverride']; 904 905 $to = GRADE_AGGREGATE_WEIGHTED_MEAN; 906 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 907 908 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 909 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 910 $this->assertEquals($todefaults['aggregationcoef2'], $gi->aggregationcoef2); 911 $this->assertEquals($todefaults['weightoverride'], $gi->weightoverride); 912 913 $gi->aggregationcoef = $fromdefaults['aggregationcoef']; 914 $gi->aggregationcoef2 = 0.321; 915 $gi->weightoverride = $fromdefaults['weightoverride']; 916 917 $to = GRADE_AGGREGATE_SUM; 918 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 919 920 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 921 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 922 $this->assertEquals($todefaults['aggregationcoef2'], $gi->aggregationcoef2); 923 $this->assertEquals($todefaults['weightoverride'], $gi->weightoverride); 924 925 // Weight is kept when using SUM with weight override. 926 $from = GRADE_AGGREGATE_SUM; 927 $fromdefaults = grade_category::get_default_aggregation_coefficient_values($from); 928 929 $gi->aggregationcoef = $fromdefaults['aggregationcoef']; 930 $gi->aggregationcoef2 = 0.321; 931 $gi->weightoverride = 1; 932 933 $to = GRADE_AGGREGATE_SUM; 934 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 935 936 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 937 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 938 $this->assertEquals(0.321, $gi->aggregationcoef2); 939 $this->assertEquals(1, $gi->weightoverride); 940 941 $gi->aggregationcoef2 = 0.321; 942 $gi->aggregationcoef = $fromdefaults['aggregationcoef']; 943 $gi->weightoverride = 1; 944 945 $to = GRADE_AGGREGATE_WEIGHTED_MEAN; 946 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 947 948 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 949 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 950 $this->assertEquals($todefaults['aggregationcoef2'], $gi->aggregationcoef2); 951 $this->assertEquals($todefaults['weightoverride'], $gi->weightoverride); 952 953 // Weight is kept when staying in weighted mean. 954 $from = GRADE_AGGREGATE_WEIGHTED_MEAN; 955 $fromdefaults = grade_category::get_default_aggregation_coefficient_values($from); 956 957 $gi->aggregationcoef = 18; 958 $gi->aggregationcoef2 = $fromdefaults['aggregationcoef2']; 959 $gi->weightoverride = $fromdefaults['weightoverride']; 960 961 $to = GRADE_AGGREGATE_WEIGHTED_MEAN; 962 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 963 964 $this->assertFalse($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 965 $this->assertEquals(18, $gi->aggregationcoef); 966 $this->assertEquals($todefaults['aggregationcoef2'], $gi->aggregationcoef2); 967 $this->assertEquals($todefaults['weightoverride'], $gi->weightoverride); 968 969 $gi->aggregationcoef = 18; 970 $gi->aggregationcoef2 = $fromdefaults['aggregationcoef2']; 971 $gi->weightoverride = $fromdefaults['weightoverride']; 972 973 $to = GRADE_AGGREGATE_SUM; 974 $todefaults = grade_category::get_default_aggregation_coefficient_values($to); 975 976 $this->assertTrue($gi->set_aggregation_fields_for_aggregation($from, $to), "From: $from, to: $to"); 977 $this->assertEquals($todefaults['aggregationcoef'], $gi->aggregationcoef); 978 $this->assertEquals($todefaults['aggregationcoef2'], $gi->aggregationcoef2); 979 $this->assertEquals($todefaults['weightoverride'], $gi->weightoverride); 980 } 981 982 /** 983 * Test that grade item event triggered when a grade item is created. 984 */ 985 protected function sub_test_grade_item_created_event() { 986 $sink = $this->redirectEvents(); 987 988 $gradeitem = new grade_item(); 989 990 $gradeitem->courseid = $this->courseid; 991 $gradeitem->categoryid = $this->grade_categories[1]->id; 992 $gradeitem->itemname = 'unittestgradeitem4'; 993 $gradeitem->itemtype = 'mod'; 994 $gradeitem->itemmodule = 'quiz'; 995 $gradeitem->iteminfo = 'Grade item used for unit testing'; 996 997 $gradeitem->insert(); 998 999 $result = $sink->get_events(); 1000 $sink->close(); 1001 1002 $this->assertCount(1, $result); 1003 1004 $event = reset($result); 1005 $this->assertEventContextNotUsed($event); 1006 $this->assertInstanceOf('core\event\grade_item_created', $event); 1007 1008 $eventgradeitem = $event->get_grade_item(); 1009 1010 $this->assertInstanceOf('grade_item', $eventgradeitem); 1011 $this->assertEquals($gradeitem->id, $eventgradeitem->id); 1012 $this->assertEquals($gradeitem->itemname, $event->other['itemname']); 1013 $this->assertEquals($gradeitem->itemtype, $event->other['itemtype']); 1014 $this->assertEquals($gradeitem->itemmodule, $event->other['itemmodule']); 1015 } 1016 1017 /** 1018 * Test that grade item event triggered when a grade item is updated. 1019 */ 1020 protected function sub_test_grade_item_updated_event() { 1021 $gradeitem = new grade_item(); 1022 1023 $gradeitem->courseid = $this->courseid; 1024 $gradeitem->categoryid = $this->grade_categories[1]->id; 1025 $gradeitem->itemname = 'unittestgradeitem4'; 1026 $gradeitem->itemtype = 'mod'; 1027 $gradeitem->itemmodule = 'quiz'; 1028 $gradeitem->iteminfo = 'Grade item used for unit testing'; 1029 $gradeitem->insert(); 1030 1031 $sink = $this->redirectEvents(); 1032 1033 $gradeitem->itemname = 'updatedname'; 1034 $gradeitem->update(); 1035 1036 $result = $sink->get_events(); 1037 $sink->close(); 1038 1039 $this->assertCount(1, $result); 1040 1041 $event = reset($result); 1042 $this->assertInstanceOf('core\event\grade_item_updated', $event); 1043 $this->assertEventContextNotUsed($event); 1044 1045 $eventgradeitem = $event->get_grade_item(); 1046 1047 $this->assertInstanceOf('grade_item', $eventgradeitem); 1048 $this->assertEquals($gradeitem->id, $eventgradeitem->id); 1049 $this->assertEquals($gradeitem->itemtype, $event->other['itemtype']); 1050 $this->assertEquals($gradeitem->itemmodule, $event->other['itemmodule']); 1051 $this->assertEquals('updatedname', $event->other['itemname']); 1052 } 1053 1054 1055 /** 1056 * Test grade item duplication expecting success. 1057 */ 1058 public function test_grade_duplicate_grade_item_success() { 1059 $cat = new grade_category(); 1060 $cat->courseid = $this->courseid; 1061 $cat->fullname = 'Grade category'; 1062 $cat->insert(); 1063 1064 // Method exists. 1065 $gi = new grade_item(); 1066 $this->assertTrue(method_exists($gi, 'duplicate')); 1067 1068 // Grade item is inserted and valid for duplication. 1069 $gi->courseid = $this->courseid; 1070 $gi->categoryid = $cat->id; 1071 $gi->itemtype = 'manual'; 1072 $gi->itemname = 'Grade Item 1'; 1073 $gi->idnumber = '1000'; 1074 $gi->insert(); 1075 $gi2 = $gi->duplicate(); 1076 1077 $this->assertEquals($gi->courseid, $gi2->courseid); 1078 $this->assertEquals($gi->categoryid, $gi2->categoryid); 1079 $this->assertEquals($gi->itemtype, $gi2->itemtype); 1080 $this->assertEquals($gi->gradetype, $gi2->gradetype); 1081 $this->assertEquals($gi->grademax, $gi2->grademax); 1082 $this->assertEquals($gi->grademin, $gi2->grademin); 1083 $this->assertEquals($gi->gradepass, $gi2->gradepass); 1084 $this->assertEquals($gi->display, $gi2->display); 1085 $this->assertEquals($gi->decimals, $gi2->decimals); 1086 $this->assertEquals($gi->hidden, $gi2->hidden); 1087 $this->assertEquals($gi->weightoverride, $gi2->weightoverride); 1088 1089 $this->assertNotEquals($gi->id, $gi2->id); 1090 $this->assertNotEquals($gi->idnumber, $gi2->idnumber); 1091 $this->assertNotEquals($gi->sortorder, $gi2->sortorder); 1092 $this->assertNotEquals($gi->itemname, $gi2->itemname); 1093 } 1094 1095 /** 1096 * Test grade item duplication exception expected with incomplete grade item. 1097 */ 1098 public function test_grade_duplicate_grade_item_incomplete() { 1099 // Grade item is not valid because it is empty. 1100 $gi = new grade_item(); 1101 $gi->courseid = $this->courseid; 1102 $this->expectException("moodle_exception"); 1103 $gi2 = $gi->duplicate(); 1104 } 1105 1106 /** 1107 * Test grade item duplication exception expected because item must be in db. 1108 */ 1109 public function test_grade_duplicate_grade_item_not_in_db() { 1110 $cat = new grade_category(); 1111 $cat->courseid = $this->courseid; 1112 $cat->fullname = 'Grade category'; 1113 $cat->insert(); 1114 1115 // Grade item is valid for insertion but is not inserted into db. 1116 // Duplicate method throws an exception. 1117 $gi = new grade_item(); 1118 $gi->courseid = $this->courseid; 1119 $gi->categoryid = $cat->id; 1120 $gi->itemtype = 'manual'; 1121 $gi->itemname = 'Grade Item 1'; 1122 $gi->idnumber = '1000'; 1123 1124 $this->expectException("moodle_exception"); 1125 $gi2 = $gi->duplicate(); 1126 } 1127 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body