MDL-79726 completion: Overall should consider pass/fail states too

In MDL-78744, when the overallcompletion state was added to be displayed
in the activity card, only COMPLETE/INCOMPLETE status were considered.
However, depending on the activity completion settings, there are a
couple of states more that should also be included (COMPLETE_FAIL and
COMPLETE_PASS).

A new method has been added to the cm_completion_details class to
calculate whether a module should be considered or not completed,
based on their completion options and the current value for the
overall complete state.
This commit is contained in:
Sara Arjona
2023-12-01 09:18:36 +01:00
parent abba174fe1
commit 032f39aeef
5 changed files with 239 additions and 3 deletions
@@ -193,6 +193,32 @@ class cm_completion_details {
return (int)$this->completiondata->completionstate;
}
/**
* Returns whether the overall completion state of this course module should be marked as complete or not.
* This is based on the completion settings of the course module, so when the course module requires a passing grade,
* it will only be marked as complete when the user has passed the course module. Otherwise, it will be marked as complete
* even when the user has failed the course module.
*
* @return bool True when the module can be marked as completed.
*/
public function is_overall_complete(): bool {
$completionstates = [];
if ($this->is_manual()) {
$completionstates = [COMPLETION_COMPLETE];
} else if ($this->is_automatic()) {
// Successfull completion states depend on the completion settings.
if (isset($this->completiondata->passgrade)) {
// Passing grade is required. Don't mark it as complete when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS];
} else {
// Any grade is required. Mark it as complete even when state is COMPLETION_COMPLETE_FAIL.
$completionstates = [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS, COMPLETION_COMPLETE_FAIL];
}
}
return in_array($this->get_overall_completion(), $completionstates);
}
/**
* Whether this activity module has completion enabled.
*
@@ -223,6 +223,141 @@ class cm_completion_details_test extends advanced_testcase {
$this->assertEquals($state, $cmcompletion->get_overall_completion());
}
/**
* Data provider for test_is_overall_complete().
* @return array[]
*/
public static function is_overall_complete_provider(): array {
return [
'Automatic, require view, not viewed' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_INCOMPLETE,
'completionview' => COMPLETION_INCOMPLETE,
'completiongrade' => null,
'completionpassgrade' => null,
],
'Automatic, require view, viewed' => [
'expected' => true,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_COMPLETE,
'completionview' => COMPLETION_COMPLETE,
'completiongrade' => null,
'completionpassgrade' => null,
],
'Automatic, require grade, not graded' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_INCOMPLETE,
'completionview' => null,
'completiongrade' => COMPLETION_INCOMPLETE,
'completionpassgrade' => null,
],
'Automatic, require grade, graded with fail' => [
'expected' => true,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_COMPLETE_FAIL,
'completionview' => null,
'completiongrade' => COMPLETION_COMPLETE_FAIL,
'completionpassgrade' => null,
],
'Automatic, require grade, graded with passing' => [
'expected' => true,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_COMPLETE_PASS,
'completionview' => null,
'completiongrade' => COMPLETION_COMPLETE_PASS,
'completionpassgrade' => null,
],
'Automatic, require passgrade, not graded' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_INCOMPLETE,
'completionview' => null,
'completiongrade' => null,
'completionpassgrade' => COMPLETION_INCOMPLETE,
],
'Automatic, require passgrade, graded with fail' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_COMPLETE_FAIL,
'completionview' => null,
'completiongrade' => null,
'completionpassgrade' => COMPLETION_COMPLETE_FAIL,
],
'Automatic, require passgrade, graded with passing' => [
'expected' => true,
'completion' => COMPLETION_TRACKING_AUTOMATIC,
'completionstate' => COMPLETION_COMPLETE_PASS,
'completionview' => null,
'completiongrade' => null,
'completionpassgrade' => COMPLETION_COMPLETE_PASS,
],
'Manual, incomplete' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_MANUAL,
'completionstate' => COMPLETION_INCOMPLETE,
],
'Manual, complete' => [
'expected' => true,
'completion' => COMPLETION_TRACKING_MANUAL,
'completionstate' => COMPLETION_COMPLETE,
],
'None, incomplete' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_NONE,
'completionstate' => COMPLETION_INCOMPLETE,
],
'None, complete' => [
'expected' => false,
'completion' => COMPLETION_TRACKING_NONE,
'completionstate' => COMPLETION_COMPLETE,
],
];
}
/**
* Test for is_overall_complete().
*
* @covers ::is_overall_complete
* @dataProvider is_overall_complete_provider
* @param bool $expected Expected result returned by is_overall_complete().
* @param int $completion The completion tracking mode.
* @param int $completionstate The overall completion state.
* @param int|null $completionview Completion status of the "view" completion condition.
* @param int|null $completiongrade Completion status of the "must receive grade" completion condition.
* @param int|null $completionpassgrade Completion status of the "must receive passing grade" completion condition.
*/
public function test_is_overall_complete(
bool $expected,
int $completion,
int $completionstate,
?int $completionview = null,
?int $completiongrade = null,
?int $completionpassgrade = null,
): void {
$options = [];
$getdatareturn = (object)[
'completionstate' => $completionstate,
'viewed' => $completionview,
'completiongrade' => $completiongrade,
'passgrade' => $completionpassgrade,
];
if (!is_null($completionview)) {
$options['completionview'] = true;
}
if (!is_null($completiongrade)) {
$options['completionusegrade'] = true;
}
if (!is_null($completionpassgrade)) {
$options['completionpassgrade'] = true;
}
$cmcompletion = $this->setup_data($completion, $options, $getdatareturn);
$this->assertEquals($expected, $cmcompletion->is_overall_complete());
}
/**
* Data provider for test_get_details().
* @return array[]
+4
View File
@@ -1,6 +1,10 @@
This file describes API changes in /completion/* - completion,
information provided here is intended especially for developers.
=== 4.4 ===
* A new method, cm_completion_details::is_overall_complete() has been added to calculate whether a module should be considered or
not completed, based on their completion options and the current value for the overall complete state.
=== 4.3 ===
* A trait class, core_completion/form/form_trait has been added to reuse code for adding and validation completion settings to any
form.