]> git.mjollnir.org Git - moodle.git/commitdiff
Unit test refactoring using mock objects. NOT FINISHED: testgradecategory and testgra...
authornicolasconnault <nicolasconnault>
Wed, 7 Nov 2007 17:59:33 +0000 (17:59 +0000)
committernicolasconnault <nicolasconnault>
Wed, 7 Nov 2007 17:59:33 +0000 (17:59 +0000)
lang/en_utf8/xmldb.php
lib/ddllib.php
lib/grade/grade_category.php
lib/grade/grade_grade.php
lib/grade/grade_object.php
lib/grade/grade_scale.php
lib/grade/simpletest/testgradecategory.php
lib/grade/simpletest/testgradegrades.php
lib/grade/simpletest/testgradeoutcome.php
lib/grade/simpletest/testgradescale.php
lib/simpletest/fixtures/gradetest.php

index a6ec4c5cca4f657c93fa9790cf972cc37df2fd68..b9afe43662925d839298a3f7bea23a57ef87d98d 100644 (file)
@@ -44,6 +44,7 @@ $string['delete_xml_file'] = 'Delete XML File';
 $string['down'] = 'Down';
 $string['duplicate'] = 'Duplicate';
 $string['duplicatefieldname'] = 'Another field with that name exists';
+$string['duplicatekeyname'] = 'Another key with that name exists';
 $string['edit'] = 'Edit';
 $string['edit_field'] = 'Edit Field';
 $string['edit_index'] = 'Edit Index';
@@ -56,6 +57,7 @@ $string['enumvaluesincorrect'] = 'Incorrect values for enum field';
 $string['field'] = 'Field';
 $string['fieldnameempty'] = 'Name field empty';
 $string['fields'] = 'Fields';
+$string['fieldsusedinkey'] = '[[incomplete lang string at line ' . __LINE__ . ' in ' . __FILE__ . ']]';
 $string['filenotwriteable'] = 'File not writeable';
 $string['floatincorrectdecimals'] = 'Incorrect number of decimals for float field';
 $string['floatincorrectlength'] = 'Incorrect length for float field';
index e6ce7ee30a409630ce33ddb3a717648e6abc8b4a..9df026e58d659c3d38335c240c880a5a016bf794 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  //
 //           (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com  //
 //                                                                       //
 // This program is free software; you can redistribute it and/or modify  //
