]> git.mjollnir.org Git - moodle.git/commitdiff
Managed to remove static calls from the core gradebook classes without removing suppo...
authornicolasconnault <nicolasconnault>
Tue, 13 Nov 2007 07:36:00 +0000 (07:36 +0000)
committernicolasconnault <nicolasconnault>
Tue, 13 Nov 2007 07:36:00 +0000 (07:36 +0000)
14 files changed:
lib/grade/grade_category.php
lib/grade/grade_grade.php
lib/grade/grade_item.php
lib/grade/grade_object.php
lib/grade/grade_outcome.php
lib/grade/grade_scale.php
lib/grade/lib_wrapper.php [new file with mode: 0644]
lib/grade/simpletest/testgradecategory.php
lib/grade/simpletest/testgradegrades.php
lib/grade/simpletest/testgradeoutcome.php
lib/grade/simpletest/testgradescale.php
lib/gradelib.php
lib/simpletest/fixtures/gradetest.php
lib/simpletestlib/mock_objects.php

index ef489bc543228ca6de098167e9c59cf59a46b1cb..815999d10aa516a8bf6ad9e598e5153bbcfe5e72 100644 (file)
@@ -157,8 +157,8 @@ class grade_category extends grade_object {
         if (empty($grade_category->parent)) {
             return '/'.$grade_category->id.'/';
         } else {
-            $parent = get_record('grade_categories', 'id', $grade_category->parent);
-            return grade_category::build_path($parent).$grade_category->id.'/';
+            $parent = $this->lib_wrapper->get_record('grade_categories', 'id', $grade_category->parent);
+            return $this->build_path($parent).$grade_category->id.'/';
         }
     }
 
