MDL-57601 Grade report: Error for ungraded quiz without view hidden
authorsam marshall <s.marshall@open.ac.uk>
Mon, 9 Jan 2017 14:24:11 +0000 (14:24 +0000)
committersam marshall <s.marshall@open.ac.uk>
Mon, 9 Jan 2017 15:32:25 +0000 (15:32 +0000)
If a course contains an ungraded quiz (max grade set to 0), and there
is a user account which can view the grader reports but does not have
permission to view hidden grades, they will get errors.

grade/report/grader/lib.php
grade/tests/report_graderlib_test.php

index 2d9378b..d154df1 100644 (file)
@@ -919,6 +919,11 @@ class grade_report_grader extends grade_report {
         // user.
         if (!$this->canviewhidden) {
             $allgradeitems = grade_item::fetch_all(array('courseid' => $this->courseid));
+
+            // But hang on - don't include ones which are set to not show the grade at all.
+            $allgradeitems = array_filter($allgradeitems, function($item) {
+                return $item->gradetype != GRADE_TYPE_NONE;
+            });
         }
 
         foreach ($this->users as $userid => $user) {
index 8282265..d65e285 100644 (file)
@@ -230,6 +230,74 @@ class core_grade_report_graderlib_testcase extends advanced_testcase {
         $this->assertEquals(count($toobigvalue['gradesonly']) - 1, count($report1->collapsed['gradesonly']));
     }
 
+    /**
+     * Tests the get_right_rows function with one 'normal' and one 'ungraded' quiz.
+     *
+     * Previously, with an ungraded quiz (which results in a grade item with type GRADETYPE_NONE)
+     * there was a bug in get_right_rows in some situations.
+     */
+    public function test_get_right_rows() {
+        global $USER, $DB;
+        $this->resetAfterTest(true);
+
+        // Create manager and student on a course.
+        $generator = $this->getDataGenerator();
+        $manager = $generator->create_user();
+        $student = $generator->create_user();
+        $course = $generator->create_course();
+        $generator->enrol_user($manager->id, $course->id, 'manager');
+        $generator->enrol_user($student->id, $course->id, 'student');
+
+        // Create a couple of quizzes on the course.
+        $normalquiz = $generator->create_module('quiz', array('course' => $course->id,
+                'name' => 'NormalQuiz'));
+        $ungradedquiz = $generator->create_module('quiz', array('course' => $course->id,
+                'name' => 'UngradedQuiz'));
+
+        // Set the grade for the second one to 0 (note, you have to do this after creating it,
+        // otherwise it doesn't create an ungraded grade item).
+        $ungradedquiz->instance = $ungradedquiz->id;
+        quiz_set_grade(0, $ungradedquiz);
+
+        // Set current user.
+        $this->setUser($manager);
+        $USER->gradeediting[$course->id] = false;
+
+        // Get the report.
+        $report = $this->create_report($course);
+        $report->load_users();
+        $report->load_final_grades();
+        $result = $report->get_right_rows(false);
+
+        // There should be 3 rows (2 header rows, plus the grades for the first user).
+        $this->assertCount(3, $result);
+
+        // The second row should contain 2 cells - one for the graded quiz and course total.
+        $this->assertCount(2, $result[1]->cells);
+        $this->assertContains('NormalQuiz', $result[1]->cells[0]->text);
+        $this->assertContains('Course total', $result[1]->cells[1]->text);
+
+        // User row should contain grade values '-'.
+        $this->assertCount(2, $result[2]->cells);
+        $this->assertContains('>-<', $result[2]->cells[0]->text);
+        $this->assertContains('>-<', $result[2]->cells[1]->text);
+
+        // Supposing the user cannot view hidden grades, this shouldn't make any difference (due
+        // to a bug, it previously did).
+        $context = context_course::instance($course->id);
+        $managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager'));
+        assign_capability('moodle/grade:viewhidden', CAP_PROHIBIT, $managerroleid, $context->id, true);
+        $context->mark_dirty();
+        $this->assertFalse(has_capability('moodle/grade:viewhidden', $context));
+
+        // Recreate the report. Confirm it returns successfully still.
+        $report = $this->create_report($course);
+        $report->load_users();
+        $report->load_final_grades();
+        $result = $report->get_right_rows(false);
+        $this->assertCount(3, $result);
+    }
+
     private function create_grade_category($course) {
         static $cnt = 0;
         $cnt++;