diff --git a/lib/completionlib.php b/lib/completionlib.php index 9154d28ad61..66d6556b1ec 100644 --- a/lib/completionlib.php +++ b/lib/completionlib.php @@ -769,9 +769,6 @@ class completion_info { item '{$item->id}', user '{$userid}'"); } return self::internal_get_grade_state($item, reset($grades)); - } else { - $this->internal_systemerror("Cannot find grade item for '{$cm->modname}' - cm '{$cm->id}' matching number '{$cm->completiongradeitemnumber}'"); } return COMPLETION_INCOMPLETE; diff --git a/lib/tests/completionlib_test.php b/lib/tests/completionlib_test.php index aa7d567b75e..a629f7b037e 100644 --- a/lib/tests/completionlib_test.php +++ b/lib/tests/completionlib_test.php @@ -1266,7 +1266,7 @@ class core_completionlib_testcase extends advanced_testcase { */ public function get_grade_completion_provider() { return [ - 'Grade not required' => [false, false, null, moodle_exception::class, null], + 'Grade not required' => [false, false, null, null, null], 'Grade required, but has no grade yet' => [true, false, null, null, COMPLETION_INCOMPLETE], 'Grade required, grade received' => [true, true, null, null, COMPLETION_COMPLETE], 'Grade required, passing grade received' => [true, true, 70, null, COMPLETION_COMPLETE_PASS], @@ -1312,6 +1312,44 @@ class core_completionlib_testcase extends advanced_testcase { $gradecompletion = $completioninfo->get_grade_completion($cm, $this->user->id); $this->assertEquals($expectedresult, $gradecompletion); } + + /** + * Test the return value for cases when the activity module does not have associated grade_item. + */ + public function test_get_grade_completion_without_grade_item() { + global $DB; + + $this->setup_data(); + + $assign = $this->getDataGenerator()->get_plugin_generator('mod_assign')->create_instance([ + 'course' => $this->course->id, + 'completion' => COMPLETION_ENABLED, + 'completionusegrade' => true, + 'gradepass' => 42, + ]); + + $cm = cm_info::create(get_coursemodule_from_instance('assign', $assign->id)); + + $DB->delete_records('grade_items', [ + 'courseid' => $this->course->id, + 'itemtype' => 'mod', + 'itemmodule' => 'assign', + 'iteminstance' => $assign->id, + ]); + + // Without the grade_item, the activity is considered incomplete. + $completioninfo = new completion_info($this->course); + $this->assertEquals(COMPLETION_INCOMPLETE, $completioninfo->get_grade_completion($cm, $this->user->id)); + + // Once the activity is graded, the grade_item is automatically created. + $assigninstance = new assign($cm->context, $cm, $this->course); + $grade = $assigninstance->get_user_grade($this->user->id, true); + $grade->grade = 40; + $assigninstance->update_grade($grade); + + // The implicitly created grade_item does not have grade to pass defined so it is not distinguished. + $this->assertEquals(COMPLETION_COMPLETE, $completioninfo->get_grade_completion($cm, $this->user->id)); + } } class core_completionlib_fake_recordset implements Iterator {