@@ -170,7 +170,7 @@ class grade_category extends grade_object {
      * @return object grade_category instance or false if none found.
      */
     function fetch($params) {
-        return grade_object::fetch_helper('grade_categories', 'grade_category', $params);
+        return $this->fetch_helper('grade_categories', 'grade_category', $params);
     }
 
     /**
@@ -181,7 +181,7 @@ class grade_category extends grade_object {
      * @return array array of grade_category insatnces or false if none found.
      */
     function fetch_all($params) {
-        return grade_object::fetch_all_helper('grade_categories', 'grade_category', $params);
+        return $this->fetch_all_helper('grade_categories', 'grade_category', $params);
     }
 
     /**
@@ -195,7 +195,7 @@ class grade_category extends grade_object {
 
         // force recalculation of path;
         if (empty($this->path)) {
-            $this->path  = grade_category::build_path($this);
+            $this->path  = $this->build_path($this);
             $this->depth = substr_count($this->path, '/') - 1;
         }
 
@@ -227,7 +227,7 @@ class grade_category extends grade_object {
         $grade_item = $this->load_grade_item();
 
         if ($this->is_course_category()) {
-            if ($categories = grade_category::fetch_all(array('courseid'=>$this->courseid))) {
+            if ($categories = $this->fetch_all(array('courseid'=>$this->courseid))) {
                 foreach ($categories as $category) {
                     if ($category->id == $this->id) {
                         continue; // do not delete course category yet
@@ -236,7 +236,7 @@ class grade_category extends grade_object {
                 }
             }
 
-            if ($items = grade_item::fetch_all(array('courseid'=>$this->courseid))) {
+            if ($items = $grade_item->fetch_all(array('courseid'=>$this->courseid))) {
                 foreach ($items as $item) {
                     if ($item->id == $grade_item->id) {
                         continue; // do not delete course item yet
@@ -251,12 +251,12 @@ class grade_category extends grade_object {
             $parent = $this->load_parent_category();
 
             // Update children's categoryid/parent field first
-            if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
+            if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                 foreach ($children as $child) {
                     $child->set_parent($parent->id);
                 }
             }
-            if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
+            if ($children = $this->fetch_all(array('parent'=>$this->id))) {
                 foreach ($children as $child) {
                     $child->set_parent($parent->id);
                 }
@@ -287,7 +287,7 @@ class grade_category extends grade_object {
         }
 
         if (empty($this->parent)) {
-            $course_category = grade_category::fetch_course_category($this->courseid);
+            $course_category = $this->fetch_course_category($this->courseid);
             $this->parent = $course_category->id;
         }
 
@@ -348,7 +348,7 @@ class grade_category extends grade_object {
             return false;
         }
 
-        $db_item = grade_category::fetch(array('id'=>$this->id));
+        $db_item = $this->fetch(array('id'=>$this->id));
 
         $aggregationdiff = $db_item->aggregation         != $this->aggregation;
         $keephighdiff    = $db_item->keephigh            != $this->keephigh;
@@ -403,7 +403,7 @@ class grade_category extends grade_object {
             $sql = "SELECT *
                       FROM {$CFG->prefix}grade_items
                      WHERE id IN ($gis)";
-            $items = get_records_sql($sql);
+            $items = $this->lib_wrapper->get_records_sql($sql);
         }
 
         if ($userid) {
@@ -412,7 +412,7 @@ class grade_category extends grade_object {
             $usersql = "";
         }
 
-        $grade_inst = new grade_grade();
+        $grade_inst = $this->get_instance('grade_grade');
         $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
 
         // where to look for final grades - include grade of this item too, we will store the results there
@@ -423,12 +423,12 @@ class grade_category extends grade_object {
               ORDER BY g.userid";
 
         // group the results by userid and aggregate the grades for this user
-        if ($rs = get_recordset_sql($sql)) {
+        if ($rs = $this->lib_wrapper->get_recordset_sql($sql)) {
             $prevuser = 0;
             $grade_values = array();
             $excluded     = array();
             $oldgrade     = null;
-            while ($used = rs_fetch_next_record($rs)) {
+            while ($used = $this->lib_wrapper->rs_fetch_next_record($rs)) {
                 if ($used->userid != $prevuser) {
                     $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);
                     $prevuser = $used->userid;
@@ -445,7 +445,7 @@ class grade_category extends grade_object {
                 }
             }
             $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);//the last one
-            rs_close($rs);
+            $this->lib_wrapper->rs_close($rs);
         }
 
         return true;
@@ -469,12 +469,12 @@ class grade_category extends grade_object {
         }
 
         if ($oldgrade) {
-            $grade = new grade_grade($oldgrade, false);
+            $grade = $this->get_instance('grade_grade', $oldgrade, false);
             $grade->grade_item =& $this->grade_item;
 
         } else {
             // insert final grade - it will be needed later anyway
-            $grade = new grade_grade(array('itemid'=>$this->grade_item->id, 'userid'=>$userid), false);
+            $grade = $this->get_instance('grade_grade', array('itemid'=>$this->grade_item->id, 'userid'=>$userid), false);
             $grade->insert('system');
             $grade->grade_item =& $this->grade_item;
 
@@ -485,7 +485,9 @@ class grade_category extends grade_object {
             $oldgrade->rawgrademax = $grade->rawgrademax;
             $oldgrade->rawscaleid  = $grade->rawscaleid;
         }
-
+        
+        $grade->itemid = $this->grade_item->id; // For testability, avoids the need for load_grade_item()
+        
         // no need to recalculate locked or overridden grades
         if ($grade->is_locked() or $grade->is_overridden()) {
             return;
@@ -503,7 +505,6 @@ class grade_category extends grade_object {
             }
             return;
         }
-
     /// normalize the grades first - all will have value 0...1
         // ungraded items are not used in aggregation
         foreach ($grade_values as $itemid=>$v) {
@@ -515,8 +516,8 @@ class grade_category extends grade_object {
                 unset($grade_values[$itemid]);
                 continue;
             }
-
-            $grade_values[$itemid] = grade_grade::standardise_score($v, $items[$itemid]->grademin, $items[$itemid]->grademax, 0, 1);
+            $grade_grade = $this->get_instance('grade_grade');
+            $grade_values[$itemid] = $grade_grade->standardise_score($v, $items[$itemid]->grademin, $items[$itemid]->grademax, 0, 1);
         }
 
         // use min grade if grade missing for these types
@@ -551,9 +552,10 @@ class grade_category extends grade_object {
         $grade->rawgrademax = $this->grade_item->grademax;
         $grade->rawscaleid  = $this->grade_item->scaleid;
         $grade->rawgrade    = null; // categories do not use raw grades
-
+        
         // recalculate the rawgrade back to requested range
-        $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
+        $grade_grade= $this->get_instance('grade_grade');
+        $finalgrade = $grade_grade->standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
 
         if (!is_null($finalgrade)) {
             $grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
@@ -689,13 +691,14 @@ class grade_category extends grade_object {
      * @return array
      */
     function fetch_course_tree($courseid, $include_category_items=false) {
-        $course_category = grade_category::fetch_course_category($courseid);
+        $obj = new grade_category();
+        $course_category = $obj->fetch_course_category($courseid);
         $category_array = array('object'=>$course_category, 'type'=>'category', 'depth'=>1,
                                 'children'=>$course_category->get_children($include_category_items));
         $sortorder = 1;
         $course_category->set_sortorder($sortorder);
         $course_category->sortorder = $sortorder;
-        return grade_category::_fetch_course_tree_recursion($category_array, $sortorder);
+        return $obj->_fetch_course_tree_recursion($category_array, $sortorder);
     }
 
     function _fetch_course_tree_recursion($category_array, &$sortorder) {
@@ -719,12 +722,12 @@ class grade_category extends grade_object {
             $cat_item_id = null;
             foreach($category_array['children'] as $oldorder=>$child_array) {
                 if ($child_array['type'] == 'courseitem' or $child_array['type'] == 'categoryitem') {
-                    $result['children'][$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
+                    $result['children'][$sortorder] = $this->_fetch_course_tree_recursion($child_array, $sortorder);
                 }
             }
             foreach($category_array['children'] as $oldorder=>$child_array) {
                 if ($child_array['type'] != 'courseitem' and $child_array['type'] != 'categoryitem') {
-                    $result['children'][++$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
+                    $result['children'][++$sortorder] = $this->_fetch_course_tree_recursion($child_array, $sortorder);
                 }
             }
         }
@@ -744,8 +747,8 @@ class grade_category extends grade_object {
         // fetch all course grade items and categories into memory - we do not expect hundreds of these in course
         // we have to limit the number of queries though, because it will be used often in grade reports
 
-        $cats  = get_records('grade_categories', 'courseid', $this->courseid);
-        $items = get_records('grade_items', 'courseid', $this->courseid);
+        $cats  = $this->lib_wrapper->get_records('grade_categories', 'courseid', $this->courseid);
+        $items = $this->lib_wrapper->get_records('grade_items', 'courseid', $this->courseid);
 
         // init children array first
         foreach ($cats as $catid=>$cat) {
@@ -789,7 +792,6 @@ class grade_category extends grade_object {
 
                 $cats[$cat->parent]->children[$sortorder] = $cat;
             }
-
             if ($catid == $this->id) {
                 $category = &$cats[$catid];
             }
@@ -798,7 +800,7 @@ class grade_category extends grade_object {
         unset($items); // not needed
         unset($cats); // not needed
 
-        $children_array = grade_category::_get_children_recursion($category);
+        $children_array = $this->_get_children_recursion($category);
 
         ksort($children_array);
 
@@ -811,7 +813,7 @@ class grade_category extends grade_object {
         $children_array = array();
         foreach($category->children as $sortorder=>$child) {
             if (array_key_exists('itemtype', $child)) {
-                $grade_item = new grade_item($child, false);
+                $grade_item = $this->get_instance('grade_item', $child, false);
                 if (in_array($grade_item->itemtype, array('course', 'category'))) {
                     $type  = $grade_item->itemtype.'item';
                     $depth = $category->depth;
@@ -822,8 +824,8 @@ class grade_category extends grade_object {
                 $children_array[$sortorder] = array('object'=>$grade_item, 'type'=>$type, 'depth'=>$depth);
 
             } else {
-                $children = grade_category::_get_children_recursion($child);
-                $grade_category = new grade_category($child, false);
+                $children = $this->_get_children_recursion($child);
+                $grade_category = $this->get_instance('grade_category', $child, false);
                 if (empty($children)) {
                     $children = array();
                 }
@@ -865,10 +867,12 @@ class grade_category extends grade_object {
         } else {
             $params = array('courseid'=>$this->courseid, 'itemtype'=>'category', 'iteminstance'=>$this->id);
         }
+        
+        $grade_item = $this->get_instance('grade_item');
 
-        if (!$grade_items = grade_item::fetch_all($params)) {
+        if (!$grade_items = $grade_item->fetch_all($params)) {
             // create a new one
-            $grade_item = new grade_item($params, false);
+            $grade_item = $this->get_instance('grade_item', $params, false);
             $grade_item->gradetype = GRADE_TYPE_VALUE;
             $grade_item->insert('system');
 
@@ -903,7 +907,7 @@ class grade_category extends grade_object {
      */
     function get_parent_category() {
         if (!empty($this->parent)) {
-            $parent_category = new grade_category(array('id' => $this->parent));
+            $parent_category = $this->get_instance('grade_category', array('id' => $this->parent));
             return $parent_category;
         } else {
             return null;
@@ -917,7 +921,7 @@ class grade_category extends grade_object {
      */
     function get_name() {
         if (empty($this->parent)) {
-            $course = get_record('course', 'id', $this->courseid);
+            $course = $this->lib_wrapper->get_record('course', 'id', $this->courseid);
             return format_string($course->fullname);
         } else {
             return $this->fullname;
@@ -943,7 +947,7 @@ class grade_category extends grade_object {
         }
 
         // find parent and check course id
-        if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
+        if (!$parent_category = $this->fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
             return false;
         }
 
@@ -1026,17 +1030,17 @@ class grade_category extends grade_object {
     function fetch_course_category($courseid) {
 
         // course category has no parent
-        if ($course_category = grade_category::fetch(array('courseid'=>$courseid, 'parent'=>null))) {
+        if ($course_category = $this->fetch(array('courseid'=>$courseid, 'parent'=>null))) {
             return $course_category;
         }
 
         // create a new one
-        $course_category = new grade_category();
+        $course_category = $this->get_instance('grade_category');
         $course_category->insert_course_category($courseid);
 
         return $course_category;
     }
-
+    
     /**
      * Is grading object editable?
      * @return boolean
@@ -1070,7 +1074,8 @@ class grade_category extends grade_object {
 
         if ($cascade) {
             //process all children - items and categories
-            if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
+            $grade_item = $this->get_instance('grade_item');
+            if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                 foreach($children as $child) {
                     $child->set_locked($lockedstate, true, false);
                     if (empty($lockedstate) and $refresh) {
@@ -1079,7 +1084,7 @@ class grade_category extends grade_object {
                     }
                 }
             }
-            if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
+            if ($children = $this->fetch_all(array('parent'=>$this->id))) {
                 foreach($children as $child) {
                     $child->set_locked($lockedstate, true, true);
                 }
@@ -1119,12 +1124,13 @@ class grade_category extends grade_object {
         $this->load_grade_item();
         $this->grade_item->set_hidden($hidden);
         if ($cascade) {
-            if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
+            $grade_item = $this->get_instance('grade_item');
+            if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                 foreach($children as $child) {
                     $child->set_hidden($hidden, $cascade);
                 }
             }
-            if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
+            if ($children = $this->fetch_all(array('parent'=>$this->id))) {
                 foreach($children as $child) {
                     $child->set_hidden($hidden, $cascade);
                 }
@@ -1157,7 +1163,7 @@ class grade_category extends grade_object {
     function updated_forced_settings() {
         global $CFG;
         $sql = "UPDATE {$CFG->prefix}grade_items SET needsupdate=1 WHERE itemtype='course' or itemtype='category'";
-        execute_sql($sql, false);
+        $this->lib_wrapper->execute_sql($sql, false);
     }
 }
 ?>
index 32d1e1e5f7d810ee55db308def262efd30b88172..033933880209a2bf11afde80e7b43b442f396637 100644 (file)
@@ -167,20 +167,20 @@ class grade_grade extends grade_object {
             $half = (int)($count/2);
             $first  = array_slice($userids, 0, $half);
             $second = array_slice($userids, $half);
-            return grade_grade::fetch_users_grades($grade_item, $first, $include_missing) + grade_grade::fetch_users_grades($grade_item, $second, $include_missing);
+            return $this->fetch_users_grades($grade_item, $first, $include_missing) + $this->fetch_users_grades($grade_item, $second, $include_missing);
         }
 
         $user_ids_cvs = implode(',', $userids);
         $result = array();
-        if ($grade_records = get_records_select('grade_grades', "itemid={$grade_item->id} AND userid IN ($user_ids_cvs)")) {
+        if ($grade_records = $this->lib_wrapper->get_records_select('grade_grades', "itemid={$grade_item->id} AND userid IN ($user_ids_cvs)")) {
             foreach ($grade_records as $record) {
-                $result[$record->userid] = new grade_grade($record, false);
+                $result[$record->userid] = $this->get_instance('grade_grade', $record, false);
             }
         }
         if ($include_missing) {
             foreach ($userids as $userid) {
                 if (!array_key_exists($userid, $result)) {
-                    $grade_grade = new grade_grade();
+                    $grade_grade = $this->get_instance('grade_grade');
                     $grade_grade->userid = $userid;
                     $grade_grade->itemid = $grade_item->id;
                     $result[$userid] = $grade_grade;
@@ -203,11 +203,12 @@ class grade_grade extends grade_object {
         }
 
         if (empty($this->grade_item)) {
-            $this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
+            $grade_item = $this->get_instance('grade_item');
+            $this->grade_item = $grade_item->fetch(array('id'=>$this->itemid));
 
         } else if ($this->grade_item->id != $this->itemid) {
             debugging('Itemid mismatch');
-            $this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
+            $this->grade_item = $grade_item->fetch(array('id'=>$this->itemid));
         }
 
         return $this->grade_item;
@@ -387,13 +388,13 @@ class grade_grade extends grade_object {
 
         $now = time(); // no rounding needed, this is not supposed to be called every 10 seconds
 
-        if ($rs = get_recordset_select('grade_grades', "itemid IN ($items_sql) AND locked = 0 AND locktime > 0 AND locktime < $now")) {
-            while ($grade = rs_fetch_next_record($rs)) {
-                $grade_grade = new grade_grade($grade, false);
+        if ($rs = $this->lib_wrapper->get_recordset_select('grade_grades', "itemid IN ($items_sql) AND locked = 0 AND locktime > 0 AND locktime < $now")) {
+            while ($grade = $this->lib_wrapper->rs_fetch_next_record($rs)) {
+                $grade_grade = $this->get_instance('grade_grade', $grade, false);
                 $grade_grade->locked = time();
                 $grade_grade->update('locktime');
             }
-            rs_close($rs);
+            $this->lib_wrapper->rs_close($rs);
         }
     }
 
@@ -503,7 +504,7 @@ class grade_grade extends grade_object {
      * @return object grade_grade instance or false if none found.
      */
     function fetch($params) {
-        return grade_object::fetch_helper('grade_grades', 'grade_grade', $params);
+        return $this->fetch_helper('grade_grades', 'grade_grade', $params);
     }
 
     /**
@@ -514,7 +515,7 @@ class grade_grade extends grade_object {
      * @return array array of grade_grade insatnces or false if none found.
      */
     function fetch_all($params) {
-        return grade_object::fetch_all_helper('grade_grades', 'grade_grade', $params);
+        return $this->fetch_all_helper('grade_grades', 'grade_grade', $params);
     }
 
     /**
@@ -555,7 +556,7 @@ class grade_grade extends grade_object {
         global $CFG;
 
         if (count($grade_grades) !== count($grade_items)) {
-            error("Incorrent size of arrays in params of grade_grade::get_hiding_affected()!");
+            error("Incorrent size of arrays in params of $this->get_hiding_affected()!");
         }
 
         $dependson = array();
@@ -627,7 +628,7 @@ class grade_grade extends grade_object {
                                     unset($values[$itemid]);
                                     continue;
                                 }
-                                $values[$itemid] = grade_grade::standardise_score($value, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax, 0, 1);
+                                $values[$itemid] = $this->standardise_score($value, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax, 0, 1);
                             }
 
                             if ($grade_category->aggregateonlygraded) {
@@ -660,7 +661,7 @@ class grade_grade extends grade_object {
                             $agg_grade = $grade_category->aggregate_values($values, $grade_items);
 
                             // recalculate the rawgrade back to requested range
-                            $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $grade_items[$do]->grademin, $grade_items[$do]->grademax);
+                            $finalgrade = $this->standardise_score($agg_grade, 0, 1, $grade_items[$do]->grademin, $grade_items[$do]->grademax);
 
                             if (!is_null($finalgrade)) {
                                 $finalgrade = bounded_number($grade_items[$do]->grademin, $finalgrade, $grade_items[$do]->grademax);
index 45a0fe47a4a24fa00e7f34b74657e1bd5cc45302..a0ecfd7e02fccfbec21af291cdc233997964f068 100644 (file)
@@ -7,7 +7,7 @@
 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
 //          http://moodle.com                                            //
 //                                                                       //
-// Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com       //
+// Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
 //                                                                       //
 // This program is free software; you can redistribute it and/or modify  //
 // it under the terms of the GNU General Public License as published by  //
@@ -24,7 +24,6 @@
 ///////////////////////////////////////////////////////////////////////////
 
 require_once('grade_object.php');
-
 /**
  * Class representing a grade item. It is responsible for handling its DB representation,
  * modifying and returning its metadata.
@@ -281,7 +280,7 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $db_item = new grade_item(array('id' => $this->id));
+        $db_item = $this->get_instance('grade_item', array('id' => $this->id));
 
         $calculationdiff = $db_item->calculation != $this->calculation;
         $categorydiff    = $db_item->categoryid  != $this->categoryid;
@@ -311,7 +310,7 @@ class grade_item extends grade_object {
      * @return object grade_item instance or false if none found.
      */
     function fetch($params) {
-        return grade_object::fetch_helper('grade_items', 'grade_item', $params);
+        return $this->fetch_helper('grade_items', 'grade_item', $params);
     }
 
     /**
@@ -322,7 +321,7 @@ class grade_item extends grade_object {
      * @return array array of grade_item insatnces or false if none found.
      */
     function fetch_all($params) {
-        return grade_object::fetch_all_helper('grade_items', 'grade_item', $params);
+        return $this->fetch_all_helper('grade_items', 'grade_item', $params);
     }
 
     /**
@@ -334,8 +333,9 @@ class grade_item extends grade_object {
         if (!$this->is_course_item()) {
             $this->force_regrading();
         }
-
-        if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
+        
+        $grade_grade = $this->get_instance('grade_grade');
+        if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
             foreach ($grades as $grade) {
                 $grade->delete($source);
             }
@@ -360,14 +360,15 @@ class grade_item extends grade_object {
         $this->load_scale();
 
         // add parent category if needed
+        $grade_category = $this->get_instance('grade_category');
         if (empty($this->categoryid) and !$this->is_course_item() and !$this->is_category_item()) {
-            $course_category = grade_category::fetch_course_category($this->courseid);
+            $course_category = $grade_category->fetch_course_category($this->courseid);
             $this->categoryid = $course_category->id;
 
         }
 
         // always place the new items at the end, move them after insert if needed
-        $last_sortorder = get_field_select('grade_items', 'MAX(sortorder)', "courseid = {$this->courseid}");
+        $last_sortorder = $this->lib_wrapper->get_field_select('grade_items', 'MAX(sortorder)', "courseid = {$this->courseid}");
         if (!empty($last_sortorder)) {
             $this->sortorder = $last_sortorder + 1;
         } else {
@@ -410,13 +411,13 @@ class grade_item extends grade_object {
         }
 
         if ($this->itemtype == 'mod' and !$this->is_outcome_item()) {
-            if (!$cm = get_coursemodule_from_instance($this->itemmodule, $this->iteminstance, $this->courseid)) {
+            if (!$cm = $this->lib_wrapper->get_coursemodule_from_instance($this->itemmodule, $this->iteminstance, $this->courseid)) {
                 return false;
             }
             if (!empty($cm->idnumber)) {
                 return false;
             }
-            if (set_field('course_modules', 'idnumber', addslashes($idnumber), 'id', $cm->id)) {
+            if ($this->lib_wrapper->set_field('course_modules', 'idnumber', addslashes($idnumber), 'id', $cm->id)) {
                 $this->idnumber = $idnumber;
                 return $this->update();
             }
@@ -442,7 +443,8 @@ class grade_item extends grade_object {
         }
 
         if (!empty($userid)) {
-            if ($grade = grade_grade::fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
+            $grade_grade = $this->get_instance('grade_grade');
+            if ($grade = $grade_grade->fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
                 $grade->grade_item =& $this; // prevent db fetching of cached grade_item
                 return $grade->is_locked();
             }
@@ -471,7 +473,7 @@ class grade_item extends grade_object {
             if ($cascade) {
                 $grades = $this->get_final();
                 foreach($grades as $g) {
-                    $grade = new grade_grade($g, false);
+                    $grade = $this->get_instance('grade_grade', $g, false);
                     $grade->grade_item =& $this;
                     $grade->set_locked(1, null, false);
                 }
@@ -490,7 +492,8 @@ class grade_item extends grade_object {
             $this->update();
 
             if ($cascade) {
-                if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
+                $grade_grade = $this->get_instance('grade_grade');
+                if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
                     foreach($grades as $grade) {
                         $grade->grade_item =& $this;
                         $grade->set_locked(0, null, false);
@@ -576,7 +579,8 @@ class grade_item extends grade_object {
         $this->update();
 
         if ($cascade) {
-            if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
+            $grade_grade = $this->get_instance('grade_grade');
+            if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
                 foreach($grades as $grade) {
                     $grade->grade_item =& $this;
                     $grade->set_hidden($hidden, $cascade);
@@ -591,7 +595,7 @@ class grade_item extends grade_object {
      */
     function has_hidden_grades($groupsql="", $groupwheresql="") {
         global $CFG;
-        return get_field_sql("SELECT COUNT(*) FROM {$CFG->prefix}grade_grades g LEFT JOIN "
+        return $this->lib_wrapper->get_field_sql("SELECT COUNT(*) FROM {$CFG->prefix}grade_grades g LEFT JOIN "
                             ."{$CFG->prefix}user u ON g.userid = u.id $groupsql WHERE itemid = $this->id AND hidden = 1 $groupwheresql");
     }
 
@@ -601,7 +605,7 @@ class grade_item extends grade_object {
     function regrading_finished() {
         $this->needsupdate = 0;
         //do not use $this->update() because we do not want this logged in grade_item_history
-        set_field('grade_items', 'needsupdate', 0, 'id', $this->id);
+        $this->lib_wrapper->set_field('grade_items', 'needsupdate', 0, 'id', $this->id);
     }
 
     /**
@@ -655,16 +659,16 @@ class grade_item extends grade_object {
 
         // normal grade item - just new final grades
         $result = true;
-        $grade_inst = new grade_grade();
+        $grade_inst = $this->get_instance('grade_grade');
         $fields = implode(',', $grade_inst->required_fields);
         if ($userid) {
-            $rs = get_recordset_select('grade_grades', "itemid={$this->id} AND userid=$userid", '', $fields);
+            $rs = $this->lib_wrapper->get_recordset_select('grade_grades', "itemid={$this->id} AND userid=$userid", '', $fields);
         } else {
-            $rs = get_recordset('grade_grades', 'itemid', $this->id, '', $fields);
+            $rs = $this->lib_wrapper->get_recordset('grade_grades', 'itemid', $this->id, '', $fields);
         }
         if ($rs) {
-            while ($grade_record = rs_fetch_next_record($rs)) {
-                $grade = new grade_grade($grade_record, false);
+            while ($grade_record = $this->lib_wrapper->rs_fetch_next_record($rs)) {
+                $grade = $this->get_instance('grade_grade', $grade_record, false);
 
                 if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
                     // this grade is locked - final grade must be ok
@@ -679,7 +683,7 @@ class grade_item extends grade_object {
                     }
                 }
             }
-            rs_close($rs);
+            $this->lib_wrapper->rs_close($rs);
         }
 
         return $result;
@@ -709,7 +713,8 @@ class grade_item extends grade_object {
             // Standardise score to the new grade range
             // NOTE: this is not compatible with current assignment grading
             if ($rawmin != $this->grademin or $rawmax != $this->grademax) {
-                $rawgrade = grade_grade::standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
+                $grade_grade = $this->get_instance('grade_grade');
+                $rawgrade = $grade_grade->standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
             }
 
             // Apply other grade_item factors
@@ -734,7 +739,8 @@ class grade_item extends grade_object {
             // Convert scale if needed
             // NOTE: this is not compatible with current assignment grading
             if ($rawmin != $this->grademin or $rawmax != $this->grademax) {
-                $rawgrade = grade_grade::standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
+                $grade_grade = $this->get_instance('grade_grade');
+                $rawgrade = $grade_grade->standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
             }
 
             return (int)bounded_number(0, round($rawgrade+0.00001), $this->grademax);
@@ -758,7 +764,7 @@ class grade_item extends grade_object {
         $this->needsupdate = 1;
         //mark this item and course item only - categories and calculated items are always regraded
         $wheresql = "(itemtype='course' OR id={$this->id}) AND courseid={$this->courseid}";
-        set_field_select('grade_items', 'needsupdate', 1, $wheresql);
+        $this->lib_wrapper->set_field_select('grade_items', 'needsupdate', 1, $wheresql);
     }
 
     /**
@@ -774,7 +780,8 @@ class grade_item extends grade_object {
         if (!empty($this->scaleid)) {
             //do not load scale if already present
             if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
-                $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
+                $grade_scale = $this->get_instance('grade_scale');
+                $this->scale = $grade_scale->fetch(array('id'=>$this->scaleid));
                 $this->scale->load_items();
             }
 
@@ -797,7 +804,8 @@ class grade_item extends grade_object {
      */
     function load_outcome() {
         if (!empty($this->outcomeid)) {
-            $this->outcome = grade_outcome::fetch(array('id'=>$this->outcomeid));
+            $grade_outcome = $this->get_instance('grade_outcome');
+            $this->outcome = $grade_outcome->fetch(array('id'=>$this->outcomeid));
         }
         return $this->outcome;
     }
@@ -813,7 +821,8 @@ class grade_item extends grade_object {
             return $this->get_item_category();
 
         } else {
-            return grade_category::fetch(array('id'=>$this->categoryid));
+            $grade_category = $this->get_instance('grade_category');
+            return $grade_category->fetch(array('id'=>$this->categoryid));
         }
     }
 
@@ -838,7 +847,8 @@ class grade_item extends grade_object {
         if (!$this->is_course_item() and !$this->is_category_item()) {
             return false;
         }
-        return grade_category::fetch(array('id'=>$this->iteminstance));
+        $grade_category = $this->get_instance('grade_category');
+        return $grade_category->fetch(array('id'=>$this->iteminstance));
     }
 
     /**
@@ -915,14 +925,16 @@ class grade_item extends grade_object {
      * @return course item object
      */
     function fetch_course_item($courseid) {
-        if ($course_item = grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'))) {
+        $obj = new grade_item();
+        if ($course_item = $obj->fetch(array('courseid'=>$courseid, 'itemtype'=>'course'))) {
             return $course_item;
         }
 
         // first get category - it creates the associated grade item
-        $course_category = grade_category::fetch_course_category($courseid);
+        $grade_category = $obj->get_instance('grade_category');
+        $course_category = $grade_category->fetch_course_category($courseid);
 
-        return grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'));
+        return $obj->fetch(array('courseid'=>$courseid, 'itemtype'=>'course'));
     }
 
     /**
@@ -962,7 +974,7 @@ class grade_item extends grade_object {
      */
     function get_calculation() {
         if ($this->is_calculated()) {
-            return grade_item::denormalize_formula($this->calculation, $this->courseid);
+            return $this->denormalize_formula($this->calculation, $this->courseid);
 
         } else {
             return NULL;
@@ -977,7 +989,7 @@ class grade_item extends grade_object {
      * @return boolean success
      */
     function set_calculation($formula) {
-        $this->calculation = grade_item::normalize_formula($formula, $this->courseid);
+        $this->calculation = $this->normalize_formula($formula, $this->courseid);
         $this->calculation_normalized = true;
         return $this->update();
     }
@@ -996,7 +1008,7 @@ class grade_item extends grade_object {
         // denormalize formula - convert ##giXX## to [[idnumber]]
         if (preg_match_all('/##gi(\d+)##/', $formula, $matches)) {
             foreach ($matches[1] as $id) {
-                if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
+                if ($grade_item = $this->fetch(array('id'=>$id, 'courseid'=>$courseid))) {
                     if (!empty($grade_item->idnumber)) {
                         $formula = str_replace('##gi'.$grade_item->id.'##', '[['.$grade_item->idnumber.']]', $formula);
                     }
@@ -1023,7 +1035,7 @@ class grade_item extends grade_object {
         }
 
         // normalize formula - we want grade item ids ##giXXX## instead of [[idnumber]]
-        if ($grade_items = grade_item::fetch_all(array('courseid'=>$courseid))) {
+        if ($grade_items = $this->fetch_all(array('courseid'=>$courseid))) {
             foreach ($grade_items as $grade_item) {
                 $formula = str_replace('[['.$grade_item->idnumber.']]', '##gi'.$grade_item->id.'##', $formula);
             }
@@ -1039,12 +1051,12 @@ class grade_item extends grade_object {
      */
     function get_final($userid=NULL) {
         if ($userid) {
-            if ($user = get_record('grade_grades', 'itemid', $this->id, 'userid', $userid)) {
+            if ($user = $this->lib_wrapper->get_record('grade_grades', 'itemid', $this->id, 'userid', $userid)) {
                 return $user;
             }
 
         } else {
-            if ($grades = get_records('grade_grades', 'itemid', $this->id)) {
+            if ($grades = $this->lib_wrapper->get_records('grade_grades', 'itemid', $this->id)) {
                 //TODO: speed up with better SQL
                 $result = array();
                 foreach ($grades as $grade) {
@@ -1068,7 +1080,7 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $grade = new grade_grade(array('userid'=>$userid, 'itemid'=>$this->id));
+        $grade = $this->get_instance('grade_grade', array('userid'=>$userid, 'itemid'=>$this->id));
         if (empty($grade->id) and $create) {
             $grade->insert();
         }
@@ -1121,7 +1133,7 @@ class grade_item extends grade_object {
         $sql = "UPDATE {$CFG->prefix}grade_items
                    SET sortorder = sortorder + 1
                  WHERE sortorder > $sortorder AND courseid = {$this->courseid}";
-        execute_sql($sql, false);
+        $this->lib_wrapper->execute_sql($sql, false);
 
         $this->set_sortorder($sortorder + 1);
     }
@@ -1162,7 +1174,8 @@ class grade_item extends grade_object {
         }
 
         // find parent and check course id
-        if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
+        $grade_category = $this->get_instance('grade_category');
+        if (!$parent_category = $grade_category->fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
             return false;
         }
 
@@ -1247,7 +1260,7 @@ class grade_item extends grade_object {
                                $outcomes_sql";
             }
 
-            if ($children = get_records_sql($sql)) {
+            if ($children = $this->lib_wrapper->get_records_sql($sql)) {
                 $this->dependson_cache = array_keys($children);
                 return $this->dependson_cache;
             } else {
@@ -1272,12 +1285,12 @@ class grade_item extends grade_object {
                 return;
             }
 
-            if (!$activity = get_record($this->itemmodule, 'id', $this->iteminstance)) {
+            if (!$activity = $this->lib_wrapper->get_record($this->itemmodule, 'id', $this->iteminstance)) {
                 debugging("Can not find $this->itemmodule activity with id $this->iteminstance");
                 return;
             }
 
-            if (!$cm = get_coursemodule_from_instance($this->itemmodule, $activity->id, $this->courseid)) {
+            if (!$cm = $this->lib_wrapper->get_coursemodule_from_instance($this->itemmodule, $activity->id, $this->courseid)) {
                 debugging('Can not find course module');
                 return;
             }
@@ -1313,7 +1326,7 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+        $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid));
         $grade->grade_item =& $this; // prevent db fetching of this grade_item
 
         if (empty($usermodified)) {
@@ -1392,7 +1405,7 @@ class grade_item extends grade_object {
             }
 
         } else if (!$this->needsupdate) {
-            $course_item = grade_item::fetch_course_item($this->courseid);
+            $course_item = $this->fetch_course_item($this->courseid);
             if (!$course_item->needsupdate) {
                 if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                     $this->force_regrading();
@@ -1432,7 +1445,7 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+        $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid));
         $grade->grade_item =& $this; // prevent db fetching of this grade_item
 
         if (empty($usermodified)) {
@@ -1512,7 +1525,7 @@ class grade_item extends grade_object {
             $this->force_regrading();
 
         } else if (!$this->needsupdate) {
-            $course_item = grade_item::fetch_course_item($this->courseid);
+            $course_item = $this->fetch_course_item($this->courseid);
             if (!$course_item->needsupdate) {
                 if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                     $this->force_regrading();
@@ -1560,7 +1573,7 @@ class grade_item extends grade_object {
             $usersql = "";
         }
 
-        $grade_inst = new grade_grade();
+        $grade_inst = $this->get_instance('grade_grade');
         $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
 
         $sql = "SELECT $fields
@@ -1571,11 +1584,11 @@ class grade_item extends grade_object {
         $return = true;
 
         // group the grades by userid and use formula on the group
-        if ($rs = get_recordset_sql($sql)) {
+        if ($rs = $this->lib_wrapper->get_recordset_sql($sql)) {
             $prevuser = 0;
             $grade_records   = array();
             $oldgrade    = null;
-            while ($used = rs_fetch_next_record($rs)) {
+            while ($used = $this->lib_wrapper->rs_fetch_next_record($rs)) {
                 if ($used->userid != $prevuser) {
                     if (!$this->use_formula($prevuser, $grade_records, $useditems, $oldgrade)) {
                         $return = false;
@@ -1593,7 +1606,7 @@ class grade_item extends grade_object {
                 $return = false;
             }
         }
-        rs_close($rs);
+        $this->lib_wrapper->rs_close($rs);
 
         return $return;
     }
@@ -1621,11 +1634,11 @@ class grade_item extends grade_object {
 
         // insert final grade - will be needed later anyway
         if ($oldgrade) {
-            $grade = new grade_grade($oldgrade, false); // fetching from db is not needed
+            $grade = $this->get_instance('grade_grade', $oldgrade, false); // fetching from db is not needed
             $grade->grade_item =& $this;
 
         } else {
-            $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid), false);
+            $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid), false);
             $grade->insert('system');
             $grade->grade_item =& $this;
 
@@ -1687,7 +1700,7 @@ class grade_item extends grade_object {
         global $CFG;
         require_once($CFG->libdir.'/mathslib.php');
 
-        $formulastr = grade_item::normalize_formula($formulastr, $this->courseid);
+        $formulastr = $this->normalize_formula($formulastr, $this->courseid);
 
         if (empty($formulastr)) {
             return true;
@@ -1727,7 +1740,7 @@ class grade_item extends grade_object {
                       FROM {$CFG->prefix}grade_items gi
                      WHERE gi.id IN ($gis) and gi.courseid={$this->courseid}"; // from the same course only!
 
-            if (!$grade_items = get_records_sql($sql)) {
+            if (!$grade_items = $this->lib_wrapper->get_records_sql($sql)) {
                 $grade_items = array();
             }
         }
index b730ee81afe5428f01ff3eaa5d728fb7f21b2e6c..79b1379c25338b3b0b22551aa1b890fe77160392 100644 (file)
@@ -59,6 +59,12 @@ class grade_object {
      */
     var $timemodified;
 
+    /**
+     * A wrapper object around moodle procedural functions (especially dmllib).
+     * @var object $lib_wrapper
+     */
+    var $lib_wrapper;
+
     /**
      * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
      * @param array $params an array with required parameters for this grade object.
@@ -66,21 +72,23 @@ class grade_object {
      *        optional fields might not be defined if false used
      */
     function grade_object($params=NULL, $fetch=true) {
+        $this->lib_wrapper = new grade_lib_wrapper();
+
         if (!empty($params) and (is_array($params) or is_object($params))) {
             if ($fetch) {
                 if ($data = $this->fetch($params)) {
-                    grade_object::set_properties($this, $data);
+                    $this->set_properties($this, $data);
                 } else {
-                    grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
-                    grade_object::set_properties($this, $params);
+                    $this->set_properties($this, $this->optional_fields);//apply defaults for optional fields
+                    $this->set_properties($this, $params);
                 }
 
             } else {
-                grade_object::set_properties($this, $params);
+                $this->set_properties($this, $params);
             }
 
         } else {
-            grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
+            $this->set_properties($this, $this->optional_fields);//apply defaults for optional fields
         }
     }
 
@@ -97,7 +105,7 @@ class grade_object {
             if (empty($this->id)) {
                 $this->$field = $default;
             } else {
-                $this->$field = get_field($this->table, $field, 'id', $this->id);
+                $this->$field = $this->lib_wrapper->get_field($this->table, $field, 'id', $this->id);
             }
         }
     }
@@ -130,7 +138,8 @@ class grade_object {
      * @return mixed object instance or false if not found
      */
     function fetch_helper($table, $classname, $params) {
-        if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
+        $obj = new grade_object();
+        if ($instances = $obj->fetch_all_helper($table, $classname, $params)) {
             if (count($instances) > 1) {
                 // we should not tolerate any errors here - problems might appear later
                 error('Found more than one record in fetch() !');
@@ -147,6 +156,7 @@ class grade_object {
      * @return mixed array of object instances or false if not found
      */
     function fetch_all_helper($table, $classname, $params) {
+        $obj = new grade_object();
         $instance = new $classname();
 
         $classvars = (array)$instance;
@@ -173,11 +183,11 @@ class grade_object {
             $wheresql = implode("AND", $wheresql);
         }
 
-        if ($datas = get_records_select($table, $wheresql, 'id')) {
+        if ($datas = $obj->lib_wrapper->get_records_select($table, $wheresql, 'id')) {
             $result = array();
             foreach($datas as $data) {
                 $instance = new $classname();
-                grade_object::set_properties($instance, $data);
+                $obj->set_properties($instance, $data);
                 $result[$instance->id] = $instance;
             }
             return $result;
@@ -202,7 +212,7 @@ class grade_object {
 
         $data = $this->get_record_data();
 
-        if (!update_record($this->table, addslashes_recursive($data))) {
+        if (!$this->lib_wrapper->update_record($this->table, addslashes_recursive($data))) {
             return false;
         }
 
@@ -213,7 +223,7 @@ class grade_object {
             $data->source       = $source;
             $data->timemodified = time();
             $data->userlogged   = $USER->id;
-            insert_record($this->table.'_history', addslashes_recursive($data));
+            $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
         }
 
         return true;
@@ -234,7 +244,7 @@ class grade_object {
 
         $data = $this->get_record_data();
 
-        if (delete_records($this->table, 'id', $this->id)) {
+        if ($this->lib_wrapper->delete_records($this->table, 'id', $this->id)) {
             if (empty($CFG->disablegradehistory)) {
                 unset($data->id);
                 unset($data->timecreated);
@@ -243,7 +253,7 @@ class grade_object {
                 $data->source       = $source;
                 $data->timemodified = time();
                 $data->userlogged   = $USER->id;
-                insert_record($this->table.'_history', addslashes_recursive($data));
+                $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
             }
             return true;
 
@@ -287,7 +297,7 @@ class grade_object {
 
         $data = $this->get_record_data();
 
-        if (!$this->id = insert_record($this->table, addslashes_recursive($data))) {
+        if (!$this->id = $this->lib_wrapper->insert_record($this->table, addslashes_recursive($data))) {
             debugging("Could not insert object into db");
             return false;
         }
@@ -304,7 +314,7 @@ class grade_object {
             $data->source       = $source;
             $data->timemodified = time();
             $data->userlogged   = $USER->id;
-            insert_record($this->table.'_history', addslashes_recursive($data));
+            $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
         }
 
         return $this->id;
@@ -322,12 +332,12 @@ class grade_object {
             return false;
         }
 
-        if (!$params = get_record($this->table, 'id', $this->id)) {
+        if (!$params = $this->lib_wrapper->get_record($this->table, 'id', $this->id)) {
             debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
             return false;
         }
 
-        grade_object::set_properties($this, $params);
+        $this->set_properties($this, $params);
 
         return true;
     }
@@ -345,5 +355,26 @@ class grade_object {
             }
         }
     }
+    
+    /**
+     * The following function is a helper for making the code more testable. It allows
+     * unit tests to mock the objects instantiated and used within method bodies. If no params are given,
+     * a static instance is returned.
+     */
+    function get_instance($class, $params=NULL, $fetch=true) {
+        $classes = array('grade_item', 'grade_category', 'grade_grade', 'grade_outcome', 'grade_scale');
+        if (!in_array($class, $classes)) {
+            return false;
+        } elseif (is_null($params)) {
+            static $grade_instances = array();  
+            if (!array_key_exists($class, $grade_instances)) {
+                $grade_instances[$class] =& new $class;
+            }
+            $instance =& $grade_instances[$class];
+            return $instance;
+        } else { 
+            return new $class($params, $fetch);
+        }
+    }
 }
 ?>
index ac87126f4ab519df52d9d6b08b0f2403d6b48f2a..f624ad960963f317cb0573bac9e27a61d24bd415 100644 (file)
@@ -92,7 +92,7 @@ class grade_outcome extends grade_object {
      */
     function delete($source=null) {
         if (!empty($this->courseid)) {
-            delete_records('grade_outcomes_courses', 'outcomeid', $this->id, 'courseid', $this->courseid);
+            $this->lib_wrapper->delete_records('grade_outcomes_courses', 'outcomeid', $this->id, 'courseid', $this->courseid);
         }
         return parent::delete($source);
     }
@@ -113,7 +113,7 @@ class grade_outcome extends grade_object {
                 $goc = new object();
                 $goc->courseid = $this->courseid;
                 $goc->outcomeid = $this->id;
-                insert_record('grade_outcomes_courses', $goc);
+                $this->lib_wrapper->insert_record('grade_outcomes_courses', $goc);
             }
         }
         return $result;
@@ -129,11 +129,11 @@ class grade_outcome extends grade_object {
 
         if ($result = parent::update($source)) {
             if (!empty($this->courseid)) {
-                if (!get_records('grade_outcomes_courses', 'courseid', $this->courseid, 'outcomeid', $this->id)) {
+                if (!$this->lib_wrapper->get_records('grade_outcomes_courses', 'courseid', $this->courseid, 'outcomeid', $this->id)) {
                     $goc = new object();
                     $goc->courseid = $this->courseid;
                     $goc->outcomeid = $this->id;
-                    insert_record('grade_outcomes_courses', $goc);
+                    $this->lib_wrapper->insert_record('grade_outcomes_courses', $goc);
                 }
             }
         }
@@ -148,7 +148,7 @@ class grade_outcome extends grade_object {
      * @return object grade_outcome instance or false if none found.
      */
     function fetch($params) {
-        return grade_object::fetch_helper('grade_outcomes', 'grade_outcome', $params);
+        return $this->fetch_helper('grade_outcomes', 'grade_outcome', $params);
     }
 
     /**
@@ -159,7 +159,7 @@ class grade_outcome extends grade_object {
      * @return array array of grade_outcome insatnces or false if none found.
      */
     function fetch_all($params) {
-        return grade_object::fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
+        return $this->fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
     }
 
     /**
@@ -168,7 +168,8 @@ class grade_outcome extends grade_object {
      */
     function load_scale() {
         if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
-            $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
+            $grade_scale = $this->get_instance('grade_scale');
+            $this->scale = $grade_scale->fetch(array('id'=>$this->scaleid));
             $this->scale->load_items();
         }
         return $this->scale;
@@ -180,7 +181,7 @@ class grade_outcome extends grade_object {
      * @return object
      */
     function fetch_all_global() {
-        if (!$outcomes = grade_outcome::fetch_all(array('courseid'=>null))) {
+        if (!$outcomes = $this->fetch_all(array('courseid'=>null))) {
             $outcomes = array();
         }
         return $outcomes;
@@ -193,7 +194,7 @@ class grade_outcome extends grade_object {
      * @return object
      */
     function fetch_all_local($courseid) {
-        if (!$outcomes =grade_outcome::fetch_all(array('courseid'=>$courseid))) {
+        if (!$outcomes =$this->fetch_all(array('courseid'=>$courseid))) {
             $outcomes = array();
         }
         return $outcomes;
@@ -216,8 +217,8 @@ class grade_outcome extends grade_object {
 
         if ($datas = get_records_sql($sql)) {
             foreach($datas as $data) {
-                $instance = new grade_outcome();
-                grade_object::set_properties($instance, $data);
+                $instance = $this->get_instance('grade_outcome');
+                $this->set_properties($instance, $data);
                 $result[$instance->id] = $instance;
             }
         }
@@ -269,7 +270,7 @@ class grade_outcome extends grade_object {
             return 1;
         }
 
-        return count_records('grade_outcomes_courses', 'outcomeid', $this->id);
+        return $this->lib_wrapper->count_records('grade_outcomes_courses', 'outcomeid', $this->id);
     }
 
     /**
@@ -277,7 +278,7 @@ class grade_outcome extends grade_object {
      * @return int
      */
     function get_item_uses_count() {
-        return count_records('grade_items', 'outcomeid', $this->id);
+        return $this->lib_wrapper->count_records('grade_items', 'outcomeid', $this->id);
     }
 
     /**
@@ -301,7 +302,7 @@ class grade_outcome extends grade_object {
         }
 
         if ($average === false && $items === false) {
-            debugging('Either the 1st or 2nd param of grade_outcome::get_grade_info() must be true, or both, but not both false!');
+            debugging('Either the 1st or 2nd param of $this->get_grade_info() must be true, or both, but not both false!');
             return false;
         }
 
@@ -322,7 +323,7 @@ class grade_outcome extends grade_object {
                    AND {$CFG->prefix}grade_outcomes.id = $this->id
                    $wheresql";
 
-        $grades = get_records_sql($sql);
+        $grades = $this->lib_wrapper->get_records_sql($sql);
         $retval = array();
 
         if ($average !== false && count($grades) > 0) {
@@ -343,7 +344,7 @@ class grade_outcome extends grade_object {
 
         if ($items !== false) {
             foreach ($grades as $grade) {
-                $retval['items'][$grade->id] = new grade_item($grade);
+                $retval['items'][$grade->id] = $this->get_instance('grade_item', $grade);
             }
         }
 
index b5516010736ea7cfb0bd58fd47861c8c3c0e439e..e26cb1dec29d5e511c3ac035b1437b887d809a9d 100644 (file)
@@ -82,7 +82,8 @@ class grade_scale extends grade_object {
      * @return object grade_scale instance or false if none found.
      */
     function fetch($params) {
-        return grade_object::fetch_helper('scale', 'grade_scale', $params);
+        $obj = new grade_scale();
+        return $obj->fetch_helper('scale', 'grade_scale', $params);
     }
 
     /**
@@ -93,7 +94,7 @@ class grade_scale extends grade_object {
      * @return array array of grade_scale insatnces or false if none found.
      */
     function fetch_all($params) {
-        return grade_object::fetch_all_helper('scale', 'grade_scale', $params);
+        return $this->fetch_all_helper('scale', 'grade_scale', $params);
     }
 
     /**
@@ -190,7 +191,7 @@ class grade_scale extends grade_object {
      */
     function get_nearest_item($grade) {
         // Obtain nearest scale item from average
-        $scales_array = get_records_list('scale', 'id', $this->id);
+        $scales_array = $this->lib_wrapper->get_records_list('scale', 'id', $this->id);
         $scale = $scales_array[$this->id];
         $scales = explode(",", $scale->scale);
 
@@ -207,7 +208,7 @@ class grade_scale extends grade_object {
      * @return object
      */
     function fetch_all_global() {
-        return grade_scale::fetch_all(array('courseid'=>0));
+        return $this->fetch_all(array('courseid'=>0));
     }
 
     /**
@@ -215,7 +216,7 @@ class grade_scale extends grade_object {
      * @return object
      */
     function fetch_all_local($courseid) {
-        return grade_scale::fetch_all(array('courseid'=>$courseid));
+        return $this->fetch_all(array('courseid'=>$courseid));
     }
 
     /**
@@ -235,18 +236,18 @@ class grade_scale extends grade_object {
 
         // count grade items excluding the
         $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_items WHERE scaleid = {$this->id} AND outcomeid IS NULL";
-        if (count_records_sql($sql)) {
+        if ($this->lib_wrapper->count_records_sql($sql)) {
             return true;
         }
 
         // count outcomes
         $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_outcomes WHERE scaleid = {$this->id}";
-        if (count_records_sql($sql)) {
+        if ($this->lib_wrapper->count_records_sql($sql)) {
             return true;
         }
 
         $legacy_mods = false;
-        if ($mods = get_records('modules', 'visible', 1)) {
+        if ($mods = $this->lib_wrapper->get_records('modules', 'visible', 1)) {
             foreach ($mods as $mod) {
                 //Check cm->name/lib.php exists
                 if (file_exists($CFG->dirroot.'/mod/'.$mod->name.'/lib.php')) {
@@ -270,12 +271,12 @@ class grade_scale extends grade_object {
         // some mods are missing the new xxx_scale_used_anywhere() - use the really slow old way
         if ($legacy_mods) {
             if (!empty($this->courseid)) {
-                if (course_scale_used($this->courseid,$this->id)) {
+                if ($this->lib_wrapper->course_scale_used($this->courseid,$this->id)) {
                     return true;
                 }
             } else {
                 $courses = array();
-                if (site_scale_used($this->id,$courses)) {
+                if ($this->lib_wrapper->site_scale_used($this->id,$courses)) {
                     return true;
                 }
             }
diff --git a/lib/grade/lib_wrapper.php b/lib/grade/lib_wrapper.php
new file mode 100644 (file)
index 0000000..2f67b51
--- /dev/null
@@ -0,0 +1,120 @@
+<?php // $Id$
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+class grade_lib_wrapper {
+    function get_records_sql($sql, $limitfrom='', $limitnum='') {
+        return get_records_sql($sql, $limitfrom, $limitnum);
+    }
+    
+    function get_records_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+        return get_records_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
+    }
+
+    function get_recordset($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+        return get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum); 
+    }
+
+    function get_recordset_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+        return get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
+    }
+
+    function get_recordset_sql($sql, $limitfrom=null, $limitnum=null) {
+        return get_recordset_sql($sql, $limitfrom, $limitnum);
+    }
+    
+    function get_record($table, $field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields='*') {
+        return get_record($table, $field1, $value1, $field2, $value2, $field3, $value3, $fields);
+    }
+
+    function get_records($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+        return get_records($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
+    }
+
+    function get_records_list($table, $field='', $values='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+        return get_records_list($table, $field, $values, $sort, $fields, $limitfrom, $limitnum);
+    }
+
+    function get_field($table, $return, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
+        return get_field($table, $return, $field1, $value1, $field2, $value2, $field3, $value3);
+    }
+
+    function get_field_sql($sql) {
+        return get_field_sql($sql);
+    }
+
+    function get_field_select($table, $return, $select) {
+        return get_field_select($table, $return, $select);
+    }
+
+    function set_field($table, $newfield, $newvalue, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
+        return set_field($table, $newfield, $newvalue, $field1, $value1, $field2, $value2, $field3, $value3);
+    }
+
+    function set_field_select($table, $newfield, $newvalue, $select, $localcall = false) {
+        return set_field_select($table, $newfield, $newvalue, $select, $localcall);
+    }
+
+    function rs_fetch_next_record(&$rs) {
+        return rs_fetch_next_record($rs);
+    }
+
+    function execute_sql($command, $feedback=true) {
+        return execute_sql($command, $feedback);
+    }
+    
+    function update_record($table, $dataobject) {
+        return update_record($table, $dataobject);
+    }
+    
+    function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
+        return insert_record($table, $dataobject, $returnid, $primarykey);
+    }
+    
+    function delete_records($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
+        return delete_records($table, $field1, $value1, $field2, $value2, $field3, $value3);
+    }
+    
+    function count_records($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
+        return count_records($table, $field1, $value1, $field2, $value2, $field3, $value3);
+    }
+
+    function rs_close(&$rs) {
+        return;
+    }
+    
+    function get_coursemodule_from_instance($modulename, $instance, $courseid=0) {
+        return get_coursemodule_from_instance($modulename, $instance, $courseid);
+    }
+
+    function course_scale_used($courseid, $scaleid) {
+        return course_scale_used($courseid, $scaleid);
+    }
+    
+    function site_scale_used($scaleid,&$courses) {
+        return site_scale_used($scaleid, $courses);
+    }
+}
+
+?>
index 02c4af6b3aa9cbd69b7ee80097e194e61474db5f..d165a2aa24e611e8cacc904864a8dbdda0ca0751 100755 (executable)
@@ -44,128 +44,137 @@ class grade_category_test extends grade_test {
         $this->load_grade_items();        
     }
 
-    function test_grade_category_construct() {
-        global $db;
-
-        $course_category = $this->grade_categories[0];
-
-        $params = new stdClass();
-
-        $params->courseid = $this->courseid;
-        $params->fullname = 'unittestcategory4';
-        
-        // Mock Insertion of category
-        $db->setReturnValue('GetInsertSQL', true);
-        $db->setReturnValue('Insert_ID', 1);
-
-        // Mock update of category
-        $grade_category = new grade_category($params, false);
-        $grade_category->parent = $course_category->id;
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
-        $column = new stdClass();
-        $column->name = 'path';
-        $db->setReturnValue('MetaColumns', array($column));
-
-        $grade_category->insert();
-
-        $this->assertEqual($params->courseid, $grade_category->courseid);
-        $this->assertEqual($params->fullname, $grade_category->fullname);
-        $this->assertEqual(2, $grade_category->depth);
-        $this->assertEqual("/$course_category->id/$grade_category->id/", $grade_category->path);
-        $parentpath = $grade_category->path;
-/*
-        // Test a child category
-        $params->parent = $grade_category->id;
-        $params->fullname = 'unittestcategory5';
-        $grade_category = new grade_category($params, false);
-
-        $this->reset_mocks();
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
-        $grade_category->insert();
-
-        $this->assertEqual(3, $grade_category->depth);
-        $this->assertEqual($parentpath.$grade_category->id."/", $grade_category->path);
-        $parentpath = $grade_category->path;
-
-        // Test a third depth category
-        $params->parent = $grade_category->id;
-        $params->fullname = 'unittestcategory6';
-        $grade_category = new grade_category($params, false);
-        
-        $this->reset_mocks();
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
-        $grade_category->insert();
-        $this->assertEqual(4, $grade_category->depth);
-        $this->assertEqual($parentpath.$grade_category->id."/", $grade_category->path);
-        */
-    }
-/*
     function test_grade_category_build_path() {
-        $grade_category = new grade_category($this->grade_categories[1]);
+        $grade_category = new grade_category(array('parent' => 2, 'id' => 3, 'path' => '/1/2/3/'), false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_category, 'build_path'));
-        $path = grade_category::build_path($grade_category);
+        
+        // Mock get_record of parent category (2) then (1)
+        $grade_category->lib_wrapper->expectCallCount('get_record', 2);
+        $parent2 = new stdClass();
+        $parent2->parent = 1;
+        $parent2->id = 2;
+        $grade_category->lib_wrapper->setReturnValueAt(0, 'get_record', $parent2);
+        $parent1 = new stdClass();
+        $parent1->parent = null;
+        $parent1->id = 1;
+        $grade_category->lib_wrapper->setReturnValueAt(1, 'get_record', $parent1);
+        
+        $path = $grade_category->build_path($grade_category);
         $this->assertEqual($grade_category->path, $path);
     }
 
     function test_grade_category_fetch() {
         $grade_category = new grade_category();
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_category, 'fetch'));
+        
+        $grade_category->lib_wrapper->expectOnce('get_records_select');
+        $grade_category->lib_wrapper->setReturnValue('get_records_select', array($this->grade_categories[1]));
 
-        $grade_category = grade_category::fetch(array('id'=>$this->grade_categories[0]->id));
-        $this->assertEqual($this->grade_categories[0]->id, $grade_category->id);
-        $this->assertEqual($this->grade_categories[0]->fullname, $grade_category->fullname);
+        $grade_category = $grade_category->fetch(array('id'=>$this->grade_categories[1]->id));
+        $this->assertEqual($this->grade_categories[1]->id, $grade_category->id);
+        $this->assertEqual($this->grade_categories[1]->fullname, $grade_category->fullname);
     }
 
     function test_grade_category_fetch_all() {
         $grade_category = new grade_category();
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_category, 'fetch_all'));
 
-        $grade_categories = grade_category::fetch_all(array('courseid'=>$this->courseid));
-        $this->assertEqual(count($this->grade_categories), count($grade_categories)-1);
+        $grade_category->lib_wrapper->expectOnce('get_records_select');
+        $grade_category->lib_wrapper->setReturnValue('get_records_select', $this->grade_categories);
+        
+        $grade_categories = $grade_category->fetch_all(array('courseid'=>$this->courseid));
+        $this->assertEqual(count($this->grade_categories), count($grade_categories));
     }
 
     function test_grade_category_update() {
-        $grade_category = new grade_category($this->grade_categories[0]);
+
+        Mock::generatePartial('grade_category', 'partial_mock', array('load_grade_item',
+                                                                      'build_path', 
+                                                                      'apply_forced_settings', 
+                                                                      'qualifies_for_regrading',
+                                                                      'force_regrading'));
+
+        $grade_category = &new partial_mock($this);
+        $grade_category->grade_category($this->grade_categories[1], false);
+
         $this->assertTrue(method_exists($grade_category, 'update'));
 
         $grade_category->fullname = 'Updated info for this unittest grade_category';
         $grade_category->path = null; // path must be recalculated if missing
         $grade_category->depth = null;
         $grade_category->aggregation = GRADE_AGGREGATE_MAX; // should force regrading
-
-        $grade_item = $grade_category->get_grade_item();
+        $grade_category->droplow = 1;
+        $grade_category->keephigh = 1;
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        
+        $grade_category->lib_wrapper->expectOnce('update_record');
+        $grade_category->lib_wrapper->setReturnValue('update_record', true);
+        
+        $grade_item = new grade_item(array('id' => 99, 'itemtype' => 'course', 'courseid' => $this->courseid, 'needsupdate' => 0), false);
+        $grade_category->grade_item = $grade_item;
         $this->assertEqual(0, $grade_item->needsupdate);
-
+        
+        // Set method expectations
+        $grade_category->expectOnce('load_grade_item');
+        $grade_category->expectOnce('apply_forced_settings');
+        $grade_category->setReturnValue('qualifies_for_regrading', true);
+        $grade_category->expectOnce('force_regrading'); 
+        
         $this->assertTrue($grade_category->update());
-
-        $fullname = get_field('grade_categories', 'fullname', 'id', $this->grade_categories[0]->id);
-        $this->assertEqual($grade_category->fullname, $fullname);
-
-        $path = get_field('grade_categories', 'path', 'id', $this->grade_categories[0]->id);
-        $this->assertEqual($grade_category->path, $path);
-
-        $depth = get_field('grade_categories', 'depth', 'id', $this->grade_categories[0]->id);
-        $this->assertEqual($grade_category->depth, $depth);
-
-        $grade_item = $grade_category->get_grade_item();
-        $this->assertEqual(1, $grade_item->needsupdate);
+        
+        $this->assertEqual(0, $grade_category->keephigh);
+        $this->assertEqual(1, $grade_category->droplow);
+        $this->assertTrue($grade_category->timemodified > 0);
+        $this->assertTrue($grade_category->timemodified <= time());
     }
 
     function test_grade_category_delete() {
-        $grade_category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($grade_category, 'delete'));
 
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_delete', array('load_grade_item',
+                                                                                        'is_course_category', 
+                                                                                        'load_parent_category', 
+                                                                                        'force_regrading'));
+
+        $grade_category = &new mock_grade_category_for_delete($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_category->id = 1;
+        $grade_category->expectOnce('load_grade_item');
+        $grade_category->setReturnValue('is_course_category', false);
+        $grade_category->expectOnce('force_regrading');
+        $grade_category->expectOnce('load_parent_category');
+
+        $parent_category = new mock_grade_category();
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $parent_category->id = 1;
+        $grade_category->setReturnReference('load_parent_category', $parent_category);
+
+        $grade_item = new mock_grade_item();
+        $grade_item->id = 2;
+        $grade_category->setReturnReference('load_grade_item', $grade_item);
+        
+        $grade_category->lib_wrapper->expectOnce('delete_records', array('grade_categories', 'id', $grade_category->id));
+        $grade_category->lib_wrapper->setReturnValue('delete_records', true);
+        
+        $grade_category->lib_wrapper->expectOnce('insert_record'); // grade_history entry
+        
+        $this->assertTrue(method_exists($grade_category, 'delete'));
         $this->assertTrue($grade_category->delete());
-        $this->assertFalse(get_record('grade_categories', 'id', $grade_category->id));
     }
 
     function test_grade_category_insert() {
-        $course_category = grade_category::fetch_course_category($this->courseid);
 
-        $grade_category = new grade_category();
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_insert', array('update',
+                                                                                        'apply_forced_settings',
+                                                                                        'force_regrading'));
+
+        $course_category = $this->grade_categories[0];
+
+        $grade_category = new mock_grade_category_for_insert($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        
         $this->assertTrue(method_exists($grade_category, 'insert'));
 
         $grade_category->fullname    = 'unittestcategory4';
@@ -175,114 +184,196 @@ class grade_category_test extends grade_test {
         $grade_category->keephigh    = 100;
         $grade_category->droplow     = 10;
         $grade_category->hidden      = 0;
-        $grade_category->parent      = $this->grade_categories[0]->id;
-
-        $grade_category->insert();
+        $grade_category->parent      = $this->grade_categories[1]->id;
 
-        $this->assertEqual('/'.$course_category->id.'/'.$this->grade_categories[0]->id.'/'.$grade_category->id.'/', $grade_category->path);
-        $this->assertEqual(3, $grade_category->depth);
+        $grade_category->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+        $grade_category->lib_wrapper->setReturnValue('insert_record', 4);
+        $grade_category->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+        $grade_category->lib_wrapper->setReturnValue('get_record', array(1));
 
-        $last_grade_category = end($this->grade_categories);
-
-        $this->assertFalse(empty($grade_category->grade_item));
-        $this->assertEqual($grade_category->id, $grade_category->grade_item->iteminstance);
-        $this->assertEqual('category', $grade_category->grade_item->itemtype);
+        $grade_category->insert();
+        
+        // Don't test path and depth, they're the job of the update method 
+        $this->assertEqual($grade_category->id, 4);
 
-        $this->assertEqual($grade_category->id, $last_grade_category->id + 1);
         $this->assertFalse(empty($grade_category->timecreated));
         $this->assertFalse(empty($grade_category->timemodified));
     }
 
     function test_grade_category_insert_course_category() {
-        $grade_category = new grade_category();
+        $grade_category = new mock_grade_category_for_insert($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_category, 'insert_course_category'));
+        $grade_category->expectOnce('apply_forced_settings');
+        $grade_category->expectOnce('update', array('system'));
 
+        $grade_category->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+        $grade_category->lib_wrapper->setReturnValue('insert_record', 1);
+        $grade_category->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+        $grade_category->lib_wrapper->setReturnValue('get_record', array(1));
+        
         $id = $grade_category->insert_course_category($this->courseid);
+        
         $this->assertNotNull($id);
-        $this->assertEqual('Course grade category', $grade_category->fullname);
-        $this->assertEqual(GRADE_AGGREGATE_MEAN, $grade_category->aggregate);
-        $this->assertEqual("/$id/", $grade_category->path);
-        $this->assertEqual(1, $grade_category->depth);
+        $this->assertEqual(get_string('coursegradecategory', 'grades'), $grade_category->fullname);
+        $this->assertEqual(GRADE_AGGREGATE_MEAN, $grade_category->aggregation);
         $this->assertNull($grade_category->parent);
+        $this->assertFalse(empty($grade_category->timecreated));
+        $this->assertFalse(empty($grade_category->timemodified));
     }
 
     function test_grade_category_qualifies_for_regrading() {
-        $grade_category = new grade_category($this->grade_categories[0]);
+        $grade_category = new grade_category($this->grade_categories[0], false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_category, 'qualifies_for_regrading'));
-
+        
+        // Mock fetch of grade_item
+        $grade_category->lib_wrapper->expectCallCount('get_records_select', 2);
+        $grade_category->lib_wrapper->setReturnValue('get_records_select', (array) fullclone($grade_category));
+        $grade_item = new stdClass();
+        $grade_item->lib_wrapper = new mock_lib_wrapper();
+        $grade_item->aggregation = GRADE_AGGREGATE_MEAN;
+        
         $this->assertFalse($grade_category->qualifies_for_regrading());
 
         $grade_category->aggregation = GRADE_AGGREGATE_MAX;
         $this->assertTrue($grade_category->qualifies_for_regrading());
 
-        $grade_category = new grade_category($this->grade_categories[0]);
+        $grade_category = new grade_category($this->grade_categories[0], false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_category->lib_wrapper->expectOnce('get_records_select');
+        $grade_category->lib_wrapper->setReturnValue('get_records_select', (array) fullclone($grade_category));
         $grade_category->droplow = 99;
         $this->assertTrue($grade_category->qualifies_for_regrading());
 
-        $grade_category = new grade_category($this->grade_categories[0]);
+        $grade_category = new grade_category($this->grade_categories[0], false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_category->lib_wrapper->expectOnce('get_records_select');
+        $grade_category->lib_wrapper->setReturnValue('get_records_select', (array) fullclone($grade_category));
         $grade_category->keephigh = 99;
         $this->assertTrue($grade_category->qualifies_for_regrading());
     }
 
-    function test_grade_category_force_regrading() {
-        $grade_category = new grade_category($this->grade_categories[1]);
-        $this->assertTrue(method_exists($grade_category, 'force_regrading'));
-
-        $grade_category->load_grade_item();
-        $this->assertEqual(0, $grade_category->grade_item->needsupdate);
-
-        $grade_category->force_regrading();
-
-        $grade_category->grade_item = null;
-        $grade_category->load_grade_item();
-
-        $this->assertEqual(1, $grade_category->grade_item->needsupdate);
-    }
-
     function test_grade_category_generate_grades() {
-        $category = new grade_category($this->grade_categories[3]);
-        $this->assertTrue(method_exists($category, 'generate_grades'));
-        $category->load_grade_item();
 
-        $grades = get_records('grade_grades', 'itemid', $category->grade_item->id);
-        $this->assertFalse($grades);
-
-        $category->generate_grades();
-        $grades = get_records('grade_grades', 'itemid', $category->grade_item->id);
-        $this->assertEqual(3, count($grades));
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_generate_grades', array('load_grade_item',
+                                                                                                 'aggregate_grades'));
+
+        // No generating should occur if the item is locked, but the method still returns true
+        $grade_category = new mock_grade_category_for_generate_grades($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_item = new mock_grade_item();
+        $grade_item->setReturnValue('is_locked', true); 
+        $grade_category->grade_item = $grade_item;
+        $this->assertTrue(method_exists($grade_category, 'generate_grades'));
+        $grade_category->expectNever('aggregate_grades');
+        $this->assertTrue($grade_category->generate_grades());
         
-        // Category grades do not have raw values
-        $finalvalues = array();
-        foreach ($grades as $grade) {
-            $this->assertWithinMargin($grade->finalgrade, $grade->rawgrademin, $grade->rawgrademax);
-            $finalvalues[] = (int)$grade->finalgrade;
-        }
-        sort($finalvalues);
-        // calculated mean results
-        $this->assertEqual($finalvalues, array(20,50,100));
+        // We can't verify DB records, so let's check method calls
+        $grade_category = new mock_grade_category_for_generate_grades($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_item = new mock_grade_item();
+        $grade_item->id = 1;
+        $grade_category->grade_item = $grade_item;
+        $grade_item->setReturnValue('is_locked', false);
+        $grade_item->setReturnValue('depends_on', array(1, 2, 3)); 
+        $grade_category->lib_wrapper->expectOnce('get_records_sql');
+        $grade_category->lib_wrapper->setReturnValue('get_records_sql', array($this->grade_items[2], $this->grade_items[3], $this->grade_items[4]));
+        $grade_category->lib_wrapper->expectOnce('get_recordset_sql');
+        $grade_category->lib_wrapper->setReturnValue('get_recordset_sql', 1);
+        $grade_category->lib_wrapper->expectCallCount('rs_fetch_next_record', 4);
+
+        $record = new stdClass();
+        $record->userid = 1;
+        $record->itemid = 1;
+        $record->finalgrade = 20; 
+        $record->excluded = false;
+        $grade_category->lib_wrapper->setReturnValueAt(0, 'rs_fetch_next_record', $record);
+        $record2 = new stdClass();
+        $record2->userid = 2;
+        $record2->itemid = 2;
+        $record2->finalgrade = 20; 
+        $record2->excluded = false;
+        $grade_category->lib_wrapper->setReturnValueAt(1, 'rs_fetch_next_record', $record2);
+        $record3 = new stdClass();
+        $record3->userid = 3;
+        $record3->itemid = 3;
+        $record3->finalgrade = 20; 
+        $record3->excluded = false;
+        $grade_category->lib_wrapper->setReturnValueAt(2, 'rs_fetch_next_record', $record3);
+        $this->assertTrue($grade_category->generate_grades()); 
     }
 
     function test_grade_category_aggregate_grades() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'aggregate_grades'));
-        // tested above in test_grade_category_generate_grades()
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_aggregate_grades', array('aggregate_values', 'apply_limit_rules'));
+        // Setup method arguments (no optionals!)
+        $arg_userid = null;
+        $arg_items = array();
+        $arg_grade_values = array(1 => 20); // should get unset early on in the method
+        $arg_oldgrade = new stdClass();
+        $arg_oldgrade->finalgrade = null; // These two are set to null to avoid a grade_grade->update() in the aggregate_grades() method
+        $arg_oldgrade->rawgrade = null;
+        $arg_oldgrade->rawgrademin = 0;
+        $arg_oldgrade->rawgrademax = 100;
+        $arg_oldgrade->rawscaleid = null;
+        $arg_excluded = false;
+    
+        // Set up rest of objects
+        $grade_category = new mock_grade_category_for_aggregate_grades($this);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_item = new mock_grade_item();
+        $grade_item->id = 1;
+        $grade_item->gradetype = GRADE_TYPE_VALUE;
+        $this->assertTrue(method_exists($grade_category, 'aggregate_grades'));
+
+        // If no userid given, should return null;
+        $grade_category->expectNever('aggregate_values');
+        $grade_category->expectNever('apply_limit_rules');
+        $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
+        // Return without doing anything if the grade or grade_item is locked (we have control over the grade_item here because
+        // the grade_grade->grade_item is the same as the grade_category->grade_item
+        $arg_userid = 1;
+        $grade_item->setReturnValueAt(0, 'is_locked', true);
+        $grade_category->grade_item = $grade_item;
+        $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
+
+        // Proceed further by setting grade_item->is_locked to false. Still return null because no other grade_values than main item's 
+        $grade_item->setReturnValueAt(1, 'is_locked', false);
+        $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
+        
+        // Going further now with a proper array of gradevalues and items. Also provide an excluded itemid
+        $gi = new mock_grade_item();
+        $gi->grademin = 0;
+        $gi->grademax = 100;
+        $arg_items = array(1 => $grade_item, 2 => fullclone($gi), 3 => fullclone($gi), 4 => fullclone($gi), 5 => fullclone($gi));
+        $arg_grade_values = array(1 => 20, 2 => null, 3 => 8, 4 => 67, 5 => 53);
+        $arg_excluded = array(3);
+        $grade_category = new mock_grade_category_for_aggregate_grades($this);
+        $grade_item->grademin = 0;
+        $grade_item->grademax = 100;
+        $grade_item->scaleid = null;
+        $grade_category->grade_item = $grade_item;
+        $grade_category->expectOnce('apply_limit_rules');
+        $grade_category->expectOnce('aggregate_values');
+        $grade_category->aggregateonlygraded = true;
+        $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
     }
 
     function test_grade_category_apply_limit_rules() {
-        $category = new grade_category();
+        $grade_category = new grade_category();
         $grades = array(5.374, 9.4743, 2.5474, 7.3754);
 
-        $category->droplow = 2;
-        $category->apply_limit_rules($grades);
+        $grade_category->droplow = 2;
+        $grade_category->apply_limit_rules($grades);
         sort($grades, SORT_NUMERIC);
         $this->assertEqual(array(7.3754, 9.4743), $grades);
 
-        $category = new grade_category();
+        $grade_category = new grade_category();
         $grades = array(5.374, 9.4743, 2.5474, 7.3754);
 
-        $category->keephigh = 1;
-        $category->droplow = 0;
-        $category->apply_limit_rules($grades);
+        $grade_category->keephigh = 1;
+        $grade_category->droplow = 0;
+        $grade_category->apply_limit_rules($grades);
         $this->assertEqual(count($grades), 1);
         $grade = reset($grades);
         $this->assertEqual(9.4743, $grade);
@@ -293,147 +384,236 @@ class grade_category_test extends grade_test {
     }
 
     function test_grade_category_fetch_course_tree() {
-        $category = new grade_category();
-        $this->assertTrue(method_exists($category, 'fetch_course_tree'));
+        $grade_category = new grade_category();
+        $this->assertTrue(method_exists($grade_category, 'fetch_course_tree'));
         //TODO: add some tests
     }
 
     function test_grade_category_get_children() {
-        $course_category = grade_category::fetch_course_category($this->courseid);
-
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'get_children'));
-
-        $children_array = $category->get_children(0);
+        $grade_category = new grade_category();
+        $grade_category->id = 1;
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+
+        // Setup course cats and items: 
+        // 1 course
+        // |_ 2 category
+        // | |_ 3 item
+        // | |_ 4 item
+        // |_ 5 category
+        // | |_ 6 item
+        // | |_ 7 item
+
+        $cats = array();
+        $cat = new stdClass();
+        $cat->id = 1;
+        $cat->parent = null;
+        $cat->sortorder = 1;
+        $cat->depth = 0;
+        $cats[1] = fullclone($cat);
+        $cat->id = 3;
+        $cat->parent = 1;
+        $cat->sortorder = 2;
+        $cat->depth = 1;
+        $cats[3] = fullclone($cat);
+        $cat->id = 4;
+        $cat->sortorder = 5;
+        $cat->depth = 1;
+        $cats[4] = fullclone($cat);
+
+        $item = new stdClass();
+        $item->itemtype = 'course';
+        $item->iteminstance = 1;
+        $item->sortorder = 1;
+        $items = array();
+        $items[5] = fullclone($item);
+        $item->itemtype = 'category';
+        $item->iteminstance = 3;
+        $item->sortorder = 2;
+        $items[6] = fullclone($item);
+        $item->iteminstance = 4;
+        $item->sortorder = 5;
+        $items[7] = fullclone($item);
+        $item->itemtype = 'item';
+        $item->categoryid = 3;
+        $item->sortorder = 3;
+        $items[8] = fullclone($item);
+        $item->categoryid = 3;
+        $item->sortorder = 4;
+        $items[9] = fullclone($item);
+        $item->categoryid = 4;
+        $item->sortorder = 6;
+        $items[10] = fullclone($item);
+        $item->categoryid = 4;
+        $item->sortorder = 7;
+        $items[11] = fullclone($item);
+
+        $grade_category->lib_wrapper->setReturnValueAt(0, 'get_records', $cats);
+        $grade_category->lib_wrapper->setReturnValueAt(1, 'get_records', $items);
+        $this->assertTrue(method_exists($grade_category, 'get_children'));
+    
+        // Do not test recursion
+        $children_array = $grade_category->get_children(true);
 
         $this->assertTrue(is_array($children_array));
-        $this->assertFalse(empty($children_array[2]));
-        $this->assertFalse(empty($children_array[2]['object']));
-        $this->assertFalse(empty($children_array[2]['children']));
-        $this->assertEqual($this->grade_categories[1]->id, $children_array[2]['object']->id);
-        $this->assertEqual($this->grade_categories[2]->id, $children_array[5]['object']->id);
-        $this->assertEqual($this->grade_items[0]->id, $children_array[2]['children'][3]['object']->id);
-        $this->assertEqual($this->grade_items[1]->id, $children_array[2]['children'][4]['object']->id);
-        $this->assertEqual($this->grade_items[2]->id, $children_array[5]['children'][6]['object']->id);
-    }
-
-    function test_grade_category_load_grade_item() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'load_grade_item'));
-        $this->assertEqual(null, $category->grade_item);
-        $category->load_grade_item();
-        $this->assertEqual($this->grade_items[3]->id, $category->grade_item->id);
-    }
+        $this->assertEqual(3, count($children_array));
+        $this->assertEqual('grade_item', get_class($children_array[1]['object']));
+        $this->assertEqual('courseitem', $children_array[1]['type']);
+        $this->assertequal(0, $children_array[1]['depth']);
+        $this->assertEqual('course', $children_array[1]['object']->itemtype);
 
-    function test_grade_category_get_grade_item() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'get_grade_item'));
-        $grade_item = $category->get_grade_item();
-        $this->assertEqual($this->grade_items[3]->id, $grade_item->id);
+        $this->assertEqual('grade_category', get_class($children_array[2]['object']));
+        $this->assertEqual('category', $children_array[2]['type']);
+        $this->assertequal(1, $children_array[2]['depth']);
+        $this->assertEqual(3, count($children_array[2]['children']));
     }
 
     function test_grade_category_load_parent_category() {
-        $category = new grade_category($this->grade_categories[1]);
-        $this->assertTrue(method_exists($category, 'load_parent_category'));
-        $this->assertEqual(null, $category->parent_category);
-        $category->load_parent_category();
-        $this->assertEqual($this->grade_categories[0]->id, $category->parent_category->id);
-    }
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_load_parent_category', array('get_parent_category'));
 
-    function test_grade_category_get_parent_category() {
-        $category = new grade_category($this->grade_categories[1]);
-        $this->assertTrue(method_exists($category, 'get_parent_category'));
-        $parent_category = $category->get_parent_category();
-        $this->assertEqual($this->grade_categories[0]->id, $parent_category->id);
+        $grade_category = new mock_grade_category_for_load_parent_category($this);;
+        $grade_category->parent = 1;
+        $parent = new grade_category($this->grade_categories[0], false);
+        $grade_category->setReturnReference('get_parent_category', $parent);
+        $grade_category->expectOnce('get_parent_category', array());
+        $this->assertTrue(method_exists($grade_category, 'load_parent_category'));
+        $this->assertEqual(null, $grade_category->parent_category);
+        $grade_category->load_parent_category();
+        $this->assertEqual($this->grade_categories[0]->id, $grade_category->parent_category->id);
     }
 
     function test_grade_category_get_name() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'get_name'));
-        $this->assertEqual($this->grade_categories[0]->fullname, $category->get_name());
-    }
-
-    function test_grade_category_set_parent() {
-        $category = new grade_category($this->grade_categories[1]);
-        $this->assertTrue(method_exists($category, 'set_parent'));
-        // TODO: implement detailed tests
+        $grade_category = new grade_category($this->grade_categories[0], false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $this->assertTrue(method_exists($grade_category, 'get_name'));
+        $grade_category->lib_wrapper->expectOnce('get_record', array('course', 'id', $this->courseid));
+        $course = new stdClass();
+        $course->fullname = $grade_category->fullname;
+        $grade_category->lib_wrapper->setReturnValue('get_record', $course);
+        $grade_category->parent = null;
+        $this->assertEqual(format_string($this->grade_categories[0]->fullname), $grade_category->get_name());
 
-        $course_category = grade_category::fetch_course_category($this->courseid);
-        $this->assertTrue($category->set_parent($course_category->id));
-        $this->assertEqual($course_category->id, $category->parent);
-    }
-
-    function test_grade_category_get_final() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'get_final'));
-        $category->load_grade_item();
-        $this->assertEqual($category->get_final(), $category->grade_item->get_final());
-    }
-
-    function test_grade_category_get_sortorder() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'get_sortorder'));
-        $category->load_grade_item();
-        $this->assertEqual($category->get_sortorder(), $category->grade_item->get_sortorder());
-    }
-
-    function test_grade_category_set_sortorder() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'set_sortorder'));
-        $category->load_grade_item();
-        $this->assertEqual($category->set_sortorder(10), $category->grade_item->set_sortorder(10));
-    }
+        // Test with a parent id
+        $grade_category = new grade_category($this->grade_categories[0], false);
+        $grade_category->lib_wrapper = new mock_lib_wrapper();
+        $grade_category->parent = 1;
+        $grade_category->lib_wrapper->expectNever('get_record');
+        $this->assertEqual(format_string($this->grade_categories[0]->fullname), $grade_category->get_name()); 
 
-    function test_grade_category_move_after_sortorder() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'move_after_sortorder'));
-        $category->load_grade_item();
-        $this->assertEqual($category->move_after_sortorder(10), $category->grade_item->move_after_sortorder(10));
     }
 
-    function test_grade_category_is_course_category() {
-        $category = grade_category::fetch_course_category($this->courseid);
-        $this->assertTrue(method_exists($category, 'is_course_category'));
-        $this->assertTrue($category->is_course_category());
+    function test_grade_category_set_parent() {
+        $methods_to_mock = array('is_course_category', 'update', 'fetch', 'force_regrading');
+        
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_set_parent', $methods_to_mock);
+        $grade_category_template = new mock_grade_category_for_set_parent($this);
+        $grade_category_template->parent = 1;
+        $grade_category_template->courseid = $this->courseid;
+        
+        $this->assertTrue(method_exists($grade_category_template, 'set_parent'));
+        
+        // Test when requested parentid is already the category's parent id (1 in this case)
+        $grade_category = fullclone($grade_category_template);
+        $grade_category->expectNever('is_course_category');
+        $grade_category->expectNever('update');
+        $grade_category->expectNever('fetch');
+        $this->assertTrue($grade_category->set_parent(1));
+
+        $grade_category_template->parent = 2;
+        
+        // Test when parent category is not found in DB
+        $grade_category = fullclone($grade_category_template);
+        $grade_category->expectOnce('is_course_category');
+        $grade_category->setReturnValue('is_course_category', false);
+        $grade_category->expectOnce('fetch', array(array('id' => 1, 'courseid' => $this->courseid)));
+        $grade_category->setReturnValue('fetch', false);
+        $grade_category->expectNever('update');
+        $grade_category->expectNever('force_regrading');
+        $this->assertFalse($grade_category->set_parent(1));
+    
+        // Test when parent category is found in DB
+        $grade_category = fullclone($grade_category_template);
+        $grade_category->expectOnce('is_course_category');
+        $grade_category->setReturnValue('is_course_category', false);
+        $grade_category->expectOnce('fetch', array(array('id' => 1, 'courseid' => $this->courseid)));
+        $grade_category->setReturnValue('fetch', $this->grade_categories[0]); 
+        $grade_category->expectOnce('force_regrading', array());
+        $grade_category->expectOnce('update');
+        $grade_category->setReturnValue('update', true);
+        $this->assertTrue($grade_category->set_parent(1));
     }
 
     function test_grade_category_fetch_course_category() {
-        $category = new grade_category();
-        $this->assertTrue(method_exists($category, 'fetch_course_category'));
-        $category = grade_category::fetch_course_category($this->courseid);
-        $this->assertTrue(empty($category->parent));
-    }
-    
-    function test_grade_category_is_editable() {
-
-    }
+        $methods_to_mock = array('instantiate_new_grade_category', 'fetch', 'insert_course_category'); 
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_fetch_course_category', $methods_to_mock);
+        $grade_category = new mock_grade_category_for_fetch_course_category($this);
+        $this->assertTrue(method_exists($grade_category, 'fetch_course_category'));
+        
+        // Test method when course category already exists
+        $grade_category->expectNever('instantiate_new_grade_category');
+        $grade_category->expectOnce('fetch', array(array('courseid' => $this->courseid, 'parent' => null)));
+        $grade_category->setReturnValue('fetch', $this->grade_categories[0]);
+        $this->assertEqual($this->grade_categories[0], $grade_category->fetch_course_category($this->courseid));
+        
+        // Test method when course category does not exists
+        $grade_category = new mock_grade_category_for_fetch_course_category($this);
+        $grade_category->expectOnce('instantiate_new_grade_category');
+        $grade_category->expectOnce('fetch', array(array('courseid' => $this->courseid, 'parent' => null)));
+        $grade_category->setReturnValue('fetch', false);
+        $course_category = new mock_grade_category_for_fetch_course_category($this);
+        $course_category->expectOnce('insert_course_category', array($this->courseid));
+        $grade_category->setReturnValue('instantiate_new_grade_category', $course_category);
+        $this->assertEqual($course_category, $grade_category->fetch_course_category($this->courseid));
 
-    function test_grade_category_is_locked() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'is_locked'));
-        $category->load_grade_item();
-        $this->assertEqual($category->is_locked(), $category->grade_item->is_locked());
     }
+    
 
     function test_grade_category_set_locked() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'set_locked'));
-        $this->assertTrue($category->set_locked(1));
+        $methods_to_mock = array('load_grade_item', 'instantiate_new_grade_item', 'fetch_all');
+        
+        $lockedstate = true;
+        $cascade = false;
+        $refresh = false;
+        
+        // Test non-cascading set_locked
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_set_locked', $methods_to_mock);
+        $grade_item = new mock_grade_item();
+        $grade_item->expectOnce('set_locked', array($lockedstate, $cascade, true));
+        $grade_item->setReturnValue('set_locked', true); 
+        $grade_item->expectNever('fetch_all');
+        $grade_category = new mock_grade_category_for_set_locked($this);
+        $grade_category->expectOnce('load_grade_item');
+        $grade_category->expectNever('instantiate_new_grade_item');
+        $this->assertTrue(method_exists($grade_category, 'set_locked'));
+        $grade_category->grade_item = $grade_item;
+
+        $this->assertTrue($grade_category->set_locked($lockedstate, $cascade, $refresh));
+        
+        // Test cascading set_locked
+        $cascading = true;
+        Mock::generatePartial('grade_category', 'mock_grade_category_for_set_locked', $methods_to_mock);
+        $grade_category = new mock_grade_category_for_set_locked($this);
+        $grade_category->expectOnce('fetch_all');
+        $grade_category->setReturnValue('fetch_all', array(fullclone($grade_item), fullclone($grade_item)));
+        $grade_category->expectOnce('load_grade_item');
+        $grade_category->grade_item = $grade_item;
+
+        $this->assertTrue($grade_category->set_locked($lockedstate, $cascade, $refresh));
     }
 
+/*
     function test_grade_category_is_hidden() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'is_hidden'));
-        $category->load_grade_item();
-        $this->assertEqual($category->is_hidden(), $category->grade_item->is_hidden());
+        $grade_category = new grade_category($this->grade_categories[0]);
+        $this->assertTrue(method_exists($grade_category, 'is_hidden'));
+        $grade_category->load_grade_item();
+        $this->assertEqual($grade_category->is_hidden(), $grade_category->grade_item->is_hidden());
     }
 
     function test_grade_category_set_hidden() {
-        $category = new grade_category($this->grade_categories[0]);
-        $this->assertTrue(method_exists($category, 'set_hidden'));
-        $category->set_hidden(1);
-        $category->load_grade_item();
-        $this->assertEqual(true, $category->grade_item->is_hidden());
+        $grade_category = new grade_category($this->grade_categories[0]);
+        $this->assertTrue(method_exists($grade_category, 'set_hidden'));
+        $grade_category->set_hidden(1);
+        $grade_category->load_grade_item();
+        $this->assertEqual(true, $grade_category->grade_item->is_hidden());
     }
 
     function generate_random_raw_grade($item, $userid) {
index 0265d41f128fdb69ac01c65f9c392ff925211074..424255084601095c5f65ace6d701257be01eccae 100755 (executable)
@@ -63,8 +63,8 @@ class grade_grade_test extends grade_test {
     }
 
     function test_grade_grade_insert() {
-        global $db;
         $grade_grade = new grade_grade();
+        $grade_grade->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_grade, 'insert'));
 
         $grade_grade->itemid = $this->grade_items[0]->id;
@@ -79,13 +79,10 @@ class grade_grade_test extends grade_test {
         // Check the grade_item's needsupdate variable first
         $this->assertFalse($grade_grade->grade_item->needsupdate);
         
-        // Mock insert of data in history table
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
-        
-        // Mock insert of outcome object
-        $db->setReturnValue('GetInsertSQL', true);
-        $db->setReturnValue('Insert_ID', 1);
+        $grade_grade->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+        $grade_grade->lib_wrapper->setReturnValue('insert_record', 1);
+        $grade_grade->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+        $grade_grade->lib_wrapper->setReturnValue('get_record', array(1));
 
         $grade_grade->insert();
 
@@ -98,21 +95,22 @@ class grade_grade_test extends grade_test {
 
     function test_grade_grade_update() {
         $grade_grade = new grade_grade($this->grade_grades[0], false);
+        $grade_grade->lib_wrapper = new mock_lib_wrapper();
+        $grade_grade->lib_wrapper->expectOnce('update_record');
+        $grade_grade->lib_wrapper->setReturnValue('update_record', true);
         $this->assertTrue(method_exists($grade_grade, 'update'));
+        $grade_grade->update();
     }
 
     function test_grade_grade_fetch() {
-        global $db;
         $grade_grade = new grade_grade($this->grade_grades[0], false);
+        $grade_grade->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_grade, 'fetch'));
 
-        // Mock fetch
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', array($grade_grade->id => (array) $grade_grade)); 
+        $grade_grade->lib_wrapper->expectOnce('get_records_select');
+        $grade_grade->lib_wrapper->setReturnValue('get_records_select', array($this->grade_grades[0]));
         
-        $grades = grade_grade::fetch(array('id'=>$grade_grade->id));
+        $grades = $grade_grade->fetch(array('id'=>$grade_grade->id));
 
         $this->assertEqual($grade_grade->id, $grades->id);
         $this->assertEqual($grade_grade->rawgrade, $grades->rawgrade);
@@ -120,35 +118,25 @@ class grade_grade_test extends grade_test {
 
     function test_grade_grade_fetch_all() {
         $grade_grade = new grade_grade();
+        $grade_grade->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_grade, 'fetch_all'));
 
-        // Mock fetch_all
-        $return_array = array();
-        foreach ($this->grade_grades as $gg) {
-            $return_array[$gg->id] = (array) $gg;
-        }
+        $grade_grade->lib_wrapper->expectOnce('get_records_select');
+        $grade_grade->lib_wrapper->setReturnValue('get_records_select', $this->grade_grades);
 
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', $return_array); 
-        
-        $grades = grade_grade::fetch_all(array());
+        $grades = $grade_grade->fetch_all(array());
         $this->assertEqual(count($this->grade_grades), count($grades)); 
     }
 
     function test_grade_grade_load_grade_item() {
         $grade_grade = new grade_grade($this->grade_grades[0], false);
+        $grade_grade->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_grade, 'load_grade_item'));
         $this->assertNull($grade_grade->grade_item);
         $this->assertTrue($grade_grade->itemid);
         
-        // Mock fetch
-        $grade_item = $this->grade_items[0];
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', array($grade_item->id => (array) $grade_item)); 
+        $grade_grade->lib_wrapper->expectOnce('get_records_select');
+        $grade_grade->lib_wrapper->setReturnValue('get_records_select', array($this->grade_items[0]));
         
         $this->assertNotNull($grade_grade->load_grade_item());
         $this->assertNotNull($grade_grade->grade_item);
@@ -165,9 +153,11 @@ class grade_grade_test extends grade_test {
      * would otherwise trigger the refresh_grades method, which is not being tested here.
      */ 
     function test_grade_grade_set_locked() {
-        global $db;
         $grade_item = new grade_item($this->grade_items[0], false);
-        $grade = new grade_grade($grade_item->get_final(1), false);
+        $grade = new grade_grade($this->grade_grades[0], false);
+        $grade->lib_wrapper = new mock_lib_wrapper();
+        $grade->lib_wrapper->expectCallCount('update_record', 2);
+        $grade->lib_wrapper->setReturnValue('update_record', true);
         $grade->grade_item = $grade_item;
         $grade->itemid = $grade_item->id;
 
@@ -182,17 +172,15 @@ class grade_grade_test extends grade_test {
 
         // Test locking the grade when needsupdate is false
         $grade->grade_item->needsupdate = false;
-        
-        $column = new stdClass();
-        $column->name = 'locked';
-        $db->setReturnValue('MetaColumns', array($column));
-
         $this->assertTrue($grade->set_locked(true, false, false));
         $this->assertFalse(empty($grade->locked));
         $this->assertTrue($grade->set_locked(false, false, false));
         $this->assertTrue(empty($grade->locked));
 
-        $grade = new grade_grade($grade_item->get_final(1), false);
+        $grade = new grade_grade($this->grade_grades[0], false);
+        $grade->lib_wrapper = new mock_lib_wrapper();
+        $grade->lib_wrapper->expectOnce('update_record');
+        $grade->lib_wrapper->setreturnvalue('update_record', true);
         $grade->grade_item = $grade_item;
         $grade->itemid = $grade_item->id;
 
@@ -211,20 +199,17 @@ class grade_grade_test extends grade_test {
     }
 
     function test_grade_grade_set_hidden() {
-        global $db;
-
         $grade_item = new grade_item($this->grade_items[0], false);
-        $grade = new grade_grade($grade_item->get_final(1), false);
+        $grade = new grade_grade($this->grade_grades[0], false);
+        $grade->lib_wrapper = new mock_lib_wrapper();
+        $grade->lib_wrapper->expectCallCount('update_record', 2);
+        $grade->lib_wrapper->setreturnvalue('update_record', true);
         $grade->grade_item = $grade_item;
         $grade->itemid = $grade_item->id;
         $this->assertTrue(method_exists($grade, 'set_hidden'));
 
         $this->assertEqual(0, $grade_item->hidden);
         $this->assertEqual(0, $grade->hidden);
-
-        $column = new stdClass();
-        $column->name = 'hidden';
-        $db->setReturnValue('MetaColumns', array($column));
         
         $grade->set_hidden(0);
         $this->assertEqual(0, $grade->hidden);
index 03dc00bf387bd8e0b6d4763e7629809575ef8351..32b80807cfc95b9af8b5ce7523a22e79fb62cfd1 100644 (file)
@@ -59,21 +59,18 @@ class grade_outcome_test extends grade_test {
     }
 
     function test_grade_outcome_insert() {
-        global $db;
         $grade_outcome = new grade_outcome();
+        $grade_outcome->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_outcome, 'insert'));
 
         $grade_outcome->courseid = $this->courseid;
         $grade_outcome->shortname = 'tw';
         $grade_outcome->fullname = 'Team work';
         
-        // Mock insert of data in history table
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
-        
-        // Mock insert of outcome object
-        $db->setReturnValue('GetInsertSQL', true);
-        $db->setReturnValue('Insert_ID', 1);
+        $grade_outcome->lib_wrapper->expectCallCount('insert_record', 3); // main insert, history table insert and grade_outcomes_courses insert
+        $grade_outcome->lib_wrapper->setReturnValue('insert_record', 1);
+        $grade_outcome->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+        $grade_outcome->lib_wrapper->setReturnValue('get_record', array(1));
 
         $grade_outcome->insert();
 
@@ -81,91 +78,71 @@ class grade_outcome_test extends grade_test {
         $this->assertFalse(empty($grade_outcome->timecreated));
         $this->assertFalse(empty($grade_outcome->timemodified));
     }
-
+    
     function test_grade_outcome_update() {
-        global $db;
-
         $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
+        $grade_outcome->lib_wrapper = new mock_lib_wrapper();
         $grade_outcome->timecreated = time() - 200000;
         $grade_outcome->timemodified = $grade_outcome->timecreated;
+        $grade_outcome->timemodified = $grade_outcome->timecreated;
         $timemodified = $grade_outcome->timemodified;
         $timecreated = $grade_outcome->timecreated;
-        $grade_outcome->courseid = null;
+        $grade_outcome->courseid = $this->courseid;
 
         $this->assertTrue(method_exists($grade_outcome, 'update'));
         $grade_outcome->shortname = 'Team work';
         
-        // Mock update: MetaColumns is first returned to compare existing data with new
-        $column = new stdClass();
-        $column->name = 'shortname';
-        $db->setReturnValue('MetaColumns', array($column));
-        
+        $grade_outcome->lib_wrapper->expectOnce('update_record');
+        $grade_outcome->lib_wrapper->setReturnValue('update_record', true);
+        $grade_outcome->lib_wrapper->expectOnce('get_records');
+        $grade_outcome->lib_wrapper->setReturnValue('get_records', false); // Pretend there is no record in grade_outcoms_courses table
+        $grade_outcome->lib_wrapper->expectCallCount('insert_record', 2); // 1. grade_outcome_courses, 2. grade_outcomes_history
+
         $this->assertTrue($grade_outcome->update());
         
         // We expect timecreated to be unchanged, and timemodified to be updated
         $this->assertTrue($grade_outcome->timemodified > $timemodified);
         $this->assertTrue($grade_outcome->timemodified > $grade_outcome->timecreated);
         $this->assertTrue($grade_outcome->timecreated == $timecreated);
-
-        // @TODO When the grade_outcome has a courseid but no match in the grade_outcomes_courses table, the update method should insert a new record in that table
-        
-        // @TODO If history switch is on, an insert should be performed in the grade_outcomes_history table
-
     }
 
     function test_grade_outcome_delete() {
-        global $db; 
         $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
+        $grade_outcome->courseid = $this->courseid;
+        $grade_outcome->lib_wrapper = new mock_lib_wrapper();
         
-        // Mock delete 
-        $this->assertTrue(method_exists($grade_outcome, 'delete')); 
-        $this->assertTrue($grade_outcome->delete());
+        $grade_outcome->lib_wrapper->expectCallCount('delete_records', 2);
+        $grade_outcome->lib_wrapper->expectAt(0, 'delete_records', array('grade_outcomes_courses', 'outcomeid', $grade_outcome->id, 'courseid', $this->courseid));
+        $grade_outcome->lib_wrapper->expectAt(1, 'delete_records', array('grade_outcomes', 'id', $grade_outcome->id));
+        $grade_outcome->lib_wrapper->setReturnValue('delete_records', true);
 
-        // @TODO If history switch is on, an insert should be performed in the grade_outcomes_history table
+        $grade_outcome->lib_wrapper->expectOnce('insert_record'); // grade_history entry
 
-        // @TODO If grade_outcome has a courseid, associated records from grade_outcomes_courses should be deleted also
+        $this->assertTrue(method_exists($grade_outcome, 'delete')); 
+        $this->assertTrue($grade_outcome->delete());
     }
 
     function test_grade_outcome_fetch() {
-        global $db;
-
         $grade_outcome = new grade_outcome();
+        $grade_outcome->lib_wrapper = new mock_lib_wrapper();
+        $grade_outcome->lib_wrapper->expectOnce('get_records_select');
+        $grade_outcome->lib_wrapper->setReturnValue('get_records_select', array($this->grade_outcomes[0]));
         $this->assertTrue(method_exists($grade_outcome, 'fetch'));
-        
-        // Mock fetch
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', array($this->grade_outcomes[0]->id => (array) $this->grade_outcomes[0])); 
 
-        $grade_outcome = grade_outcome::fetch(array('id'=>$this->grade_outcomes[0]->id));
+        $grade_outcome = $grade_outcome->fetch(array('id'=>$this->grade_outcomes[0]->id));
+       
         $this->assertEqual($this->grade_outcomes[0]->id, $grade_outcome->id);
         $this->assertEqual($this->grade_outcomes[0]->shortname, $grade_outcome->shortname);
-        
-        // Mock fetching of scale object
-        $this->reset_mocks();
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', array($this->scale[2]->id => (array) $this->scale[2])); 
-        $grade_outcome->load_scale();
-        $this->assertEqual($this->scale[2]->id, $grade_outcome->scale->id);
     }
 
     function test_grade_outcome_fetch_all() {
         $grade_outcome = new grade_outcome();
+        $grade_outcome->lib_wrapper = new mock_lib_wrapper();
+        $grade_outcome->lib_wrapper->expectOnce('get_records_select');
+        $grade_outcome->lib_wrapper->setReturnValue('get_records_select', $this->grade_outcomes);
         $this->assertTrue(method_exists($grade_outcome, 'fetch_all'));
-        
-        // Mock fetch_all
-        $return_array = array();
-        foreach ($this->grade_outcomes as $go) {
-            $return_array[$go->id] = (array) $go;
-        }
-
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', $return_array); 
-
-        $grade_outcomes = grade_outcome::fetch_all(array());
+
+        $grade_outcomes = $grade_outcome->fetch_all(array());
         $this->assertEqual(count($this->grade_outcomes), count($grade_outcomes));
     }
 }
index 68f1eec4f6646abe4174da38a865a40b43959e49..94245da432c70a333ca3a5766f32c2e045a2500d 100755 (executable)
@@ -67,8 +67,9 @@ class grade_scale_test extends grade_test {
     }
 
     function test_grade_scale_insert() {
-        global $db;
         $grade_scale = new grade_scale();
+        $grade_scale->lib_wrapper = new mock_lib_wrapper();
+
         $this->assertTrue(method_exists($grade_scale, 'insert'));
 
         $grade_scale->name        = 'unittestscale3';
@@ -77,14 +78,11 @@ class grade_scale_test extends grade_test {
         $grade_scale->scale       = 'Distinction, Very Good, Good, Pass, Fail';
         $grade_scale->description = 'This scale is used to mark standard assignments.';
 
-        // Mock insert of data in history table
-        $this->rs->setReturnValue('RecordCount', 1);
-        $this->rs->fields = array(1); 
+        $grade_scale->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+        $grade_scale->lib_wrapper->setReturnValue('insert_record', 1);
+        $grade_scale->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+        $grade_scale->lib_wrapper->setReturnValue('get_record', array(1));
         
-        // Mock insert of outcome object
-        $db->setReturnValue('GetInsertSQL', true);
-        $db->setReturnValue('Insert_ID', 1);
-
         $grade_scale->insert();
 
         $this->assertEqual($grade_scale->id, 1);
@@ -93,8 +91,8 @@ class grade_scale_test extends grade_test {
     }
 
     function test_grade_scale_update() {
-        global $db;
         $grade_scale = new grade_scale($this->scale[0], false);
+        $grade_scale->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_scale, 'update'));
         
         $grade_scale->timecreated = time() - 200000;
@@ -102,10 +100,8 @@ class grade_scale_test extends grade_test {
         $timemodified = $grade_scale->timemodified;
         $timecreated = $grade_scale->timecreated;
 
-        // Mock update: MetaColumns is first returned to compare existing data with new
-        $column = new stdClass();
-        $column->name = 'name';
-        $db->setReturnValue('MetaColumns', array($column));
+        $grade_scale->lib_wrapper->expectOnce('update_record');
+        $grade_scale->lib_wrapper->setReturnValue('update_record', true);
         
         $grade_scale->name = 'Updated info for this unittest grade_scale';
         $this->assertTrue($grade_scale->update());
@@ -118,24 +114,25 @@ class grade_scale_test extends grade_test {
 
     function test_grade_scale_delete() {
         $grade_scale = new grade_scale($this->scale[0], false);
+        $grade_scale->lib_wrapper = new mock_lib_wrapper();
         $this->assertTrue(method_exists($grade_scale, 'delete'));
 
+        $grade_scale->lib_wrapper->expectOnce('delete_records', array('scale', 'id', $grade_scale->id));
+        $grade_scale->lib_wrapper->setReturnValue('delete_records', true);
+        
+        $grade_scale->lib_wrapper->expectOnce('insert_record'); // grade_history entry
+        
         $this->assertTrue($grade_scale->delete());
     }
 
     function test_grade_scale_fetch() {
-        global $db;
-
         $grade_scale = new grade_scale();
+        $grade_scale->lib_wrapper = new mock_lib_wrapper();
+        $grade_scale->lib_wrapper->expectOnce('get_records_select');
+        $grade_scale->lib_wrapper->setReturnValue('get_records_select', array($this->scale[0]));
         $this->assertTrue(method_exists($grade_scale, 'fetch'));
 
-        // Mock fetch
-        $column = new stdClass();
-        $column->name = 'id';
-        $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
-        $this->rs->setReturnValue('GetAssoc', array($this->scale[0]->id => (array) $this->scale[0])); 
-        
-        $grade_scale = grade_scale::fetch(array('id'=>$this->scale[0]->id));
+        $grade_scale = $grade_scale->fetch(array('id'=>$this->scale[0]->id));
         $this->assertEqual($this->scale[0]->id, $grade_scale->id);
         $this->assertEqual($this->scale[0]->name, $grade_scale->name);
     }
index 45788d644b03e3ae4cdcf71127027869036c0f72..17da4ffa41c71d3cba0344985cfbf60fc817cc3c 100644 (file)
@@ -38,6 +38,7 @@ require_once($CFG->libdir . '/grade/grade_item.php');
 require_once($CFG->libdir . '/grade/grade_grade.php');
 require_once($CFG->libdir . '/grade/grade_scale.php');
 require_once($CFG->libdir . '/grade/grade_outcome.php');
+require_once($CFG->libdir . '/grade/lib_wrapper.php');
 
 /***** PUBLIC GRADE API - only these functions should be used in modules *****/
 
index f6dac512c00ea9fe9586cf8f78f26fd42d97deb0..53ad417e2421d55566a7f477f71a33992edf97f6 100644 (file)
@@ -37,8 +37,14 @@ if (!defined('MOODLE_INTERNAL')) {
 require_once($CFG->libdir . '/gradelib.php');
 require_once($CFG->libdir . '/dmllib.php');
 
-Mock::generate('ADODB_' . $CFG->dbtype);
-Mock::generate('ADORecordSet_' . $CFG->dbtype);
+Mock::generate('grade_item', 'mock_grade_item');
+Mock::generate('grade_scale', 'mock_grade_scale');
+Mock::generate('grade_category', 'mock_grade_category');
+Mock::generate('grade_grade', 'mock_grade_grade');
+Mock::generate('grade_outcome', 'mock_grade_outcome');
+Mock::generate('grade_lib_wrapper', 'mock_lib_wrapper');
+Mock::generate('ADODB_' . $CFG->dbtype, 'mock_db');
+Mock::generate('ADORecordSet_' . $CFG->dbtype, 'mock_rs');
 
 /**
  * Here is a brief explanation of the test data set up in these unit tests.
@@ -78,10 +84,10 @@ class grade_test extends UnitTestCase {
     var $forums = array();
     var $courseid = 1;
     var $userid = 1;
-
+       
     var $loaded_tables = array(); // An array of the data tables that were loaded for a specific test. Only these will be "unloaded" at tearDown time
-    var $real_db;
-    var $rs;   
+       var $real_db;
+    var $rs;  
 
     /**
      * Create temporary test tables and entries in the database for these tests.
@@ -97,25 +103,9 @@ class grade_test extends UnitTestCase {
         $CFG->grade_aggregateonlygraded = -1;
         $CFG->grade_aggregateoutcomes = -1;
         $CFG->grade_aggregatesubcats = -1;
-
-        $CFG->old_prefix = $CFG->prefix;
-        $CFG->prefix .= 'unittest_';
-
-        $this->real_db = fullclone($db);
-
-        $this->reset_mocks();
-
-        /*
-        if (!$this->prepare_test_tables()) {
-            die("Could not create all the test tables!");
-        }
-        */
-
-        /*
-        if (!$this->prepare_test_history_tables()) {
-            die("Could not create all the test tables!");
-        }
-        */
+        $CFG->disablegradehistory = false;
+               $this->real_db = fullclone($db);
+        // $this->reset_mocks();
     }
 
     /**
@@ -124,757 +114,23 @@ class grade_test extends UnitTestCase {
      */
     function tearDown() {
         global $CFG, $db;
-        // delete the contents of tables before the test run - the unit test might fail on fatal error and the data would not be deleted!
+               // delete the contents of tables before the test run - the unit test might fail on fatal error and the data would not be deleted!
         foreach ($this->loaded_tables as $table) {
             unset($this->$table);
         }
         $this->loaded_tables = array();
-        $CFG->prefix = $CFG->old_prefix;
-        $db = $this->real_db; 
-    }
-
-    function get_mock($type='db') {
-        global $CFG;
-
-        if ($type == 'db') {
-            $mock_string = 'MockADODB_' . $CFG->dbtype; 
-        } elseif ($type == 'rs') {
-            $mock_string = 'MockADORecordSet_' . $CFG->dbtype; 
-        } else {
-            return false;
-        }
-
-        return new $mock_string();
+               $db = $this->real_db; 
     }
 
     function reset_mocks() {
         global $db, $CFG;
-        $db = $this->get_mock('db');
-        $this->rs = $this->get_mock('rs');
+        $db = new mock_db();
+        $this->rs = new mock_rs();
         $this->rs->EOF = false;
         $db->setReturnReference('Execute', $this->rs);
         $db->setReturnReference('SelectLimit', $this->rs); 
     }
 
-    function prepare_test_tables() {
-        $result = true;
-
-        /// Define table course_modules to be created
-        $table = new XMLDBTable('course_modules');
-
-        if ($result && !table_exists($table)) {
-            /// Adding fields to table course_modules
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('module', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('section', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('added', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('score', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('indent', XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('visibleold', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('groupmode', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('groupingid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('groupmembersonly', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table course_modules
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('groupingid', XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
-
-            /// Adding indexes to table course_modules
-            $table->addIndexInfo('visible', XMLDB_INDEX_NOTUNIQUE, array('visible'));
-            $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
-            $table->addIndexInfo('module', XMLDB_INDEX_NOTUNIQUE, array('module'));
-            $table->addIndexInfo('instance', XMLDB_INDEX_NOTUNIQUE, array('instance'));
-            $table->addIndexInfo('idnumber-course', XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'course'));
-
-            /// Launch create table for course_modules
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table modules to be created
-        $table = new XMLDBTable('modules');
-
-        if ($result && !table_exists($table)) {
-
-            /// Adding fields to table modules
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('cron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('lastcron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('search', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
-
-            /// Adding keys to table modules
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-            /// Adding indexes to table modules
-            $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name'));
-
-            /// Launch create table for modules
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table grade_items to be created
-        $table = new XMLDBTable('grade_items');
-
-        if ($result && !table_exists($table)) {
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
-            $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
-            $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
-            $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
-            $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
-            $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
-            $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
-            $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
-            $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
-
-            /// Launch create table for grade_items
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table grade_categories to be created
-        $table = new XMLDBTable('grade_categories');
-
-        if ($result && !table_exists($table)) {
-
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
-
-            /// Launch create table for grade_categories
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table grade_grades to be created
-        $table = new XMLDBTable('grade_grades');
-
-        if ($result && !table_exists($table)) {
-
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
-            $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
-            $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
-            $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
-            $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
-
-            /// Launch create table for grade_grades
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table grade_outcomes to be created
-        $table = new XMLDBTable('grade_outcomes');
-
-        if ($result && !table_exists($table)) {
-
-            /// Adding fields to table grade_outcomes
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-
-            /// Adding keys to table grade_outcomes
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
-            $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
-
-            /// Launch create table for grade_outcomes
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table scale to be created
-        $table = new XMLDBTable('scale');
-
-        if ($result && !table_exists($table)) {
-
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addIndexInfo('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
-
-            /// Launch create table for scale
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table quiz to be created
-        $table = new XMLDBTable('quiz');
-
-        if ($result && !table_exists($table)) {
-            /// Adding fields to table quiz
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('intro', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('optionflags', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('penaltyscheme', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('attempts', XMLDB_TYPE_INTEGER, '6', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('attemptonlast', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('grademethod', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('decimalpoints', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '2');
-            $table->addFieldInfo('review', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('questionsperpage', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('shufflequestions', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('shuffleanswers', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('questions', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('sumgrades', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('grade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timelimit', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('password', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('subnet', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('popup', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('delay1', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('delay2', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table quiz
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-            /// Adding indexes to table quiz
-            $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
-
-            /// Launch create table for quiz
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-    
-        /// Define table quiz_grades to be created
-        $table = new XMLDBTable('quiz_grades');
-
-        if ($result && !table_exists($table)) { 
-
-            /// Adding fields to table quiz_grades
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('quiz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('grade', XMLDB_TYPE_FLOAT, null, null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table quiz_grades
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('quiz', XMLDB_KEY_FOREIGN, array('quiz'), 'quiz', array('id'));
-
-            /// Adding indexes to table quiz_grades
-            $table->addIndexInfo('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
-
-            /// Launch create table for quiz_grades
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-        
-        /// Define table assignment to be created
-        $table = new XMLDBTable('assignment');
-        
-        if ($result && !table_exists($table)) {
-
-            /// Adding fields to table assignment
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('format', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('assignmenttype', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('resubmit', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('preventlate', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('emailteachers', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('var1', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, '0');
-            $table->addFieldInfo('var2', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, '0');
-            $table->addFieldInfo('var3', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, '0');
-            $table->addFieldInfo('var4', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, '0');
-            $table->addFieldInfo('var5', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, '0');
-            $table->addFieldInfo('maxbytes', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '100000');
-            $table->addFieldInfo('timedue', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timeavailable', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('grade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table assignment
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-            /// Adding indexes to table assignment
-            $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
-
-            /// Launch create table for assignment
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-        
-        /// Define table forum to be created
-        $table = new XMLDBTable('forum');
-        
-        if ($result && !table_exists($table)) { 
-            /// Adding fields to table forum
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('type', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, XMLDB_ENUM, array('single', 'news', 'general', 'social', 'eachuser', 'teacher', 'qanda'), 'general');
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('intro', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('assessed', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('assesstimestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('assesstimefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('scale', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('maxbytes', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('forcesubscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('trackingtype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('rsstype', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('rssarticles', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('warnafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('blockafter', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('blockperiod', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table forum
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-            /// Adding indexes to table forum
-            $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
-
-            /// Launch create table for forum
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table quiz_attempts to be created
-        $table = new XMLDBTable('quiz_attempts');
-        
-        if ($result && !table_exists($table)) { 
-            /// Adding fields to table quiz_attempts
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('uniqueid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('quiz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('attempt', XMLDB_TYPE_INTEGER, '6', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('sumgrades', XMLDB_TYPE_FLOAT, null, null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timestart', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timefinish', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('layout', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('preview', XMLDB_TYPE_INTEGER, '3', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table quiz_attempts
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('uniqueid', XMLDB_KEY_FOREIGN_UNIQUE, array('uniqueid'));
-            $table->addKeyInfo('quiz', XMLDB_KEY_FOREIGN, array('quiz'), 'quiz', array('id'));
-
-            /// Adding indexes to table quiz_attempts
-            $table->addIndexInfo('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
-
-            /// Launch create table for quiz_attempts
-            $result = $result && create_table($table, true, false);
-        } else {
-            delete_records($table->name);
-        }
-
-
-        return $result;
-    }
-
-    function prepare_test_history_tables() {
-        $result = true;
-
-        /// Define table grade_items to be created
-        $table = new XMLDBTable('grade_items_history');
-
-        if (!table_exists($table)) {
-
-        /// Adding fields to table grade_items_history
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
-            $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
-            $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
-            $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
-            $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
-            $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
-            $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-
-        /// Adding keys to table grade_items_history
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_items', array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
-            $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
-            $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
-
-        /// Adding indexes to table grade_items_history
-            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
-
-        /// Launch create table for grade_items_history
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table grade_categories to be created
-        $table = new XMLDBTable('grade_categories_history');
-
-
-        if ($result && !table_exists($table)) {
-
-        /// Adding fields to table grade_categories_history
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-        /// Adding keys to table grade_categories_history
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_categories', array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
-
-        /// Adding indexes to table grade_categories_history
-            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
-
-        /// Launch create table for grade_categories_history
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table grade_grades to be created
-        $table = new XMLDBTable('grade_grades_history');
-
-        if ($result && !table_exists($table)) {
-
-        /// Adding fields to table grade_grades_history
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
-            $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-
-        /// Adding keys to table grade_grades_history
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades', array('id'));
-            $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
-            $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
-            $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
-            $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
-            $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
-
-        /// Adding indexes to table grade_grades_history
-            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
-
-        /// Launch create table for grade_grades_history
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-
-        /// Define table grade_outcomes to be created
-        $table = new XMLDBTable('grade_outcomes_history');
-
-        if ($result && !table_exists($table)) {
-
-        /// Adding fields to table grade_outcomes_history
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-
-        /// Adding keys to table grade_outcomes_history
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_outcomes', array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-            $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
-            $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
-
-        /// Adding indexes to table grade_outcomes_history
-            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
-
-        /// Launch create table for grade_outcomes_history
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-
-        /// Define table scale to be created
-        $table = new XMLDBTable('scale_history');
-
-
-        if ($result && !table_exists($table)) {
-
-        /// Adding fields to table scale_history
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
-
-        /// Adding keys to table scale_history
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'scales', array('id'));
-            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
-
-        /// Adding indexes to table scale_history
-            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
-
-        /// Launch create table for scale_history
-            $result = $result && create_table($table, true, false);
-
-        } else {
-            delete_records($table->name);
-        }
-        
-        /// Define table user to be created
-        $table = new XMLDBTable('user');
-        
-        if ($result && !table_exists($table)) { 
-
-            /// Adding fields to table user
-            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
-            $table->addFieldInfo('auth', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 'manual');
-            $table->addFieldInfo('confirmed', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('policyagreed', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('mnethostid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('username', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('password', XMLDB_TYPE_CHAR, '32', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '64', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('firstname', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('lastname', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('email', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('emailstop', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('icq', XMLDB_TYPE_CHAR, '15', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('skype', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('yahoo', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('aim', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('msn', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('phone1', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('phone2', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('institution', XMLDB_TYPE_CHAR, '40', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('department', XMLDB_TYPE_CHAR, '30', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('address', XMLDB_TYPE_CHAR, '70', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('city', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('country', XMLDB_TYPE_CHAR, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('lang', XMLDB_TYPE_CHAR, '30', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 'en');
-            $table->addFieldInfo('theme', XMLDB_TYPE_CHAR, '50', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('timezone', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '99');
-            $table->addFieldInfo('firstaccess', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('lastaccess', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('lastlogin', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('currentlogin', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('lastip', XMLDB_TYPE_CHAR, '15', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('secret', XMLDB_TYPE_CHAR, '15', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('picture', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('url', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('mailformat', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('maildigest', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('maildisplay', XMLDB_TYPE_INTEGER, '2', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '2');
-            $table->addFieldInfo('htmleditor', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('ajax', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('autosubscribe', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '1');
-            $table->addFieldInfo('trackforums', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('trustbitmask', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
-            $table->addFieldInfo('imagealt', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, null, null, null, null, null);
-            $table->addFieldInfo('screenreader', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '0');
-
-            /// Adding keys to table user
-            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-
-            /// Adding indexes to table user
-            $table->addIndexInfo('username', XMLDB_INDEX_UNIQUE, array('mnethostid', 'username'));
-            $table->addIndexInfo('deleted', XMLDB_INDEX_NOTUNIQUE, array('deleted'));
-            $table->addIndexInfo('confirmed', XMLDB_INDEX_NOTUNIQUE, array('confirmed'));
-            $table->addIndexInfo('firstname', XMLDB_INDEX_NOTUNIQUE, array('firstname'));
-            $table->addIndexInfo('lastname', XMLDB_INDEX_NOTUNIQUE, array('lastname'));
-            $table->addIndexInfo('city', XMLDB_INDEX_NOTUNIQUE, array('city'));
-            $table->addIndexInfo('country', XMLDB_INDEX_NOTUNIQUE, array('country'));
-            $table->addIndexInfo('lastaccess', XMLDB_INDEX_NOTUNIQUE, array('lastaccess'));
-            $table->addIndexInfo('email', XMLDB_INDEX_NOTUNIQUE, array('email'));
-            $table->addIndexInfo('auth', XMLDB_INDEX_NOTUNIQUE, array('auth'));
-            $table->addIndexInfo('idnumber', XMLDB_INDEX_NOTUNIQUE, array('idnumber'));
-
-            /// Launch create table for user
-            $result = $result && create_table($table, true, false);
-
-            /// Main savepoint reached
-        } else {
-            delete_records($table->name);
-        }
-
-        return $result;
-    }
-
     /**
      * Load scale data into the database, and adds the corresponding objects to this class' variable.
      */
@@ -962,13 +218,14 @@ class grade_test extends UnitTestCase {
 
         $course_category = new stdClass();
         $course_category->id = $id++;
+        $course_category->courseid    = $this->courseid;
         $course_category->fullname = "Course grade category";
         $course_category->path = null;
         $course_category->parent = null;
         $course_category->aggregate = GRADE_AGGREGATE_MEAN;
         $course_category->timecreated = $course_category->timemodified = time();
         
-        $this->grade_categories[0] = $course_category;
+        $this->grade_categories[] = $course_category;
 
         $grade_category = new stdClass();
 
@@ -984,7 +241,7 @@ class grade_test extends UnitTestCase {
         $grade_category->depth = 2;
 
         $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
-        $this->grade_categories[0] = $grade_category;
+        $this->grade_categories[] = $grade_category;
 
         $grade_category = new stdClass();
 
@@ -995,12 +252,12 @@ class grade_test extends UnitTestCase {
         $grade_category->aggregateonlygraded = 1;
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
-        $grade_category->parent      = $this->grade_categories[0]->id;
+        $grade_category->parent      = $this->grade_categories[1]->id;
         $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 3;
 
-        $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
-        $this->grade_categories[1] = $grade_category;
+        $grade_category->path = $this->grade_categories[1]->path.$grade_category->id.'/';
+        $this->grade_categories[] = $grade_category;
 
         $grade_category = new stdClass();
 
@@ -1011,12 +268,12 @@ class grade_test extends UnitTestCase {
         $grade_category->aggregateonlygraded = 1;
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
-        $grade_category->parent      = $this->grade_categories[0]->id;
+        $grade_category->parent      = $this->grade_categories[1]->id;
         $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 3;
 
-        $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
-        $this->grade_categories[2] = $grade_category;
+        $grade_category->path = $this->grade_categories[1]->path.$grade_category->id.'/';
+        $this->grade_categories[] = $grade_category;
 
         // A category with no parent, but grade_items as children
 
@@ -1034,7 +291,7 @@ class grade_test extends UnitTestCase {
         $grade_category->depth = 2;
 
         $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
-        $this->grade_categories[3] = $grade_category;
+        $this->grade_categories[] = $grade_category;
 
         $this->loaded_tables[] = 'grade_categories';
     }
@@ -1238,7 +495,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->categoryid = $this->grade_categories[1]->id;
+        $grade_item->categoryid = $this->grade_categories[2]->id;
         $grade_item->itemname = 'unittestgradeitem2';
         $grade_item->itemtype = 'import';
         $grade_item->itemmodule = 'assignment';
@@ -1259,7 +516,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->categoryid = $this->grade_categories[2]->id;
+        $grade_item->categoryid = $this->grade_categories[3]->id;
         $grade_item->itemname = 'unittestgradeitem3';
         $grade_item->itemtype = 'mod';
         $grade_item->itemmodule = 'forum';
@@ -1280,7 +537,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->iteminstance = $this->grade_categories[0]->id;
+        $grade_item->iteminstance = $this->grade_categories[1]->id;
         $grade_item->itemname = 'unittestgradeitemcategory1';
         $grade_item->needsupdate = 0;
         $grade_item->itemtype = 'category';
@@ -1298,7 +555,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->iteminstance = $this->grade_categories[1]->id;
+        $grade_item->iteminstance = $this->grade_categories[2]->id;
         $grade_item->itemname = 'unittestgradeitemcategory2';
         $grade_item->itemtype = 'category';
         $grade_item->gradetype = GRADE_TYPE_VALUE;
@@ -1316,7 +573,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->iteminstance = $this->grade_categories[2]->id;
+        $grade_item->iteminstance = $this->grade_categories[3]->id;
         $grade_item->itemname = 'unittestgradeitemcategory3';
         $grade_item->itemtype = 'category';
         $grade_item->gradetype = GRADE_TYPE_VALUE;
@@ -1357,7 +614,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->categoryid = $this->grade_categories[3]->id;
+        $grade_item->categoryid = $this->grade_categories[4]->id;
         $grade_item->itemname = 'singleparentitem1';
         $grade_item->itemtype = 'mod';
         $grade_item->itemmodule = 'forum';
@@ -1377,7 +634,7 @@ class grade_test extends UnitTestCase {
 
         $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
-        $grade_item->categoryid = $this->grade_categories[3]->id;
+        $grade_item->categoryid = $this->grade_categories[4]->id;
         $grade_item->itemname = 'singleparentitem2';
         $grade_item->itemtype = 'mod';
         $grade_item->itemmodule = 'forum';
@@ -1400,7 +657,7 @@ class grade_test extends UnitTestCase {
         $grade_item->itemname = 'grade_item for level1 category';
         $grade_item->itemtype = 'category';
         $grade_item->itemmodule = 'quiz';
-        $grade_item->iteminstance = $this->grade_categories[3]->id;
+        $grade_item->iteminstance = $this->grade_categories[4]->id;
         $grade_item->needsupdate = true;
         $grade_item->gradetype = GRADE_TYPE_VALUE;
         $grade_item->grademin = 0;
index aefdd31e6dd38c39364efe2e38bd2c6d333810fb..047685fe362a332c07d0a62a00bcc5d553f5788c 100644 (file)
             return $code;
         }
     }
-?>
\ No newline at end of file
+?>