Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

Differences Between: [Versions 311 and 403] [Versions 400 and 403] [Versions 401 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  namespace core;
  18  
  19  use core_grading_external;
  20  use core_external\external_api;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  
  24  global $CFG;
  25  
  26  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  27  
  28  /**
  29   * Unit tests for the grading API defined in core_grading_external class.
  30   *
  31   * @package core
  32   * @category test
  33   * @copyright 2013 Paul Charsley
  34   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  35   */
  36  class grading_external_test extends \externallib_advanced_testcase {
  37  
  38      /**
  39       * Test get_definitions
  40       */
  41      public function test_get_definitions() {
  42          global $DB, $CFG, $USER;
  43  
  44          $this->resetAfterTest(true);
  45          // Create a course and assignment.
  46          $coursedata['idnumber'] = 'idnumbercourse';
  47          $coursedata['fullname'] = 'Lightwork Course';
  48          $coursedata['summary'] = 'Lightwork Course description';
  49          $coursedata['summaryformat'] = FORMAT_MOODLE;
  50          $course = self::getDataGenerator()->create_course($coursedata);
  51  
  52          $assigndata['course'] = $course->id;
  53          $assigndata['name'] = 'lightwork assignment';
  54  
  55          $cm = self::getDataGenerator()->create_module('assign', $assigndata);
  56  
  57          // Create manual enrolment record.
  58          $manualenroldata['enrol'] = 'manual';
  59          $manualenroldata['status'] = 0;
  60          $manualenroldata['courseid'] = $course->id;
  61          $enrolid = $DB->insert_record('enrol', $manualenroldata);
  62  
  63          // Create a teacher and give them capabilities.
  64          $coursecontext = \context_course::instance($course->id);
  65          $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $coursecontext->id, 3);
  66          $modulecontext = \context_module::instance($cm->cmid);
  67          $this->assignUserCapability('mod/assign:grade', $modulecontext->id, $roleid);
  68  
  69          // Create the teacher's enrolment record.
  70          $userenrolmentdata['status'] = 0;
  71          $userenrolmentdata['enrolid'] = $enrolid;
  72          $userenrolmentdata['userid'] = $USER->id;
  73          $DB->insert_record('user_enrolments', $userenrolmentdata);
  74  
  75          // Create a grading area.
  76          $gradingarea = array(
  77              'contextid' => $modulecontext->id,
  78              'component' => 'mod_assign',
  79              'areaname' => 'submissions',
  80              'activemethod' => 'rubric'
  81          );
  82          $areaid = $DB->insert_record('grading_areas', $gradingarea);
  83  
  84          // Create a rubric grading definition.
  85          $rubricdefinition = array (
  86              'areaid' => $areaid,
  87              'method' => 'rubric',
  88              'name' => 'test',
  89              'status' => 20,
  90              'copiedfromid' => 1,
  91              'timecreated' => 1,
  92              'usercreated' => $USER->id,
  93              'timemodified' => 1,
  94              'usermodified' => $USER->id,
  95              'timecopied' => 0
  96          );
  97          $definitionid = $DB->insert_record('grading_definitions', $rubricdefinition);
  98  
  99          // Create a criterion with levels.
 100          $rubriccriteria1 = array (
 101              'definitionid' => $definitionid,
 102              'sortorder' => 1,
 103              'description' => 'Demonstrate an understanding of disease control',
 104              'descriptionformat' => 0
 105          );
 106          $criterionid1 = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria1);
 107          $rubriclevel1 = array (
 108              'criterionid' => $criterionid1,
 109              'score' => 5,
 110              'definition' => 'pass',
 111              'definitionformat' => 0
 112          );
 113          $DB->insert_record('gradingform_rubric_levels', $rubriclevel1);
 114          $rubriclevel2 = array (
 115              'criterionid' => $criterionid1,
 116              'score' => 10,
 117              'definition' => 'excellent',
 118              'definitionformat' => 0
 119          );
 120          $DB->insert_record('gradingform_rubric_levels', $rubriclevel2);
 121  
 122          // Create a second criterion with levels.
 123          $rubriccriteria2 = array (
 124              'definitionid' => $definitionid,
 125              'sortorder' => 2,
 126              'description' => 'Demonstrate an understanding of brucellosis',
 127              'descriptionformat' => 0
 128          );
 129          $criterionid2 = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria2);
 130          $rubriclevel1 = array (
 131              'criterionid' => $criterionid2,
 132              'score' => 5,
 133              'definition' => 'pass',
 134              'definitionformat' => 0
 135          );
 136          $DB->insert_record('gradingform_rubric_levels', $rubriclevel1);
 137          $rubriclevel2 = array (
 138              'criterionid' => $criterionid2,
 139              'score' => 10,
 140              'definition' => 'excellent',
 141              'definitionformat' => 0
 142          );
 143          $DB->insert_record('gradingform_rubric_levels', $rubriclevel2);
 144  
 145          // Call the external function.
 146          $cmids = array ($cm->cmid);
 147          $areaname = 'submissions';
 148          $result = core_grading_external::get_definitions($cmids, $areaname);
 149          $result = external_api::clean_returnvalue(core_grading_external::get_definitions_returns(), $result);
 150  
 151          $this->assertEquals(1, count($result['areas']));
 152          $this->assertEquals(1, count($result['areas'][0]['definitions']));
 153          $definition = $result['areas'][0]['definitions'][0];
 154  
 155          $this->assertEquals($rubricdefinition['method'], $definition['method']);
 156          $this->assertEquals($USER->id, $definition['usercreated']);
 157  
 158          require_once("$CFG->dirroot/grade/grading/lib.php");
 159          require_once($CFG->dirroot.'/grade/grading/form/'.$rubricdefinition['method'].'/lib.php');
 160  
 161          $gradingmanager = get_grading_manager($areaid);
 162  
 163          $this->assertEquals(1, count($definition[$rubricdefinition['method']]));
 164  
 165          $rubricdetails = $definition[$rubricdefinition['method']];
 166          $details = call_user_func('gradingform_'.$rubricdefinition['method'].'_controller::get_external_definition_details');
 167  
 168          $this->assertEquals(2, count($rubricdetails[key($details)]));
 169  
 170          $found = false;
 171          foreach ($rubricdetails[key($details)] as $criterion) {
 172              if ($criterion['id'] == $criterionid1) {
 173                  $this->assertEquals($rubriccriteria1['description'], $criterion['description']);
 174                  $this->assertEquals(2, count($criterion['levels']));
 175                  $found = true;
 176                  break;
 177              }
 178          }
 179          $this->assertTrue($found);
 180      }
 181  
 182      /**
 183       * Test get_gradingform_instances
 184       */
 185      public function test_get_gradingform_instances() {
 186          global $DB, $USER;
 187  
 188          $this->resetAfterTest(true);
 189          // Create a course and assignment.
 190          $coursedata['idnumber'] = 'idnumbercourse';
 191          $coursedata['fullname'] = 'Lightwork Course';
 192          $coursedata['summary'] = 'Lightwork Course description';
 193          $coursedata['summaryformat'] = FORMAT_MOODLE;
 194          $course = self::getDataGenerator()->create_course($coursedata);
 195  
 196          $assigndata['course'] = $course->id;
 197          $assigndata['name'] = 'lightwork assignment';
 198  
 199          $assign = self::getDataGenerator()->create_module('assign', $assigndata);
 200  
 201          // Create manual enrolment record.
 202          $manualenroldata['enrol'] = 'manual';
 203          $manualenroldata['status'] = 0;
 204          $manualenroldata['courseid'] = $course->id;
 205          $enrolid = $DB->insert_record('enrol', $manualenroldata);
 206  
 207          // Create a teacher and give them capabilities.
 208          $coursecontext = \context_course::instance($course->id);
 209          $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $coursecontext->id, 3);
 210          $modulecontext = \context_module::instance($assign->cmid);
 211          $this->assignUserCapability('mod/assign:grade', $modulecontext->id, $roleid);
 212  
 213          // Create the teacher's enrolment record.
 214          $userenrolmentdata['status'] = 0;
 215          $userenrolmentdata['enrolid'] = $enrolid;
 216          $userenrolmentdata['userid'] = $USER->id;
 217          $DB->insert_record('user_enrolments', $userenrolmentdata);
 218  
 219          // Create a student with an assignment grade.
 220          $student = self::getDataGenerator()->create_user();
 221          $assigngrade = new \stdClass();
 222          $assigngrade->assignment = $assign->id;
 223          $assigngrade->userid = $student->id;
 224          $assigngrade->timecreated = time();
 225          $assigngrade->timemodified = $assigngrade->timecreated;
 226          $assigngrade->grader = $USER->id;
 227          $assigngrade->grade = 50;
 228          $assigngrade->attemptnumber = 0;
 229          $gid = $DB->insert_record('assign_grades', $assigngrade);
 230  
 231          // Create a grading area.
 232          $gradingarea = array(
 233              'contextid' => $modulecontext->id,
 234              'component' => 'mod_assign',
 235              'areaname' => 'submissions',
 236              'activemethod' => 'rubric'
 237          );
 238          $areaid = $DB->insert_record('grading_areas', $gradingarea);
 239  
 240          // Create a rubric grading definition.
 241          $rubricdefinition = array (
 242              'areaid' => $areaid,
 243              'method' => 'rubric',
 244              'name' => 'test',
 245              'status' => 20,
 246              'copiedfromid' => 1,
 247              'timecreated' => 1,
 248              'usercreated' => $USER->id,
 249              'timemodified' => 1,
 250              'usermodified' => $USER->id,
 251              'timecopied' => 0
 252          );
 253          $definitionid = $DB->insert_record('grading_definitions', $rubricdefinition);
 254  
 255          // Create a criterion with a level.
 256          $rubriccriteria = array (
 257              'definitionid' => $definitionid,
 258              'sortorder' => 1,
 259              'description' => 'Demonstrate an understanding of disease control',
 260              'descriptionformat' => 0
 261          );
 262          $criterionid = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria);
 263          $rubriclevel = array (
 264              'criterionid' => $criterionid,
 265              'score' => 50,
 266              'definition' => 'pass',
 267              'definitionformat' => 0
 268          );
 269          $levelid = $DB->insert_record('gradingform_rubric_levels', $rubriclevel);
 270  
 271          // Create a grading instance.
 272          $instance = array (
 273              'definitionid' => $definitionid,
 274              'raterid' => $USER->id,
 275              'itemid' => $gid,
 276              'status' => 1,
 277              'feedbackformat' => 0,
 278              'timemodified' => 1
 279          );
 280          $instanceid = $DB->insert_record('grading_instances', $instance);
 281  
 282          // Create a filling.
 283          $filling = array (
 284              'instanceid' => $instanceid,
 285              'criterionid' => $criterionid,
 286              'levelid' => $levelid,
 287              'remark' => 'excellent work',
 288              'remarkformat' => 0
 289          );
 290          $DB->insert_record('gradingform_rubric_fillings', $filling);
 291  
 292          // Call the external function.
 293          $result = core_grading_external::get_gradingform_instances($definitionid, 0);
 294          $result = external_api::clean_returnvalue(core_grading_external::get_gradingform_instances_returns(), $result);
 295  
 296          $this->assertEquals(1, count($result['instances']));
 297          $this->assertEquals($USER->id, $result['instances'][0]['raterid']);
 298          $this->assertEquals($gid, $result['instances'][0]['itemid']);
 299          $this->assertEquals(1, $result['instances'][0]['status']);
 300          $this->assertEquals(1, $result['instances'][0]['timemodified']);
 301          $this->assertEquals(1, count($result['instances'][0]['rubric']));
 302          $this->assertEquals(1, count($result['instances'][0]['rubric']['criteria']));
 303          $criteria = $result['instances'][0]['rubric']['criteria'];
 304          $this->assertEquals($criterionid, $criteria[0]['criterionid']);
 305          $this->assertEquals($levelid, $criteria[0]['levelid']);
 306          $this->assertEquals('excellent work', $criteria[0]['remark']);
 307      }
 308  
 309      /**
 310       *
 311       * Test save_definitions for rubric grading method
 312       */
 313      public function test_save_definitions_rubric() {
 314          global $DB, $CFG, $USER;
 315  
 316          $this->resetAfterTest(true);
 317          // Create a course and assignment.
 318          $course = self::getDataGenerator()->create_course();
 319          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
 320          $params['course'] = $course->id;
 321          $instance = $generator->create_instance($params);
 322          $cm = get_coursemodule_from_instance('assign', $instance->id);
 323          $context = \context_module::instance($cm->id);
 324          $coursecontext = \context_course::instance($course->id);
 325  
 326          // Create the teacher.
 327          $teacher = self::getDataGenerator()->create_user();
 328          $USER->id = $teacher->id;
 329          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 330          $this->assignUserCapability('moodle/grade:managegradingforms', $context->id, $teacherrole->id);
 331          $this->getDataGenerator()->enrol_user($teacher->id,
 332                                                $course->id,
 333                                                $teacherrole->id);
 334  
 335          // The grading area to insert.
 336          $gradingarea = array(
 337              'cmid' => $cm->id,
 338              'contextid' => $context->id,
 339              'component' => 'mod_assign',
 340              'areaname'  => 'submissions',
 341              'activemethod' => 'rubric'
 342          );
 343  
 344          // The rubric definition to insert.
 345          $rubricdefinition = array(
 346              'method' => 'rubric',
 347              'name' => 'test',
 348              'description' => '',
 349              'status' => 20,
 350              'copiedfromid' => 1,
 351              'timecreated' => 1,
 352              'usercreated' => $teacher->id,
 353              'timemodified' => 1,
 354              'usermodified' => $teacher->id,
 355              'timecopied' => 0
 356          );
 357  
 358          // The criterion to insert.
 359          $rubriccriteria1 = array (
 360               'sortorder' => 1,
 361               'description' => 'Demonstrate an understanding of disease control',
 362               'descriptionformat' => 0
 363          );
 364  
 365          // 3 levels for the criterion.
 366          $rubriclevel1 = array (
 367              'score' => 50,
 368              'definition' => 'pass',
 369              'definitionformat' => 0
 370          );
 371          $rubriclevel2 = array (
 372              'score' => 100,
 373              'definition' => 'excellent',
 374              'definitionformat' => 0
 375          );
 376          $rubriclevel3 = array (
 377              'score' => 0,
 378              'definition' => 'fail',
 379              'definitionformat' => 0
 380          );
 381  
 382          $rubriccriteria1['levels'] = array($rubriclevel1, $rubriclevel2, $rubriclevel3);
 383          $rubricdefinition['rubric'] = array('rubric_criteria' => array($rubriccriteria1));
 384          $gradingarea['definitions'] = array($rubricdefinition);
 385  
 386          $results = core_grading_external::save_definitions(array($gradingarea));
 387  
 388          $area = $DB->get_record('grading_areas',
 389                                  array('contextid' => $context->id, 'component' => 'mod_assign', 'areaname' => 'submissions'),
 390                                  '*', MUST_EXIST);
 391          $this->assertEquals($area->activemethod, 'rubric');
 392  
 393          $definition = $DB->get_record('grading_definitions', array('areaid' => $area->id, 'method' => 'rubric'), '*', MUST_EXIST);
 394          $this->assertEquals($rubricdefinition['name'], $definition->name);
 395  
 396          $criterion1 = $DB->get_record('gradingform_rubric_criteria', array('definitionid' => $definition->id), '*', MUST_EXIST);
 397          $levels = $DB->get_records('gradingform_rubric_levels', array('criterionid' => $criterion1->id));
 398          $validlevelcount = 0;
 399          $expectedvalue = true;
 400          foreach ($levels as $level) {
 401              if ($level->score == 0) {
 402                  $this->assertEquals('fail', $level->definition);
 403                  $validlevelcount++;
 404              } else if ($level->score == 50) {
 405                  $this->assertEquals('pass', $level->definition);
 406                  $validlevelcount++;
 407              } else if ($level->score == 100) {
 408                  $this->assertEquals('excellent', $level->definition);
 409                  $excellentlevelid = $level->id;
 410                  $validlevelcount++;
 411              } else {
 412                  $expectedvalue = false;
 413              }
 414          }
 415          $this->assertEquals(3, $validlevelcount);
 416          $this->assertTrue($expectedvalue, 'A level with an unexpected score was found');
 417  
 418          // Test add a new level and modify an existing.
 419          // Test add a new criteria and modify an existing.
 420          // Test modify a definition.
 421  
 422          // The rubric definition to update.
 423          $rubricdefinition = array(
 424              'id' => $definition->id,
 425              'method' => 'rubric',
 426              'name' => 'test changed',
 427              'description' => '',
 428              'status' => 20,
 429              'copiedfromid' => 1,
 430              'timecreated' => 1,
 431              'usercreated' => $teacher->id,
 432              'timemodified' => 1,
 433              'usermodified' => $teacher->id,
 434              'timecopied' => 0
 435          );
 436  
 437          // A criterion to update.
 438          $rubriccriteria1 = array (
 439               'id' => $criterion1->id,
 440               'sortorder' => 1,
 441               'description' => 'Demonstrate an understanding of rabies control',
 442               'descriptionformat' => 0
 443          );
 444  
 445          // A new criterion to add.
 446          $rubriccriteria2 = array (
 447               'sortorder' => 2,
 448               'description' => 'Demonstrate an understanding of anthrax control',
 449               'descriptionformat' => 0
 450          );
 451  
 452          // A level to update.
 453          $rubriclevel2 = array (
 454              'id' => $excellentlevelid,
 455              'score' => 75,
 456              'definition' => 'excellent',
 457              'definitionformat' => 0
 458          );
 459  
 460          // A level to insert.
 461          $rubriclevel4 = array (
 462              'score' => 100,
 463              'definition' => 'superb',
 464              'definitionformat' => 0
 465          );
 466  
 467          $rubriccriteria1['levels'] = array($rubriclevel1, $rubriclevel2, $rubriclevel3, $rubriclevel4);
 468          $rubricdefinition['rubric'] = array('rubric_criteria' => array($rubriccriteria1, $rubriccriteria2));
 469          $gradingarea['definitions'] = array($rubricdefinition);
 470  
 471          $results = core_grading_external::save_definitions(array($gradingarea));
 472  
 473          // Test definition name change.
 474          $definition = $DB->get_record('grading_definitions', array('id' => $definition->id), '*', MUST_EXIST);
 475          $this->assertEquals('test changed', $definition->name);
 476  
 477          // Test criteria description change.
 478          $modifiedcriteria = $DB->get_record('gradingform_rubric_criteria', array('id' => $criterion1->id), '*', MUST_EXIST);
 479          $this->assertEquals('Demonstrate an understanding of rabies control', $modifiedcriteria->description);
 480  
 481          // Test new criteria added.
 482          $newcriteria = $DB->get_record('gradingform_rubric_criteria',
 483                                         array('definitionid' => $definition->id, 'sortorder' => 2), '*', MUST_EXIST);
 484          $this->assertEquals('Demonstrate an understanding of anthrax control', $newcriteria->description);
 485  
 486          // Test excellent level score change from 100 to 75.
 487          $modifiedlevel = $DB->get_record('gradingform_rubric_levels', array('id' => $excellentlevelid), '*', MUST_EXIST);
 488          $this->assertEquals(75, $modifiedlevel->score);
 489  
 490          // Test new superb level added.
 491          $newlevel = $DB->get_record('gradingform_rubric_levels',
 492                                         array('criterionid' => $criterion1->id, 'score' => 100), '*', MUST_EXIST);
 493          $this->assertEquals('superb', $newlevel->definition);
 494  
 495          // Test remove a level
 496          // Test remove a criterion
 497          // The rubric definition with the removed criterion and levels.
 498          $rubricdefinition = array(
 499              'id' => $definition->id,
 500              'method' => 'rubric',
 501              'name' => 'test changed',
 502              'description' => '',
 503              'status' => 20,
 504              'copiedfromid' => 1,
 505              'timecreated' => 1,
 506              'usercreated' => $teacher->id,
 507              'timemodified' => 1,
 508              'usermodified' => $teacher->id,
 509              'timecopied' => 0
 510          );
 511  
 512          $rubriccriteria1 = array (
 513               'id' => $criterion1->id,
 514               'sortorder' => 1,
 515               'description' => 'Demonstrate an understanding of rabies control',
 516               'descriptionformat' => 0
 517          );
 518  
 519          $rubriclevel1 = array (
 520              'score' => 0,
 521              'definition' => 'fail',
 522              'definitionformat' => 0
 523          );
 524          $rubriclevel2 = array (
 525              'score' => 100,
 526              'definition' => 'pass',
 527              'definitionformat' => 0
 528          );
 529  
 530          $rubriccriteria1['levels'] = array($rubriclevel1, $rubriclevel2);
 531          $rubricdefinition['rubric'] = array('rubric_criteria' => array($rubriccriteria1));
 532          $gradingarea['definitions'] = array($rubricdefinition);
 533  
 534          $results = core_grading_external::save_definitions(array($gradingarea));
 535  
 536          // Only 1 criterion should now exist.
 537          $this->assertEquals(1, $DB->count_records('gradingform_rubric_criteria', array('definitionid' => $definition->id)));
 538          $criterion1 = $DB->get_record('gradingform_rubric_criteria', array('definitionid' => $definition->id), '*', MUST_EXIST);
 539          $this->assertEquals('Demonstrate an understanding of rabies control', $criterion1->description);
 540          // This criterion should only have 2 levels.
 541          $this->assertEquals(2, $DB->count_records('gradingform_rubric_levels', array('criterionid' => $criterion1->id)));
 542  
 543          $gradingarea['activemethod'] = 'invalid';
 544          $this->expectException('moodle_exception');
 545          $results = core_grading_external::save_definitions(array($gradingarea));
 546      }
 547  
 548      /**
 549       *
 550       * Tests save_definitions for the marking guide grading method
 551       */
 552      public function test_save_definitions_marking_guide() {
 553          global $DB, $CFG, $USER;
 554  
 555          $this->resetAfterTest(true);
 556          // Create a course and assignment.
 557          $course = self::getDataGenerator()->create_course();
 558          $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
 559          $params['course'] = $course->id;
 560          $instance = $generator->create_instance($params);
 561          $cm = get_coursemodule_from_instance('assign', $instance->id);
 562          $context = \context_module::instance($cm->id);
 563          $coursecontext = \context_course::instance($course->id);
 564  
 565          // Create the teacher.
 566          $teacher = self::getDataGenerator()->create_user();
 567          $USER->id = $teacher->id;
 568          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 569          $this->assignUserCapability('moodle/grade:managegradingforms', $context->id, $teacherrole->id);
 570          $this->getDataGenerator()->enrol_user($teacher->id,
 571                                                $course->id,
 572                                                $teacherrole->id);
 573  
 574          // Test insert a grading area with guide definition, criteria and comments.
 575          $gradingarea = array(
 576              'cmid' => $cm->id,
 577              'contextid' => $context->id,
 578              'component' => 'mod_assign',
 579              'areaname'  => 'submissions',
 580              'activemethod' => 'guide'
 581          );
 582  
 583          $guidedefinition = array(
 584              'method' => 'guide',
 585              'name' => 'test',
 586              'description' => '',
 587              'status' => 20,
 588              'copiedfromid' => 1,
 589              'timecreated' => 1,
 590              'usercreated' => $teacher->id,
 591              'timemodified' => 1,
 592              'usermodified' => $teacher->id,
 593              'timecopied' => 0
 594          );
 595  
 596          $guidecomment = array(
 597               'sortorder' => 1,
 598               'description' => 'Students need to show that they understand the control of zoonoses',
 599               'descriptionformat' => 0
 600          );
 601          $guidecriteria1 = array (
 602               'sortorder' => 1,
 603               'shortname' => 'Rabies Control',
 604               'description' => 'Understand rabies control techniques',
 605               'descriptionformat' => 0,
 606               'descriptionmarkers' => 'Student must demonstrate that they understand rabies control',
 607               'descriptionmarkersformat' => 0,
 608               'maxscore' => 50
 609          );
 610          $guidecriteria2 = array (
 611               'sortorder' => 2,
 612               'shortname' => 'Anthrax Control',
 613               'description' => 'Understand anthrax control',
 614               'descriptionformat' => 0,
 615               'descriptionmarkers' => 'Student must demonstrate that they understand anthrax control',
 616               'descriptionmarkersformat' => 0,
 617               'maxscore' => 50
 618          );
 619  
 620          $guidedefinition['guide'] = array('guide_criteria' => array($guidecriteria1, $guidecriteria2),
 621                                            'guide_comments' => array($guidecomment));
 622          $gradingarea['definitions'] = array($guidedefinition);
 623  
 624          $results = core_grading_external::save_definitions(array($gradingarea));
 625          $area = $DB->get_record('grading_areas',
 626                                  array('contextid' => $context->id, 'component' => 'mod_assign', 'areaname' => 'submissions'),
 627                                  '*', MUST_EXIST);
 628          $this->assertEquals($area->activemethod, 'guide');
 629  
 630          $definition = $DB->get_record('grading_definitions', array('areaid' => $area->id, 'method' => 'guide'), '*', MUST_EXIST);
 631          $this->assertEquals($guidedefinition['name'], $definition->name);
 632          $this->assertEquals(2, $DB->count_records('gradingform_guide_criteria', array('definitionid' => $definition->id)));
 633          $this->assertEquals(1, $DB->count_records('gradingform_guide_comments', array('definitionid' => $definition->id)));
 634  
 635          // Test removal of a criteria.
 636          $guidedefinition['guide'] = array('guide_criteria' => array($guidecriteria1),
 637                                            'guide_comments' => array($guidecomment));
 638          $gradingarea['definitions'] = array($guidedefinition);
 639          $results = core_grading_external::save_definitions(array($gradingarea));
 640          $this->assertEquals(1, $DB->count_records('gradingform_guide_criteria', array('definitionid' => $definition->id)));
 641  
 642          // Test an invalid method in the definition.
 643          $guidedefinition['method'] = 'invalid';
 644          $gradingarea['definitions'] = array($guidedefinition);
 645          $this->expectException('invalid_parameter_exception');
 646          $results = core_grading_external::save_definitions(array($gradingarea));
 647      }
 648  }