index b0b928919638410f0005b48fc6f771283c71c249..afd44c656d5e952fe3c387c9f0a8cf7967de4c88 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  //
@@ -283,6 +283,7 @@ class grade_category extends grade_object {
 
         if (empty($this->courseid)) {
             error('Can not insert grade category without course id!');
+            return false;
         }
 
         if (empty($this->parent)) {
@@ -314,11 +315,11 @@ class grade_category extends grade_object {
      * @return bool success
      */
     function insert_course_category($courseid) {
-        $this->courseid  = $courseid;
-        $this->fullname  = get_string('coursegradecategory', 'grades');
-        $this->path      = null;
-        $this->parent    = null;
-        $this->aggregate = GRADE_AGGREGATE_MEAN;
+        $this->courseid    = $courseid;
+        $this->fullname    = get_string('coursegradecategory', 'grades');
+        $this->path        = null;
+        $this->parent      = null;
+        $this->aggregation = GRADE_AGGREGATE_MEAN;
 
         $this->apply_forced_settings();
 
index c9c0bb96d31ff2b628a5ba45bb9bf4834ff6e36a..32d1e1e5f7d810ee55db308def262efd30b88172 100644 (file)
@@ -240,8 +240,11 @@ class grade_grade extends grade_object {
      */
     function is_locked() {
         $this->load_grade_item();
-
-        return !empty($this->locked) or $this->grade_item->is_locked();
+        if (empty($this->grade_item)) {
+            return !empty($this->locked);
+        } else {
+            return !empty($this->locked) or $this->grade_item->is_locked();
+        }
     }
 
     /**
@@ -429,8 +432,11 @@ class grade_grade extends grade_object {
      */
     function is_hidden() {
         $this->load_grade_item();
-
-        return $this->hidden == 1 or ($this->hidden != 0 and $this->hidden > time()) or $this->grade_item->is_hidden();
+        if (empty($this->grade_item)) {
+            return $this->hidden == 1 or ($this->hidden != 0 and $this->hidden > time());
+        } else {
+            return $this->hidden == 1 or ($this->hidden != 0 and $this->hidden > time()) or $this->grade_item->is_hidden();
+        } 
     }
 
     /**
index d31bf6f16ae2cb732056338cd6a97efe20896908..30b8ce39c970b630d2edb618cc588c17869bef9c 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  //
@@ -127,11 +127,9 @@ class grade_object {
     /**
      * Factory method - uses the parameters to retrieve matching instance from the DB.
      * @static final protected
-     * @return mixed object insatnce or false if not found
+     * @return mixed object instance or false if not found
      */
     function fetch_helper($table, $classname, $params) {
-        // we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
-        // in PHP5 we could do it much better
         if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
             if (count($instances) > 1) {
                 // we should not tolerate any errors here - problems might appear later
@@ -149,8 +147,6 @@ class grade_object {
      * @return mixed array of object instances or false if not found
      */
     function fetch_all_helper($table, $classname, $params) {
-        // we have to do use this hack because of the incomplete OOP implementation in PHP4 :-(
-        // in PHP5 we could do it much better
         $instance = new $classname();
 
         $classvars = (array)$instance;
index f2067b16254e918af45461730e37c54c8b930448..b5516010736ea7cfb0bd58fd47861c8c3c0e439e 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  //
@@ -104,6 +104,7 @@ class grade_scale extends grade_object {
      * @return int PK ID if successful, false otherwise
      */
     function insert($source=null) {
+        $this->timecreated = time();
         $this->timemodified = time();
         return parent::insert($source);
     }
index c907413171a3a5827ce1c06dde6fc7542eee006e..02c4af6b3aa9cbd69b7ee80097e194e61474db5f 100755 (executable)
@@ -26,7 +26,7 @@
 /**
  * Unit tests for grade_category object.
  *
- * @author nicolas@moodle.com
+ * @author nicolasconnault@gmail.com
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package moodlecore
  */
@@ -39,15 +39,34 @@ require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class grade_category_test extends grade_test {
 
+    function setUp() {
+        parent::setUp();
+        $this->load_grade_items();        
+    }
+
     function test_grade_category_construct() {
-        $course_category = grade_category::fetch_course_category($this->courseid);
+        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);
@@ -55,11 +74,15 @@ class grade_category_test extends grade_test {
         $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);
@@ -70,11 +93,16 @@ class grade_category_test extends grade_test {
         $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]);
         $this->assertTrue(method_exists($grade_category, 'build_path'));
@@ -260,9 +288,6 @@ class grade_category_test extends grade_test {
         $this->assertEqual(9.4743, $grade);
     }
 
-    /**
-     * TODO implement
-     */
     function test_grade_category_is_aggregationcoef_used() {
 
     }
@@ -378,9 +403,7 @@ class grade_category_test extends grade_test {
         $category = grade_category::fetch_course_category($this->courseid);
         $this->assertTrue(empty($category->parent));
     }
-    /**
-     * TODO implement
-     */
+    
     function test_grade_category_is_editable() {
 
     }
@@ -424,5 +447,6 @@ class grade_category_test extends grade_test {
         $grade->insert();
         return $grade->rawgrade;
     }
+    */
 }
 ?>
index 33cbe363125f0e05c835d88a3e9be6eb877a1912..0265d41f128fdb69ac01c65f9c392ff925211074 100755 (executable)
@@ -38,6 +38,15 @@ if (!defined('MOODLE_INTERNAL')) {
 require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class grade_grade_test extends grade_test {
+    
+    function setUp() {
+        parent::setUp();
+        $this->load_grade_grades();
+    }
+
+    function tearDown() {
+        parent::tearDown();
+    }
 
     function test_grade_grade_construct() {
         $params = new stdClass();
@@ -54,6 +63,7 @@ class grade_grade_test extends grade_test {
     }
 
     function test_grade_grade_insert() {
+        global $db;
         $grade_grade = new grade_grade();
         $this->assertTrue(method_exists($grade_grade, 'insert'));
 
@@ -62,89 +72,137 @@ class grade_grade_test extends grade_test {
         $grade_grade->rawgrade = 88;
         $grade_grade->rawgrademax = 110;
         $grade_grade->rawgrademin = 18;
+        
+        $grade_item = new grade_item($this->grade_items[0], false);
+        $grade_grade->grade_item = $grade_item;
 
         // Check the grade_item's needsupdate variable first
-        $grade_grade->load_grade_item();
         $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->insert();
 
-        $last_grade_grade = end($this->grade_grades);
+        $this->assertEqual($grade_grade->id, 1);
 
-        $this->assertEqual($grade_grade->id, $last_grade_grade->id + 1);
-        $this->assertFalse(empty($grade_grade->timecreated));
-        $this->assertFalse(empty($grade_grade->timemodified));
+        // timecreated doesn't refer to creation in the DB, but to time of submission. Timemodified refers to date of grading
+        $this->assertTrue(empty($grade_grade->timecreated));
+        $this->assertTrue(empty($grade_grade->timemodified));
     }
 
     function test_grade_grade_update() {
-        $grade_grade = new grade_grade($this->grade_grades[0]);
+        $grade_grade = new grade_grade($this->grade_grades[0], false);
         $this->assertTrue(method_exists($grade_grade, 'update'));
     }
 
     function test_grade_grade_fetch() {
-        $grade_grade = new grade_grade();
+        global $db;
+        $grade_grade = new grade_grade($this->grade_grades[0], false);
         $this->assertTrue(method_exists($grade_grade, 'fetch'));
 
-        $grades = grade_grade::fetch(array('id'=>$this->grade_grades[0]->id));
-        $this->assertEqual($this->grade_grades[0]->id, $grades->id);
-        $this->assertEqual($this->grade_grades[0]->rawgrade, $grades->rawgrade);
+        // 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)); 
+        
+        $grades = grade_grade::fetch(array('id'=>$grade_grade->id));
+
+        $this->assertEqual($grade_grade->id, $grades->id);
+        $this->assertEqual($grade_grade->rawgrade, $grades->rawgrade);
     }
 
     function test_grade_grade_fetch_all() {
         $grade_grade = new grade_grade();
         $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;
+        }
+
+        $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());
-        $this->assertEqual(count($this->grade_grades), count($grades));
+        $this->assertEqual(count($this->grade_grades), count($grades)); 
     }
 
     function test_grade_grade_load_grade_item() {
-        $grade_grade = new grade_grade($this->grade_grades[0]);
+        $grade_grade = new grade_grade($this->grade_grades[0], false);
         $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)); 
+        
         $this->assertNotNull($grade_grade->load_grade_item());
         $this->assertNotNull($grade_grade->grade_item);
         $this->assertEqual($this->grade_items[0]->id, $grade_grade->grade_item->id);
     }
 
-
     function test_grade_grade_standardise_score() {
         $this->assertEqual(4, round(grade_grade::standardise_score(6, 0, 7, 0, 5)));
         $this->assertEqual(40, grade_grade::standardise_score(50, 30, 80, 0, 100));
     }
 
-
+    /**
+     * In this test we always set the 2nd param of set_locked() to false, because it 
+     * would otherwise trigger the refresh_grades method, which is not being tested here.
+     */ 
     function test_grade_grade_set_locked() {
-        $grade_item = new grade_item($this->grade_items[0]);
-        $grade = new grade_grade($grade_item->get_final(1));
+        global $db;
+        $grade_item = new grade_item($this->grade_items[0], false);
+        $grade = new grade_grade($grade_item->get_final(1), false);
+        $grade->grade_item = $grade_item;
+        $grade->itemid = $grade_item->id;
+
         $this->assertTrue(method_exists($grade, 'set_locked'));
 
         $this->assertTrue(empty($grade_item->locked));
         $this->assertTrue(empty($grade->locked));
         
-        // Test locking the grade
-        $this->assertTrue($grade->set_locked(true));
-        $this->assertFalse(empty($grade->locked));
-        $this->assertTrue($grade->set_locked(false));
-        $this->assertTrue(empty($grade->locked));
+        // Test locking the grade when needsupdate is true
+        $grade->grade_item->needsupdate = true;
+        $this->assertFalse($grade->set_locked(true, false, false)); 
 
-        // Test locking the grade item with cascading on
-        $this->assertTrue($grade_item->set_locked(true, true, false));
-        $grade = new grade_grade($grade_item->get_final(1));
+        // Test locking the grade when needsupdate is false
+        $grade->grade_item->needsupdate = false;
+        
+        $column = new stdClass();
+        $column->name = 'locked';
+        $db->setReturnValue('MetaColumns', array($column));
 
-        // Grade should already be locked
-        $this->assertFalse(empty($grade->locked)); 
-        $this->assertTrue($grade->set_locked(false));
+        $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));
 
-        $this->assertTrue($grade_item->set_locked(false));
-        $grade = new grade_grade($grade_item->get_final(1));
+        $grade = new grade_grade($grade_item->get_final(1), false);
+        $grade->grade_item = $grade_item;
+        $grade->itemid = $grade_item->id;
 
-        $this->assertTrue($grade->set_locked(false));
+        $this->assertTrue($grade->set_locked(false, false, false));
     }
 
+
     function test_grade_grade_is_locked() {
-        $grade = new grade_grade($this->grade_grades[0]);
+        $grade = new grade_grade($this->grade_grades[0], false);
+        $grade->grade_item = new grade_item($this->grade_items[0], false);
         $this->assertTrue(method_exists($grade, 'is_locked'));
 
         $this->assertFalse($grade->is_locked());
@@ -153,22 +211,33 @@ class grade_grade_test extends grade_test {
     }
 
     function test_grade_grade_set_hidden() {
-        $grade_item = new grade_item($this->grade_items[0]);
-        $grade = new grade_grade($grade_item->get_final(1));
+        global $db;
+
+        $grade_item = new grade_item($this->grade_items[0], false);
+        $grade = new grade_grade($grade_item->get_final(1), false);
+        $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);
 
         $grade->set_hidden(1);
         $this->assertEqual(1, $grade->hidden);
+
+        // @TODO test with cascading on (2nd param set to true)
     }
 
     function test_grade_grade_is_hidden() {
-        $grade = new grade_grade($this->grade_grades[0]);
+        $grade = new grade_grade($this->grade_grades[0], false);
+        $grade->grade_item = new grade_item($this->grade_items[0], false);
         $this->assertTrue(method_exists($grade, 'is_hidden'));
 
         $this->assertFalse($grade->is_hidden());
@@ -181,7 +250,5 @@ class grade_grade_test extends grade_test {
         $grade->hidden = time()+666;
         $this->assertTrue($grade->is_hidden());
     }
-
-
 }
 ?>
index a8724503b5102b968fbfb38e47d1f1b37ba7ed04..03dc00bf387bd8e0b6d4763e7629809575ef8351 100644 (file)
@@ -38,6 +38,14 @@ if (!defined('MOODLE_INTERNAL')) {
 require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class grade_outcome_test extends grade_test {
+    function setUp() {
+        parent::setUp();
+        $this->load_grade_outcomes();
+    }
+
+    function tearDown() {
+        parent::tearDown();
+    }
 
     function test_grade_outcome_construct() {
         $params = new stdClass();
@@ -51,46 +59,93 @@ class grade_outcome_test extends grade_test {
     }
 
     function test_grade_outcome_insert() {
+        global $db;
         $grade_outcome = new grade_outcome();
         $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->insert();
 
-        $last_grade_outcome = end($this->grade_outcomes);
-
-        $this->assertEqual($grade_outcome->id, $last_grade_outcome->id + 1);
+        $this->assertEqual($grade_outcome->id, 1);
         $this->assertFalse(empty($grade_outcome->timecreated));
         $this->assertFalse(empty($grade_outcome->timemodified));
     }
 
     function test_grade_outcome_update() {
-        $grade_outcome = new grade_outcome($this->grade_outcomes[0]);
+        global $db;
+
+        $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
+        $grade_outcome->timecreated = time() - 200000;
+        $grade_outcome->timemodified = $grade_outcome->timecreated;
+        $timemodified = $grade_outcome->timemodified;
+        $timecreated = $grade_outcome->timecreated;
+        $grade_outcome->courseid = null;
+
         $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));
+        
         $this->assertTrue($grade_outcome->update());
-        $shortname = get_field('grade_outcomes', 'shortname', 'id', $this->grade_outcomes[0]->id);
-        $this->assertEqual($grade_outcome->shortname, $shortname);
+        
+        // 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() {
-        $grade_outcome = new grade_outcome($this->grade_outcomes[0]);
-        $this->assertTrue(method_exists($grade_outcome, 'delete'));
-
+        global $db; 
+        $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
+        
+        // Mock delete 
+        $this->assertTrue(method_exists($grade_outcome, 'delete')); 
         $this->assertTrue($grade_outcome->delete());
-        $this->assertFalse(get_record('grade_outcomes', 'id', $grade_outcome->id));
+
+        // @TODO If history switch is on, an insert should be performed in the grade_outcomes_history table
+
+        // @TODO If grade_outcome has a courseid, associated records from grade_outcomes_courses should be deleted also
     }
 
     function test_grade_outcome_fetch() {
+        global $db;
+
         $grade_outcome = new grade_outcome();
         $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));
         $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);
     }
@@ -98,6 +153,17 @@ class grade_outcome_test extends grade_test {
     function test_grade_outcome_fetch_all() {
         $grade_outcome = new grade_outcome();
         $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());
         $this->assertEqual(count($this->grade_outcomes), count($grade_outcomes));
index b3e90a97b144c6b12e34bdcc7b823973d47a1208..68f1eec4f6646abe4174da38a865a40b43959e49 100755 (executable)
@@ -7,7 +7,7 @@
 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
 //          http://moodle.org                                            //
 //                                                                       //
-// 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  //
@@ -39,6 +39,15 @@ require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class grade_scale_test extends grade_test {
 
+    function setUp() {
+        parent::setUp();
+        $this->load_scale();
+    }
+
+    function tearDown() {
+        parent::tearDown();
+    }
+
     function test_scale_construct() {
         $params = new stdClass();
 
@@ -58,6 +67,7 @@ class grade_scale_test extends grade_test {
     }
 
     function test_grade_scale_insert() {
+        global $db;
         $grade_scale = new grade_scale();
         $this->assertTrue(method_exists($grade_scale, 'insert'));
 
@@ -67,53 +77,83 @@ 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.';
 
-        $grade_scale->insert();
+        // 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);
 
-        $last_grade_scale = end($this->scale);
+        $grade_scale->insert();
 
-        $this->assertEqual($grade_scale->id, $last_grade_scale->id + 1);
-        $this->assertTrue(!empty($grade_scale->timecreated));
-        $this->assertTrue(!empty($grade_scale->timemodified));
+        $this->assertEqual($grade_scale->id, 1);
+        $this->assertFalse(empty($grade_scale->timecreated));
+        $this->assertFalse(empty($grade_scale->timemodified));
     }
 
     function test_grade_scale_update() {
-        $grade_scale = new grade_scale($this->scale[0]);
+        global $db;
+        $grade_scale = new grade_scale($this->scale[0], false);
         $this->assertTrue(method_exists($grade_scale, 'update'));
-
+        
+        $grade_scale->timecreated = time() - 200000;
+        $grade_scale->timemodified = $grade_scale->timecreated;
+        $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->name = 'Updated info for this unittest grade_scale';
         $this->assertTrue($grade_scale->update());
-        $name = get_field('scale', 'name', 'id', $this->scale[0]->id);
-        $this->assertEqual($grade_scale->name, $name);
+        
+        // We expect timecreated to be unchanged, and timemodified to be updated
+        $this->assertTrue($grade_scale->timemodified > $timemodified);
+        $this->assertTrue($grade_scale->timemodified > $grade_scale->timecreated);
+        $this->assertTrue($grade_scale->timecreated == $timecreated);
     }
 
     function test_grade_scale_delete() {
-        $grade_scale = new grade_scale($this->scale[0]);
+        $grade_scale = new grade_scale($this->scale[0], false);
         $this->assertTrue(method_exists($grade_scale, 'delete'));
 
         $this->assertTrue($grade_scale->delete());
-        $this->assertFalse(get_record('scale', 'id', $grade_scale->id));
     }
 
     function test_grade_scale_fetch() {
+        global $db;
+
         $grade_scale = new grade_scale();
         $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));
         $this->assertEqual($this->scale[0]->id, $grade_scale->id);
         $this->assertEqual($this->scale[0]->name, $grade_scale->name);
     }
 
     function test_scale_load_items() {
-        $scale = new grade_scale($this->scale[0]);
+        $scale = new grade_scale($this->scale[0], false);
         $this->assertTrue(method_exists($scale, 'load_items'));
 
         $scale->load_items();
         $this->assertEqual(7, count($scale->scale_items));
         $this->assertEqual('Fairly neutral', $scale->scale_items[2]);
+
+        $newscale = 'Item1, Item2, Item3, Item4';
+        $this->assertEqual(4, count($scale->load_items($newscale)));
     }
 
     function test_scale_compact_items() {
-        $scale = new grade_scale($this->scale[0]);
+        $scale = new grade_scale($this->scale[0], false);
         $this->assertTrue(method_exists($scale, 'compact_items'));
 
         $scale->load_items();
@@ -121,8 +161,7 @@ class grade_scale_test extends grade_test {
         $scale->compact_items();
 
         // The original string and the new string may have differences in whitespace around the delimiter, and that's OK
-        $this->assertEqual(preg_replace('/\s*,\s*/', ',', $this->scale[0]->scale), $scale->scale);
+        $this->assertEqual(preg_replace('/\s*,\s*' . '/', ',', $this->scale[0]->scale), $scale->scale);
     }
-
 }
 ?>
index ee2de170355814a31c38ad28617ff5dc88cae162..f6dac512c00ea9fe9586cf8f78f26fd42d97deb0 100644 (file)
@@ -36,7 +36,9 @@ if (!defined('MOODLE_INTERNAL')) {
  */
 require_once($CFG->libdir . '/gradelib.php');
 require_once($CFG->libdir . '/dmllib.php');
-require_once($CFG->libdir . '/ddllib.php');
+
+Mock::generate('ADODB_' . $CFG->dbtype);
+Mock::generate('ADORecordSet_' . $CFG->dbtype);
 
 /**
  * Here is a brief explanation of the test data set up in these unit tests.
@@ -77,6 +79,10 @@ class grade_test extends UnitTestCase {
     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;   
+
     /**
      * Create temporary test tables and entries in the database for these tests.
      * These tests have to work on a brand new site.
@@ -84,7 +90,7 @@ class grade_test extends UnitTestCase {
      */
     function setUp() {
         // Set global category settings to -1 (not force)
-        global $CFG;
+        global $CFG, $db;
         $CFG->grade_droplow = -1;
         $CFG->grade_keephigh = -1;
         $CFG->grade_aggregation = -1;
@@ -94,18 +100,60 @@ class grade_test extends UnitTestCase {
 
         $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!");
         }
+        */
+    }
 
-        foreach ($this->tables as $table) {
-            $function = "load_$table";
-            $this->$function();
+    /**
+     * Drop test tables from DB.
+     * Restore original $CFG->prefix.
+     */
+    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!
+        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();
+    }
+
+    function reset_mocks() {
+        global $db, $CFG;
+        $db = $this->get_mock('db');
+        $this->rs = $this->get_mock('rs');
+        $this->rs->EOF = false;
+        $db->setReturnReference('Execute', $this->rs);
+        $db->setReturnReference('SelectLimit', $this->rs); 
     }
 
     function prepare_test_tables() {
@@ -411,7 +459,7 @@ class grade_test extends UnitTestCase {
             $table->addIndexInfo('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
 
             /// Launch create table for quiz_grades
-            $result = $result && create_table($table);
+            $result = $result && create_table($table, true, false);
         } else {
             delete_records($table->name);
         }
@@ -449,7 +497,7 @@ class grade_test extends UnitTestCase {
             $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
 
             /// Launch create table for assignment
-            $result = $result && create_table($table);
+            $result = $result && create_table($table, true, false);
         } else {
             delete_records($table->name);
         }
@@ -485,15 +533,46 @@ class grade_test extends UnitTestCase {
             $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
 
             /// Launch create table for forum
-            $result = $result && create_table($table);
+            $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;
 
@@ -713,21 +792,87 @@ class grade_test extends UnitTestCase {
         } else {
             delete_records($table->name);
         }
+        
+        /// Define table user to be created
+        $table = new XMLDBTable('user');
+        
+        if ($result && !table_exists($table)) { 
 
-        return $result;
-    }
+            /// 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');
 
-    /**
-     * Drop test tables from DB.
-     * Restore original $CFG->prefix.
-     */
-    function tearDown() {
-        global $CFG;
-        // 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->tables as $table) {
-            unset($this->$table);
+            /// 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);
         }
-        $CFG->prefix = $CFG->old_prefix;
+
+        return $result;
     }
 
     /**
@@ -736,6 +881,7 @@ class grade_test extends UnitTestCase {
     function load_scale() {
         $scale = new stdClass();
 
+        $scale->id          = 1;
         $scale->name        = 'unittestscale1';
         $scale->courseid    = $this->courseid;
         $scale->userid      = $this->userid;
@@ -743,14 +889,13 @@ class grade_test extends UnitTestCase {
         $scale->description = 'This scale defines some of qualities that make posts helpful within the Moodle help forums.\n Your feedback will help others see how their posts are being received.';
         $scale->timemodified = mktime();
 
-        if ($scale->id = insert_record('scale', $scale)) {
-            $this->scale[0] = $scale;
-            $temp = explode(',', $scale->scale);
-            $this->scalemax[0] = count($temp) -1;
-        }
+        $this->scale[0] = $scale;
+        $temp = explode(',', $scale->scale);
+        $this->scalemax[0] = count($temp) -1;
 
         $scale = new stdClass();
 
+        $scale->id          = 2;
         $scale->name        = 'unittestscale2';
         $scale->courseid    = $this->courseid;
         $scale->userid      = $this->userid;
@@ -758,14 +903,13 @@ class grade_test extends UnitTestCase {
         $scale->description = 'This scale is used to mark standard assignments.';
         $scale->timemodified = mktime();
 
-        if ($scale->id = insert_record('scale', $scale)) {
-            $this->scale[1] = $scale;
-            $temp = explode(',', $scale->scale);
-            $this->scalemax[1] = count($temp) -1;
-        }
+        $this->scale[1] = $scale;
+        $temp = explode(',', $scale->scale);
+        $this->scalemax[1] = count($temp) -1;
 
         $scale = new stdClass();
 
+        $scale->id          = 3;
         $scale->name        = 'unittestscale3';
         $scale->courseid    = $this->courseid;
         $scale->userid      = $this->userid;
@@ -775,12 +919,11 @@ class grade_test extends UnitTestCase {
         $temp  = explode(',', $scale->scale);
         $scale->max         = count($temp) -1;
 
-        if ($scale->id = insert_record('scale', $scale)) {
-            $this->scale[2] = $scale;
-            $temp = explode(',', $scale->scale);
-            $this->scalemax[2] = count($temp) -1;
-        }
+        $this->scale[2] = $scale;
+        $temp = explode(',', $scale->scale);
+        $this->scalemax[2] = count($temp) -1;
 
+        $scale->id          = 4;
         $scale->name        = 'unittestscale4';
         $scale->courseid    = $this->courseid;
         $scale->userid      = $this->userid;
@@ -790,12 +933,11 @@ class grade_test extends UnitTestCase {
         $temp  = explode(',', $scale->scale);
         $scale->max         = count($temp) -1;
 
-        if ($scale->id = insert_record('scale', $scale)) {
-            $this->scale[3] = $scale;
-            $temp = explode(',', $scale->scale);
-            $this->scalemax[3] = count($temp) -1;
-        }
+        $this->scale[3] = $scale;
+        $temp = explode(',', $scale->scale);
+        $this->scalemax[3] = count($temp) -1;
 
+        $scale->id          = 5;
         $scale->name        = 'unittestscale5';
         $scale->courseid    = $this->courseid;
         $scale->userid      = $this->userid;
@@ -805,22 +947,32 @@ class grade_test extends UnitTestCase {
         $temp  = explode(',', $scale->scale);
         $scale->max         = count($temp) -1;
 
-        if ($scale->id = insert_record('scale', $scale)) {
-            $this->scale[4] = $scale;
-            $temp = explode(',', $scale->scale);
-            $this->scalemax[4] = count($temp) -1;
-        }
+        $this->scale[4] = $scale;
+        $temp = explode(',', $scale->scale);
+        $this->scalemax[4] = count($temp) -1;
+
+        $this->loaded_tables[] = 'scale';
     }
 
     /**
      * Load grade_category data into the database, and adds the corresponding objects to this class' variable.
      */
     function load_grade_categories() {
-
-        $course_category = grade_category::fetch_course_category($this->courseid);
+        $id = 1;
+
+        $course_category = new stdClass();
+        $course_category->id = $id++;
+        $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;
 
         $grade_category = new stdClass();
 
+        $grade_category->id          = $id++;
         $grade_category->fullname    = 'unittestcategory1';
         $grade_category->courseid    = $this->courseid;
         $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
@@ -828,18 +980,15 @@ class grade_test extends UnitTestCase {
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
         $grade_category->parent      = $course_category->id;
-        $grade_category->timecreated = mktime();
-        $grade_category->timemodified = mktime();
+        $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 2;
 
-        if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
-            $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
-            update_record('grade_categories', $grade_category);
-            $this->grade_categories[0] = $grade_category;
-        }
+        $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
+        $this->grade_categories[0] = $grade_category;
 
         $grade_category = new stdClass();
 
+        $grade_category->id          = $id++;
         $grade_category->fullname    = 'unittestcategory2';
         $grade_category->courseid    = $this->courseid;
         $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
@@ -847,18 +996,15 @@ class grade_test extends UnitTestCase {
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
         $grade_category->parent      = $this->grade_categories[0]->id;
-        $grade_category->timecreated = mktime();
-        $grade_category->timemodified = mktime();
+        $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 3;
 
-        if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
-            $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
-            update_record('grade_categories', $grade_category);
-            $this->grade_categories[1] = $grade_category;
-        }
+        $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
+        $this->grade_categories[1] = $grade_category;
 
         $grade_category = new stdClass();
 
+        $grade_category->id          = $id++;
         $grade_category->fullname    = 'unittestcategory3';
         $grade_category->courseid    = $this->courseid;
         $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
@@ -866,20 +1012,17 @@ class grade_test extends UnitTestCase {
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
         $grade_category->parent      = $this->grade_categories[0]->id;
-        $grade_category->timecreated = mktime();
-        $grade_category->timemodified = mktime();
+        $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 3;
 
-        if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
-            $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
-            update_record('grade_categories', $grade_category);
-            $this->grade_categories[2] = $grade_category;
-        }
+        $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
+        $this->grade_categories[2] = $grade_category;
 
         // A category with no parent, but grade_items as children
 
         $grade_category = new stdClass();
 
+        $grade_category->id          = $id++;
         $grade_category->fullname    = 'level1category';
         $grade_category->courseid    = $this->courseid;
         $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
@@ -887,15 +1030,13 @@ class grade_test extends UnitTestCase {
         $grade_category->keephigh    = 0;
         $grade_category->droplow     = 0;
         $grade_category->parent      = $course_category->id;
-        $grade_category->timecreated = mktime();
-        $grade_category->timemodified = mktime();
+        $grade_category->timecreated = $grade_category->timemodified = mktime();
         $grade_category->depth = 2;
 
-        if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
-            $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
-            update_record('grade_categories', $grade_category);
-            $this->grade_categories[3] = $grade_category;
-        }
+        $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
+        $this->grade_categories[3] = $grade_category;
+
+        $this->loaded_tables[] = 'grade_categories';
     }
 
     /**
@@ -903,22 +1044,21 @@ class grade_test extends UnitTestCase {
      */
     function load_modules() {
         $module = new stdClass();
+        $module->id   = 1;
         $module->name = 'assignment';
-        if ($module->id = insert_record('modules', $module)) {
-            $this->modules[0] = $module;
-        }
+        $this->modules[] = $module;
 
         $module = new stdClass();
+        $module->id   = 2;
         $module->name = 'quiz';
-        if ($module->id = insert_record('modules', $module)) {
-            $this->modules[1] = $module;
-        }
+        $this->modules[] = $module;
 
         $module = new stdClass();
+        $module->id   = 3;
         $module->name = 'forum';
-        if ($module->id = insert_record('modules', $module)) {
-            $this->modules[2] = $module;
-        }
+        $this->modules[] = $module;
+
+        $this->loaded_tables[] = 'modules';
     }
 
     /**
@@ -926,26 +1066,22 @@ class grade_test extends UnitTestCase {
      */
     function load_quiz() {
         $quiz = new stdClass();
+        $quiz->id = 1;
         $quiz->course = $this->courseid;
         $quiz->name = 'test quiz';
         $quiz->intro = 'let us quiz you!';
         $quiz->questions = '1,2';
-        if ($quiz->id = insert_record('quiz', $quiz)) {
-            $this->quizzes[0] = $quiz;
-        } else {
-            die("Can't create a test quiz!!!");
-        }
+        $this->quizzes[] = $quiz;
 
         $quiz = new stdClass();
+        $quiz->id = 2;
         $quiz->course = $this->courseid;
         $quiz->name = 'test quiz 2';
         $quiz->intro = 'let us quiz you again!';
         $quiz->questions = '1,3';
-        if ($quiz->id = insert_record('quiz', $quiz)) {
-            $this->quizzes[1] = $quiz;
-        }  else {
-            die("Can't create a test quiz!!!");
-        }
+        $this->quizzes[] = $quiz;
+
+        $this->loaded_tables[] = 'quiz';
     }
 
     /**
@@ -953,14 +1089,13 @@ class grade_test extends UnitTestCase {
      */
     function load_assignment() {
         $assignment = new stdClass();
+        $assignment->id = 1;
         $assignment->course = $this->courseid;
         $assignment->name = 'test assignment';
         $assignment->description = 'What is the purpose of life?';
-        if ($assignment->id = insert_record('assignment', $assignment)) {
-            $this->assignments[0] = $assignment;
-        } else {
-            die("Can't create a test assignment!!!");
-        }
+        $this->assignments[] = $assignment;
+
+        $this->loaded_tables[] = 'assignment';
     }
 
     /**
@@ -968,99 +1103,118 @@ class grade_test extends UnitTestCase {
      */
     function load_forum() {
         $forum = new stdClass();
+        $forum->id = 1;
         $forum->course = $this->courseid;
         $forum->name = 'test forum 1';
         $forum->intro = 'Another test forum';
-        if ($forum->id = insert_record('forum', $forum)) {
-            $this->forums[0] = $forum;
-        } else {
-            die("Can't create a test forum!!!");
-        }
-        
+        $this->forums[] = $forum;
+    
         $forum = new stdClass();
+        $forum->id = 2;
         $forum->course = $this->courseid;
         $forum->name = 'test forum 2';
         $forum->intro = 'Another test forum';
-        if ($forum->id = insert_record('forum', $forum)) {
-            $this->forums[1] = $forum;
-        } else {
-            die("Can't create a test forum!!!");
-        }
-        
+        $this->forums[] = $forum;
+    
         $forum = new stdClass();
+        $forum->id = 3;
         $forum->course = $this->courseid;
         $forum->name = 'test forum 3';
         $forum->intro = 'Another test forum';
-        if ($forum->id = insert_record('forum', $forum)) {
-            $this->forums[2] = $forum;
-        } else {
-            die("Can't create a test forum!!!");
-        }
+        $this->forums[] = $forum;
+
+        $this->loaded_tables[] = 'forum';
     }
 
     /**
      * Load module instance entries in course_modules table
      */
     function load_course_modules() {
+        if (!in_array('modules', $this->loaded_tables)) {
+            $this->load_modules();
+        }
+        if (!in_array('quiz', $this->loaded_tables)) {
+            $this->load_quiz();
+        }
+        if (!in_array('assignment', $this->loaded_tables)) {
+            $this->load_assignment();
+        }
+        if (!in_array('forum', $this->loaded_tables)) {
+            $this->load_forum();
+        }
+
         $course_module = new stdClass();
+        $course_module->id = 1;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[0]->id;
         $course_module->instance = $this->assignments[0]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[0] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
 
         $course_module = new stdClass();
+        $course_module->id = 2;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[1]->id;
         $course_module->instance = $this->quizzes[0]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[1] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
 
         $course_module = new stdClass();
+        $course_module->id = 3;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[1]->id;
         $course_module->instance = $this->quizzes[1]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[2] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
 
         $course_module = new stdClass();
+        $course_module->id = 4;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[2]->id;
         $course_module->instance = $this->forums[0]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[3] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
 
         $course_module = new stdClass();
+        $course_module->id = 5;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[2]->id;
         $course_module->instance = $this->forums[1]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[4] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
 
         $course_module = new stdClass();
+        $course_module->id = 6;
         $course_module->course = $this->courseid;
         $course_module->module = $this->modules[2]->id;
         $course_module->instance = $this->forums[2]->id;
-        if ($course_module->id = insert_record('course_modules', $course_module)) {
-            $this->course_modules[5] = $course_module;
-        }
+        $this->course_modules[] = $course_module;
+
+        $this->loaded_tables[] = 'course_modules';
     }
 
     /**
      * Load grade_item data into the database, and adds the corresponding objects to this class' variable.
      */
     function load_grade_items() {
+        if (!in_array('scale', $this->loaded_tables)) {
+            $this->load_scale();
+        }
+        if (!in_array('grade_categories', $this->loaded_tables)) {
+            $this->load_grade_categories();
+        }
+        if (!in_array('quiz', $this->loaded_tables)) {
+            $this->load_quiz();
+        }
+        if (!in_array('assignment', $this->loaded_tables)) {
+            $this->load_assignment();
+        }
+        if (!in_array('forum', $this->loaded_tables)) {
+            $this->load_forum();
+        }
+        
+        $id = 1;
+        
+        $course_category = $this->grade_categories[0];
 
-        $course_category = grade_category::fetch_course_category($this->courseid);
-
-        // id = 0
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $this->grade_categories[1]->id;
         $grade_item->itemname = 'unittestgradeitem1';
@@ -1076,14 +1230,13 @@ class grade_test extends UnitTestCase {
         $grade_item->timecreated = mktime();
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 3;
+        $grade_item->needsupdate = false;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[0] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
-        // id = 1
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $this->grade_categories[1]->id;
         $grade_item->itemname = 'unittestgradeitem2';
@@ -1100,13 +1253,11 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 4;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[1] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
-        // id = 2
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $this->grade_categories[2]->id;
         $grade_item->itemname = 'unittestgradeitem3';
@@ -1122,14 +1273,12 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 6;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[2] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
         // Load grade_items associated with the 3 categories
-        // id = 3
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->iteminstance = $this->grade_categories[0]->id;
         $grade_item->itemname = 'unittestgradeitemcategory1';
@@ -1143,13 +1292,11 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 1;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[3] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
-        // id = 4
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->iteminstance = $this->grade_categories[1]->id;
         $grade_item->itemname = 'unittestgradeitemcategory2';
@@ -1163,13 +1310,11 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 2;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[4] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
-        // id = 5
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->iteminstance = $this->grade_categories[2]->id;
         $grade_item->itemname = 'unittestgradeitemcategory3';
@@ -1183,14 +1328,12 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 5;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[5] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
         // Orphan grade_item
-        // id = 6
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $course_category->id;
         $grade_item->itemname = 'unittestorphangradeitem1';
@@ -1207,14 +1350,12 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 7;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[6] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
         // 2 grade items under level1category
-        // id = 7
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $this->grade_categories[3]->id;
         $grade_item->itemname = 'singleparentitem1';
@@ -1230,13 +1371,11 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 9;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[7] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
-        // id = 8
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $this->grade_categories[3]->id;
         $grade_item->itemname = 'singleparentitem2';
@@ -1251,14 +1390,12 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 10;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[8] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
         // Grade_item for level1category
-        // id = 9
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->itemname = 'grade_item for level1 category';
         $grade_item->itemtype = 'category';
@@ -1273,14 +1410,12 @@ class grade_test extends UnitTestCase {
         $grade_item->timemodified = mktime();
         $grade_item->sortorder = 8;
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[9] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
 
         // Manual grade_item
-        // id = 10
         $grade_item = new stdClass();
 
+        $grade_item->id = $id++;
         $grade_item->courseid = $this->courseid;
         $grade_item->categoryid = $course_category->id;
         $grade_item->itemname = 'manual grade_item';
@@ -1294,9 +1429,9 @@ class grade_test extends UnitTestCase {
         $grade_item->timecreated = mktime();
         $grade_item->timemodified = mktime();
 
-        if ($grade_item->id = insert_record('grade_items', $grade_item)) {
-            $this->grade_items[10] = $grade_item;
-        }
+        $this->grade_items[] = $grade_item;
+
+        $this->loaded_tables[] = 'grade_items';
 
     }
 
@@ -1304,10 +1439,19 @@ class grade_test extends UnitTestCase {
      * Load grade_grades data into the database, and adds the corresponding objects to this class' variable.
      */
     function load_grade_grades() {
+        if (!in_array('grade_items', $this->loaded_tables)) {
+            $this->load_grade_items();
+        }
+        $id = 1;
+        $course_category = $this->grade_categories[0];
+
         // Grades for grade_item 1
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[0]->id;
+        $grade->grade_item = $this->grade_items[0];
         $grade->userid = 1;
+        $grade->parent = $course_category->id;
         $grade->rawgrade = 15; // too small
         $grade->finalgrade = 30;
         $grade->timecreated = mktime();
@@ -1317,74 +1461,70 @@ class grade_test extends UnitTestCase {
         $grade->feedback = 'Good, but not good enough..';
         $grade->feedbackformat = FORMAT_PLAIN;
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[0] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[0]->id;
+        $grade->parent = $course_category->id;
         $grade->userid = 2;
         $grade->rawgrade = 40;
         $grade->finalgrade = 40;
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[1] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[0]->id;
+        $grade->parent = $course_category->id;
         $grade->userid = 3;
         $grade->rawgrade = 170; // too big
         $grade->finalgrade = 110;
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[2] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
 
         // No raw grades for grade_item 2 - it is calculated
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[1]->id;
         $grade->userid = 1;
         $grade->finalgrade = 60;
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[3] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[1]->id;
         $grade->userid = 2;
         $grade->finalgrade = 70;
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[4] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[1]->id;
         $grade->userid = 3;
         $grade->finalgrade = 100;
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[5] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
 
         // Grades for grade_item 3
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[2]->id;
         $grade->userid = 1;
         $grade->rawgrade = 2;
@@ -1393,11 +1533,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[6] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[2]->id;
         $grade->userid = 2;
         $grade->rawgrade = 3;
@@ -1406,11 +1545,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[2]->id;
         $grade->userid = 3;
         $grade->rawgrade = 1;
@@ -1419,13 +1557,12 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         // Grades for grade_item 7
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[6]->id;
         $grade->userid = 1;
         $grade->rawgrade = 97;
@@ -1433,11 +1570,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[6]->id;
         $grade->userid = 2;
         $grade->rawgrade = 49;
@@ -1445,11 +1581,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[6]->id;
         $grade->userid = 3;
         $grade->rawgrade = 67;
@@ -1457,13 +1592,12 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         // Grades for grade_item 8
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[7]->id;
         $grade->userid = 2;
         $grade->rawgrade = 3;
@@ -1471,11 +1605,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[7]->id;
         $grade->userid = 3;
         $grade->rawgrade = 6;
@@ -1483,13 +1616,12 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         // Grades for grade_item 9
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[8]->id;
         $grade->userid = 1;
         $grade->rawgrade = 20;
@@ -1497,11 +1629,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[8]->id;
         $grade->userid = 2;
         $grade->rawgrade = 50;
@@ -1509,11 +1640,10 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
 
         $grade = new stdClass();
+        $grade->id = $id++;
         $grade->itemid = $this->grade_items[7]->id;
         $grade->userid = 3;
         $grade->rawgrade = 100;
@@ -1521,47 +1651,51 @@ class grade_test extends UnitTestCase {
         $grade->timecreated = mktime();
         $grade->timemodified = mktime();
 
-        if ($grade->id = insert_record('grade_grades', $grade)) {
-            $this->grade_grades[] = $grade;
-        }
+        $this->grade_grades[] = $grade;
+
+        $this->loaded_tables[] = 'grade_grades';
     }
 
     /**
      * Load grade_outcome data into the database, and adds the corresponding objects to this class' variable.
      */
     function load_grade_outcomes() {
+        if (!in_array('scale', $this->loaded_tables)) {
+            $this->load_scale();
+        }
+        $id = 1;
+        
         // Calculation for grade_item 1
         $grade_outcome = new stdClass();
+        $grade_outcome->id = $id++;
         $grade_outcome->shortname = 'Team work';
         $grade_outcome->timecreated = mktime();
         $grade_outcome->timemodified = mktime();
         $grade_outcome->scaleid = $this->scale[2]->id;
 
-        if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
-            $this->grade_outcomes[] = $grade_outcome;
-        }
+        $this->grade_outcomes[] = $grade_outcome;
 
         // Calculation for grade_item 2
         $grade_outcome = new stdClass();
+        $grade_outcome->id = $id++;
         $grade_outcome->shortname = 'Complete circuit board';
         $grade_outcome->timecreated = mktime();
         $grade_outcome->timemodified = mktime();
         $grade_outcome->scaleid = $this->scale[3]->id;
 
-        if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
-            $this->grade_outcomes[] = $grade_outcome;
-        }
+        $this->grade_outcomes[] = $grade_outcome;
 
         // Calculation for grade_item 3
         $grade_outcome = new stdClass();
+        $grade_outcome->id = $id++;
         $grade_outcome->shortname = 'Debug Java program';
         $grade_outcome->timecreated = mktime();
         $grade_outcome->timemodified = mktime();
         $grade_outcome->scaleid = $this->scale[4]->id;
 
-        if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
-            $this->grade_outcomes[] = $grade_outcome;
-        }
+        $this->grade_outcomes[] = $grade_outcome;
+
+        $this->loaded_tables[] = 'grade_outcomes';
     }
 
 /**