35d527b4fccc2ed3837c0f94154dd1791de3e4c7
[moodle.git] / lib / grade / tests / grade_item_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * @package    core_grades
19  * @category   phpunit
20  * @copyright  nicolas@moodle.com
21  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
24 defined('MOODLE_INTERNAL') || die();
26 require_once(__DIR__.'/fixtures/lib.php');
28 class grade_item_testcase extends grade_base_testcase {
29     public function test_grade_item() {
30         $this->sub_test_grade_item_construct();
31         $this->sub_test_grade_item_insert();
32         $this->sub_test_grade_item_delete();
33         $this->sub_test_grade_item_update();
34         $this->sub_test_grade_item_load_scale();
35         $this->sub_test_grade_item_load_outcome();
36         $this->sub_test_grade_item_qualifies_for_regrading();
37         $this->sub_test_grade_item_force_regrading();
38         $this->sub_test_grade_item_fetch();
39         $this->sub_test_grade_item_fetch_all();
40         $this->sub_test_grade_item_get_all_finals();
41         $this->sub_test_grade_item_get_final();
42         $this->sub_test_grade_item_get_sortorder();
43         $this->sub_test_grade_item_set_sortorder();
44         $this->sub_test_grade_item_move_after_sortorder();
45         $this->sub_test_grade_item_get_name();
46         $this->sub_test_grade_item_set_parent();
47         $this->sub_test_grade_item_get_parent_category();
48         $this->sub_test_grade_item_load_parent_category();
49         $this->sub_test_grade_item_get_item_category();
50         $this->sub_test_grade_item_load_item_category();
51         $this->sub_test_grade_item_regrade_final_grades();
52         $this->sub_test_grade_item_adjust_raw_grade();
53         $this->sub_test_grade_item_set_locked();
54         $this->sub_test_grade_item_is_locked();
55         $this->sub_test_grade_item_set_hidden();
56         $this->sub_test_grade_item_is_hidden();
57         $this->sub_test_grade_item_is_category_item();
58         $this->sub_test_grade_item_is_course_item();
59         $this->sub_test_grade_item_fetch_course_item();
60         $this->sub_test_grade_item_depends_on();
61         $this->sub_test_refresh_grades();
62         $this->sub_test_grade_item_is_calculated();
63         $this->sub_test_grade_item_set_calculation();
64         $this->sub_test_grade_item_get_calculation();
65         $this->sub_test_grade_item_compute();
66     }
68     protected function sub_test_grade_item_construct() {
69         $params = new stdClass();
71         $params->courseid = $this->courseid;
72         $params->categoryid = $this->grade_categories[1]->id;
73         $params->itemname = 'unittestgradeitem4';
74         $params->itemtype = 'mod';
75         $params->itemmodule = 'database';
76         $params->iteminfo = 'Grade item used for unit testing';
78         $grade_item = new grade_item($params, false);
80         $this->assertEquals($params->courseid, $grade_item->courseid);
81         $this->assertEquals($params->categoryid, $grade_item->categoryid);
82         $this->assertEquals($params->itemmodule, $grade_item->itemmodule);
83     }
85     protected function sub_test_grade_item_insert() {
86         $grade_item = new grade_item();
87         $this->assertTrue(method_exists($grade_item, 'insert'));
89         $grade_item->courseid = $this->courseid;
90         $grade_item->categoryid = $this->grade_categories[1]->id;
91         $grade_item->itemname = 'unittestgradeitem4';
92         $grade_item->itemtype = 'mod';
93         $grade_item->itemmodule = 'quiz';
94         $grade_item->iteminfo = 'Grade item used for unit testing';
96         $grade_item->insert();
98         $last_grade_item = end($this->grade_items);
100         $this->assertEquals($grade_item->id, $last_grade_item->id + 1);
101         $this->assertEquals(11, $grade_item->sortorder);
103         //keep our reference collection the same as what is in the database
104         $this->grade_items[] = $grade_item;
105     }
107     protected function sub_test_grade_item_delete() {
108         global $DB;
109         $grade_item = new grade_item($this->grade_items[7],false);//use a grade item not touched by previous (or future) tests
110         $this->assertTrue(method_exists($grade_item, 'delete'));
112         $this->assertTrue($grade_item->delete());
114         $this->assertFalse($DB->get_record('grade_items', array('id' => $grade_item->id)));
116         //keep our reference collection the same as the database
117         unset($this->grade_items[7]);
118     }
120     protected function sub_test_grade_item_update() {
121         global $DB;
122         $grade_item = new grade_item($this->grade_items[0], false);
123         $this->assertTrue(method_exists($grade_item, 'update'));
125         $grade_item->iteminfo = 'Updated info for this unittest grade_item';
127         $this->assertTrue($grade_item->update());
129         $grade_item->grademin = 14;
130         $this->assertTrue($grade_item->qualifies_for_regrading());
131         $this->assertTrue($grade_item->update());
133         $iteminfo = $DB->get_field('grade_items', 'iteminfo', array('id' => $this->grade_items[0]->id));
134         $this->assertEquals($grade_item->iteminfo, $iteminfo);
135     }
137     protected function sub_test_grade_item_load_scale() {
138         $grade_item = new grade_item($this->grade_items[2], false);
139         $this->assertTrue(method_exists($grade_item, 'load_scale'));
140         $scale = $grade_item->load_scale();
141         $this->assertFalse(empty($grade_item->scale));
142         $this->assertEquals($scale->id, $this->grade_items[2]->scaleid);
143     }
145     protected function sub_test_grade_item_load_outcome() {
146         $grade_item = new grade_item($this->grade_items[0], false);
147         $this->assertTrue(method_exists($grade_item, 'load_outcome'));
148         //TODO: add tests
149     }
151     protected function sub_test_grade_item_qualifies_for_regrading() {
152         $grade_item = new grade_item($this->grade_items[3], false);//use a grade item not touched by previous tests
153         $this->assertTrue(method_exists($grade_item, 'qualifies_for_regrading'));
155         $this->assertFalse($grade_item->qualifies_for_regrading());
157         $grade_item->iteminfo = 'Updated info for this unittest grade_item';
159         $this->assertFalse($grade_item->qualifies_for_regrading());
161         $grade_item->grademin = 14;
163         $this->assertTrue($grade_item->qualifies_for_regrading());
164     }
166     protected function sub_test_grade_item_force_regrading() {
167         $grade_item = new grade_item($this->grade_items[3], false);//use a grade item not touched by previous tests
168         $this->assertTrue(method_exists($grade_item, 'force_regrading'));
170         $this->assertEquals(0, $grade_item->needsupdate);
172         $grade_item->force_regrading();
173         $this->assertEquals(1, $grade_item->needsupdate);
174         $grade_item->update_from_db();
175         $this->assertEquals(1, $grade_item->needsupdate);
176     }
178     protected function sub_test_grade_item_fetch() {
179         $grade_item = new grade_item();
180         $this->assertTrue(method_exists($grade_item, 'fetch'));
182         //not using $this->grade_items[0] as it's iteminfo was modified by sub_test_grade_item_qualifies_for_regrading()
183         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[1]->id));
184         $this->assertEquals($this->grade_items[1]->id, $grade_item->id);
185         $this->assertEquals($this->grade_items[1]->iteminfo, $grade_item->iteminfo);
187         $grade_item = grade_item::fetch(array('itemtype'=>$this->grade_items[1]->itemtype, 'itemmodule'=>$this->grade_items[1]->itemmodule));
188         $this->assertEquals($this->grade_items[1]->id, $grade_item->id);
189         $this->assertEquals($this->grade_items[1]->iteminfo, $grade_item->iteminfo);
190     }
192     protected function sub_test_grade_item_fetch_all() {
193         $grade_item = new grade_item();
194         $this->assertTrue(method_exists($grade_item, 'fetch_all'));
196         $grade_items = grade_item::fetch_all(array('courseid'=>$this->courseid));
197         $this->assertEquals(count($this->grade_items), count($grade_items)-1);//-1 to account for the course grade item
198     }
200     // Retrieve all final scores for a given grade_item.
201     protected function sub_test_grade_item_get_all_finals() {
202         $grade_item = new grade_item($this->grade_items[0], false);
203         $this->assertTrue(method_exists($grade_item, 'get_final'));
205         $final_grades = $grade_item->get_final();
206         $this->assertEquals(3, count($final_grades));
207     }
210     // Retrieve all final scores for a specific userid.
211     protected function sub_test_grade_item_get_final() {
212         $grade_item = new grade_item($this->grade_items[0], false);
213         $this->assertTrue(method_exists($grade_item, 'get_final'));
214         $final_grade = $grade_item->get_final($this->user[1]->id);
215         $this->assertEquals($this->grade_grades[0]->finalgrade, $final_grade->finalgrade);
216     }
218     protected function sub_test_grade_item_get_sortorder() {
219         $grade_item = new grade_item($this->grade_items[0], false);
220         $this->assertTrue(method_exists($grade_item, 'get_sortorder'));
221         $sortorder = $grade_item->get_sortorder();
222         $this->assertEquals($this->grade_items[0]->sortorder, $sortorder);
223     }
225     protected function sub_test_grade_item_set_sortorder() {
226         $grade_item = new grade_item($this->grade_items[0], false);
227         $this->assertTrue(method_exists($grade_item, 'set_sortorder'));
228         $grade_item->set_sortorder(999);
229         $this->assertEquals($grade_item->sortorder, 999);
230     }
232     protected function sub_test_grade_item_move_after_sortorder() {
233         $grade_item = new grade_item($this->grade_items[0], false);
234         $this->assertTrue(method_exists($grade_item, 'move_after_sortorder'));
235         $grade_item->move_after_sortorder(5);
236         $this->assertEquals($grade_item->sortorder, 6);
238         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[0]->id));
239         $this->assertEquals($grade_item->sortorder, 6);
241         $after = grade_item::fetch(array('id'=>$this->grade_items[6]->id));
242         $this->assertEquals($after->sortorder, 8);
243     }
245     protected function sub_test_grade_item_get_name() {
246         $grade_item = new grade_item($this->grade_items[0], false);
247         $this->assertTrue(method_exists($grade_item, 'get_name'));
249         $name = $grade_item->get_name();
250         $this->assertEquals($this->grade_items[0]->itemname, $name);
251     }
253     protected function sub_test_grade_item_set_parent() {
254         $grade_item = new grade_item($this->grade_items[0], false);
255         $this->assertTrue(method_exists($grade_item, 'set_parent'));
257         $old = $grade_item->get_parent_category();
258         $new = new grade_category($this->grade_categories[3], false);
259         $new_item = $new->get_grade_item();
261         $this->assertTrue($grade_item->set_parent($new->id));
263         $new_item->update_from_db();
264         $grade_item->update_from_db();
266         $this->assertEquals($grade_item->categoryid, $new->id);
267     }
269     protected function sub_test_grade_item_get_parent_category() {
270         $grade_item = new grade_item($this->grade_items[0], false);
271         $this->assertTrue(method_exists($grade_item, 'get_parent_category'));
273         $category = $grade_item->get_parent_category();
274         $this->assertEquals($this->grade_categories[1]->fullname, $category->fullname);
275     }
277     protected function sub_test_grade_item_load_parent_category() {
278         $grade_item = new grade_item($this->grade_items[0], false);
279         $this->assertTrue(method_exists($grade_item, 'load_parent_category'));
281         $category = $grade_item->load_parent_category();
282         $this->assertEquals($this->grade_categories[1]->fullname, $category->fullname);
283         $this->assertEquals($this->grade_categories[1]->fullname, $grade_item->parent_category->fullname);
284     }
286     protected function sub_test_grade_item_get_item_category() {
287         $grade_item = new grade_item($this->grade_items[3], false);
288         $this->assertTrue(method_exists($grade_item, 'get_item_category'));
290         $category = $grade_item->get_item_category();
291         $this->assertEquals($this->grade_categories[0]->fullname, $category->fullname);
292     }
294     protected function sub_test_grade_item_load_item_category() {
295         $grade_item = new grade_item($this->grade_items[3], false);
296         $this->assertTrue(method_exists($grade_item, 'load_item_category'));
298         $category = $grade_item->load_item_category();
299         $this->assertEquals($this->grade_categories[0]->fullname, $category->fullname);
300         $this->assertEquals($this->grade_categories[0]->fullname, $grade_item->item_category->fullname);
301     }
303     // Test update of all final grades
304     protected function sub_test_grade_item_regrade_final_grades() {
305         $grade_item = new grade_item($this->grade_items[0], false);
306         $this->assertTrue(method_exists($grade_item, 'regrade_final_grades'));
307         $this->assertEquals(true, $grade_item->regrade_final_grades());
308         //TODO: add more tests
309     }
311     // Test the adjust_raw_grade method
312     protected function sub_test_grade_item_adjust_raw_grade() {
313         $grade_item = new grade_item($this->grade_items[2], false); // anything but assignment module!
314         $this->assertTrue(method_exists($grade_item, 'adjust_raw_grade'));
316         $grade_raw = new stdClass();
317         $grade_raw->rawgrade = 40;
318         $grade_raw->grademax = 100;
319         $grade_raw->grademin = 0;
321         $grade_item->gradetype = GRADE_TYPE_VALUE;
322         $grade_item->multfactor = 1;
323         $grade_item->plusfactor = 0;
324         $grade_item->grademax = 50;
325         $grade_item->grademin = 0;
327         $original_grade_raw  = clone($grade_raw);
328         $original_grade_item = clone($grade_item);
330         $this->assertEquals(20, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
332         // Try a larger maximum grade
333         $grade_item->grademax = 150;
334         $grade_item->grademin = 0;
335         $this->assertEquals(60, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
337         // Try larger minimum grade
338         $grade_item->grademin = 50;
340         $this->assertEquals(90, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
342         // Rescaling from a small scale (0-50) to a larger scale (0-100)
343         $grade_raw->grademax = 50;
344         $grade_raw->grademin = 0;
345         $grade_item->grademax = 100;
346         $grade_item->grademin = 0;
348         $this->assertEquals(80, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
350         // Rescaling from a small scale (0-50) to a larger scale with offset (40-100)
351         $grade_item->grademax = 100;
352         $grade_item->grademin = 40;
354         $this->assertEquals(88, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
356         // Try multfactor and plusfactor
357         $grade_raw = clone($original_grade_raw);
358         $grade_item = clone($original_grade_item);
359         $grade_item->multfactor = 1.23;
360         $grade_item->plusfactor = 3;
362         $this->assertEquals(27.6, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
364         // Try multfactor below 0 and a negative plusfactor
365         $grade_raw = clone($original_grade_raw);
366         $grade_item = clone($original_grade_item);
367         $grade_item->multfactor = 0.23;
368         $grade_item->plusfactor = -3;
370         $this->assertEquals(round(1.6), round($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)));
371     }
373     // Test locking of grade items
374     protected function sub_test_grade_item_set_locked() {
375         //getting a grade_item from the DB as set_locked() will fail if the grade items needs to be updated
376         //also needs to have at least one grade_grade or $grade_item->get_final(1) returns null
377         //$grade_item = new grade_item($this->grade_items[8]);
378         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[8]->id));
380         $this->assertTrue(method_exists($grade_item, 'set_locked'));
382         $grade_grade = new grade_grade($grade_item->get_final($this->user[1]->id), false);
383         $this->assertTrue(empty($grade_item->locked));//not locked
384         $this->assertTrue(empty($grade_grade->locked));//not locked
386         $this->assertTrue($grade_item->set_locked(true, true, false));
387         $grade_grade = new grade_grade($grade_item->get_final($this->user[1]->id), false);
389         $this->assertFalse(empty($grade_item->locked));//locked
390         $this->assertFalse(empty($grade_grade->locked)); // individual grades should be locked too
392         $this->assertTrue($grade_item->set_locked(false, true, false));
393         $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false);
395         $this->assertTrue(empty($grade_item->locked));
396         $this->assertTrue(empty($grade->locked)); // individual grades should be unlocked too
397     }
399     protected function sub_test_grade_item_is_locked() {
400         $grade_item = new grade_item($this->grade_items[10], false);
401         $this->assertTrue(method_exists($grade_item, 'is_locked'));
403         $this->assertFalse($grade_item->is_locked());
404         $this->assertFalse($grade_item->is_locked($this->user[1]->id));
405         $this->assertTrue($grade_item->set_locked(true, true, false));
406         $this->assertTrue($grade_item->is_locked());
407         $this->assertTrue($grade_item->is_locked($this->user[1]->id));
408     }
410     // Test hiding of grade items
411     protected function sub_test_grade_item_set_hidden() {
412         $grade_item = new grade_item($this->grade_items[0], false);
413         $this->assertTrue(method_exists($grade_item, 'set_hidden'));
415         $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false);
416         $this->assertEquals(0, $grade_item->hidden);
417         $this->assertEquals(0, $grade->hidden);
419         $grade_item->set_hidden(666, true);
420         $grade = new grade_grade($grade_item->get_final($this->user[1]->id), false);
422         $this->assertEquals(666, $grade_item->hidden);
423         $this->assertEquals(666, $grade->hidden);
424     }
426     protected function sub_test_grade_item_is_hidden() {
427         $grade_item = new grade_item($this->grade_items[0], false);
428         $this->assertTrue(method_exists($grade_item, 'is_hidden'));
430         $this->assertFalse($grade_item->is_hidden());
431         $this->assertFalse($grade_item->is_hidden(1));
433         $grade_item->set_hidden(1);
434         $this->assertTrue($grade_item->is_hidden());
435         $this->assertTrue($grade_item->is_hidden(1));
437         $grade_item->set_hidden(666);
438         $this->assertFalse($grade_item->is_hidden());
439         $this->assertFalse($grade_item->is_hidden(1));
441         $grade_item->set_hidden(time()+666);
442         $this->assertTrue($grade_item->is_hidden());
443         $this->assertTrue($grade_item->is_hidden(1));
444     }
446     protected function sub_test_grade_item_is_category_item() {
447         $grade_item = new grade_item($this->grade_items[3], false);
448         $this->assertTrue(method_exists($grade_item, 'is_category_item'));
449         $this->assertTrue($grade_item->is_category_item());
450     }
452     protected function sub_test_grade_item_is_course_item() {
453         $grade_item = grade_item::fetch_course_item($this->courseid);
454         $this->assertTrue(method_exists($grade_item, 'is_course_item'));
455         $this->assertTrue($grade_item->is_course_item());
456     }
458     protected function sub_test_grade_item_fetch_course_item() {
459         $grade_item = grade_item::fetch_course_item($this->courseid);
460         $this->assertTrue(method_exists($grade_item, 'fetch_course_item'));
461         $this->assertEquals($grade_item->itemtype, 'course');
462     }
464     protected function sub_test_grade_item_depends_on() {
465         $grade_item = new grade_item($this->grade_items[1], false);
467         // calculated grade dependency
468         $deps = $grade_item->depends_on();
469         sort($deps, SORT_NUMERIC); // for comparison
470         $this->assertEquals(array($this->grade_items[0]->id), $deps);
472         // simulate depends on returns none when locked
473         $grade_item->locked = time();
474         $grade_item->update();
475         $deps = $grade_item->depends_on();
476         sort($deps, SORT_NUMERIC); // for comparison
477         $this->assertEquals(array(), $deps);
479         // category dependency
480         $grade_item = new grade_item($this->grade_items[3], false);
481         $deps = $grade_item->depends_on();
482         sort($deps, SORT_NUMERIC); // for comparison
483         $res = array($this->grade_items[4]->id, $this->grade_items[5]->id);
484         $this->assertEquals($res, $deps);
485     }
487     protected function sub_test_refresh_grades() {
488         // Testing with the grade item for a mod_assignment instance.
489         $grade_item = new grade_item($this->grade_items[0], false);
490         $this->assertTrue(method_exists($grade_item, 'refresh_grades'));
491         $this->assertTrue($grade_item->refresh_grades());
493         // Break the grade item and check error handling.
494         $grade_item->iteminstance = 123456789;
495         $this->assertFalse($grade_item->refresh_grades());
496         $this->assertDebuggingCalled();
497     }
499     protected function sub_test_grade_item_is_calculated() {
500         $grade_item = new grade_item($this->grade_items[1], false);
501         $this->assertTrue(method_exists($grade_item, 'is_calculated'));
502         $this->assertTrue($grade_item->is_calculated());
504         $grade_item = new grade_item($this->grade_items[0], false);
505         $this->assertFalse($grade_item->is_calculated());
506     }
508     protected function sub_test_grade_item_set_calculation() {
509         $grade_item = new grade_item($this->grade_items[1], false);
510         $this->assertTrue(method_exists($grade_item, 'set_calculation'));
511         $grade_itemsource = new grade_item($this->grade_items[0], false);
513         $grade_item->set_calculation('=[['.$grade_itemsource->idnumber.']]');
515         $this->assertTrue(!empty($grade_item->needsupdate));
516         $this->assertEquals('=##gi'.$grade_itemsource->id.'##', $grade_item->calculation);
517     }
519     protected function sub_test_grade_item_get_calculation() {
520         $grade_item = new grade_item($this->grade_items[1], false);
521         $this->assertTrue(method_exists($grade_item, 'get_calculation'));
522         $grade_itemsource = new grade_item($this->grade_items[0], false);
524         $denormalizedformula = str_replace('##gi'.$grade_itemsource->id.'##', '[['.$grade_itemsource->idnumber.']]', $this->grade_items[1]->calculation);
526         $formula = $grade_item->get_calculation();
527         $this->assertTrue(!empty($grade_item->needsupdate));
528         $this->assertEquals($denormalizedformula, $formula);
529     }
531     public function sub_test_grade_item_compute() {
532         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[1]->id));
533         $this->assertTrue(method_exists($grade_item, 'compute'));
535         //check the grade_grades in the array match those in the DB then delete $this->grade_items[1]'s grade_grades
536         $this->grade_grades[3] = grade_grade::fetch(array('id'=>$this->grade_grades[3]->id));
537         $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[3]->id));
538         $grade_grade->delete();
540         $this->grade_grades[4] = grade_grade::fetch(array('id'=>$this->grade_grades[4]->id));
541         $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[4]->id));
542         $grade_grade->delete();
544         $this->grade_grades[5] = grade_grade::fetch(array('id'=>$this->grade_grades[5]->id));
545         $grade_grade = grade_grade::fetch(array('id'=>$this->grade_grades[5]->id));
546         $grade_grade->delete();
548         //recalculate the grades (its a calculation so pulls values from other grade_items) and reinsert them
549         $grade_item->compute();
551         $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[3]->userid, 'itemid'=>$this->grade_grades[3]->itemid));
552         $this->assertEquals($this->grade_grades[3]->finalgrade, $grade_grade->finalgrade);
554         $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[4]->userid, 'itemid'=>$this->grade_grades[4]->itemid));
555         $this->assertEquals($this->grade_grades[4]->finalgrade, $grade_grade->finalgrade);
557         $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[5]->userid, 'itemid'=>$this->grade_grades[5]->itemid));
558         $this->assertEquals($this->grade_grades[5]->finalgrade, $grade_grade->finalgrade);
559     }