Skip to content

Commit

Permalink
MBS-8358: Fix passing grade
Browse files Browse the repository at this point in the history
  • Loading branch information
sh-csg committed Jan 25, 2024
1 parent 66205e4 commit 7a38f0d
Show file tree
Hide file tree
Showing 4 changed files with 316 additions and 127 deletions.
18 changes: 14 additions & 4 deletions classes/activitymanager.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,20 @@ public function __construct(stdClass $course, stdClass $user, int $group = 0) {
/**
* Checks whether a given course module is completed (either by the user or at least one
* of the users of the group, if group is set).
*
* Please be aware: If an activity has a passing grade set, the passing grade is only used
* to check completion when it is set as an completion requirement. Otherwise
* @param \cm_info $cm course module to check
*/
public function is_completed(cm_info $cm): bool {
foreach ($this->members as $member) {
$completionstate = $this->completion->get_data($cm, true, $member->id)->completionstate;
if (
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE ||
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE_PASS
$completionstate == COMPLETION_COMPLETE ||
$completionstate == COMPLETION_COMPLETE_PASS ||
(
intval($cm->completionpassgrade) == 0 &&
$completionstate == COMPLETION_COMPLETE_FAIL
)
) {
return true;
}
Expand Down Expand Up @@ -114,7 +120,11 @@ public function get_completion_order(array $cms): array {
foreach ($this->members as $member) {
if (
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE ||
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE_PASS
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE_PASS ||
(
intval($cm->completionpassgrade) == 0 &&
$this->completion->get_data($cm, true, $member->id)->completionstate == COMPLETION_COMPLETE_FAIL
)
) {
$completed = $this->completion->get_data($cm, true, $member->id)->timemodified;
if (!isset($completiontime[$cm->id]) || $completed < $completiontime[$cm->id]) {
Expand Down
104 changes: 104 additions & 0 deletions tests/mod_learningmap_activitymanager_test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.

namespace mod_learningmap;

use course_modinfo;

defined('MOODLE_INTERNAL') || die();

global $CFG;
require_once($CFG->dirroot . '/mod/learningmap/tests/mod_learningmap_testcase.php');

/**
* Unit test for mod_learningmap
*
* @package mod_learningmap
* @copyright 2021-2023, ISB Bayern
* @author Stefan Hanauska <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @group mod_learningmap
* @group mebis
* @covers \mod_learningmap\activitymanager
*/
class mod_learningmap_activitymanager_test extends mod_learningmap_testcase {
/**
* Activitymanager instance for testing.
* @var activitymanager $activitymanager
*/
protected $activitymanager;

/**
* Test completion checking
* @return void
*/
public function test_is_completed(): void {
$this->resetAfterTest();
$this->setAdminUser();
$this->prepare(completion\custom_completion::COMPLETION_WITH_ONE_TARGET, true, true);
$this->activitymanager = new activitymanager($this->course, $this->users[0]);
$cm = $this->modinfo->get_cm($this->activities[0]->cmid);
$this->completion->set_module_viewed($cm, $this->users[0]->id);
// The module requires only viewing it. Should be complete now.
$this->assertEquals($this->activitymanager->is_completed($cm), true);

$assign = $this->activities[7];
$grades = [];
$grades[$this->users[0]->id] = (object)[
'rawgrade' => 90, 'userid' => $this->users[0]->id,
];
$assign->cmidnumber = null;
assign_grade_item_update($assign, $grades);
$cm = $this->modinfo->get_cm($this->activities[7]->cmid);
// The module requires only viewing it. Should be incomplete after grading, as it is not viewed yet.
$this->assertEquals($this->activitymanager->is_completed($cm), false);
$this->completion->set_module_viewed($cm, $this->users[0]->id);
// Should be complete after viewing it.
$this->assertEquals($this->activitymanager->is_completed($cm), true);

$assign = $this->activities[8];
$grades = [];
$grades[$this->users[0]->id] = (object)[
'rawgrade' => 1, 'userid' => $this->users[0]->id,
];
$assign->cmidnumber = $assign->cmid;
assign_grade_item_update($assign, $grades);
$cm = $this->modinfo->get_cm($this->activities[8]->cmid);
// The module requires viewing it and a passing grade. Should be incomplete after grading, as it is not viewed yet
// and it the grade is below the passing grade.
$this->assertEquals($this->activitymanager->is_completed($cm), false);
$this->completion->set_module_viewed($cm, $this->users[0]->id);
// Should still be incomplete, as passing grade is not reached.
$this->assertEquals($this->activitymanager->is_completed($cm), false);
$grades[$this->users[0]->id] = (object)[
'rawgrade' => 90, 'userid' => $this->users[0]->id,
];
$result = assign_grade_item_update($assign, $grades);
$this->assertEquals(0, $result);
// Should be complete as passing grade is reached now.
$this->assertEquals($this->activitymanager->is_completed($cm), true);

$this->activitymanager = new activitymanager($this->course, $this->users[1], $this->group->id);
$cm = $this->modinfo->get_cm($this->activities[0]->cmid);
$this->assertEquals($this->activitymanager->is_completed($cm), true);
$cm = $this->modinfo->get_cm($this->activities[1]->cmid);
$this->assertEquals($this->activitymanager->is_completed($cm), false);
$cm = $this->modinfo->get_cm($this->activities[7]->cmid);
$this->assertEquals($this->activitymanager->is_completed($cm), true);
$cm = $this->modinfo->get_cm($this->activities[8]->cmid);
$this->assertEquals($this->activitymanager->is_completed($cm), true);
}
}
129 changes: 6 additions & 123 deletions tests/mod_learningmap_completion_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
use mod_learningmap\completion\custom_completion;

defined('MOODLE_INTERNAL') || die();
require_once(__DIR__ . '/../lib.php');

global $CFG;

require_once($CFG->dirroot . '/mod/learningmap/lib.php');
require_once($CFG->dirroot . '/mod/learningmap/tests/mod_learningmap_testcase.php');

/**
* Unit test for mod_learningmap
Expand All @@ -31,128 +35,7 @@
* @group mebis
* @covers \mod_learningmap\completion\custom_completion
*/
class mod_learningmap_completion_test extends \advanced_testcase {
/**
* The course used for testing
*
* @var \stdClass
*/
protected $course;
/**
* The learning map used for testing
*
* @var \stdClass
*/
protected $learningmap;
/**
* The activities linked in the learningmap
*
* @var array
*/
protected $activities;
/**
* The users used for testing
*
* @var array
*/
protected $users;
/**
* The group used for testing
*
* @var \stdClass
*/
protected $group;
/**
* Whether group mode is active
*
* @var boolean
*/
protected $groupmode;
/**
* The modinfo of the course
*
* @var \course_modinfo|null
*/
protected $modinfo;
/**
* The completion info of the course
*
* @var \completion_info
*/
protected $completion;
/**
* The cm_info object belonging to the learning map (differs from the learningmap record)
*
* @var \cm_info
*/
protected $cm;
/**
* Prepare testing environment
*/
/**
* Prepare testing environment
* @param int $completiontype Type for automatic completion
* @param bool $groupmode Whether to use group mode (defaults to false)
*/
public function prepare($completiontype, $groupmode = false): void {
global $DB;
$this->groupmode = $groupmode;
$this->course = $this->getDataGenerator()->create_course(['enablecompletion' => 1]);
$this->learningmap = $this->getDataGenerator()->create_module(
'learningmap',
['course' => $this->course, 'completion' => 2, 'completiontype' => $completiontype,
'groupmode' => ($groupmode ? SEPARATEGROUPS : NOGROUPS), ]
);

$this->activities = [];
for ($i = 0; $i < 9; $i++) {
$this->activities[] = $this->getDataGenerator()->create_module(
'page',
['name' => 'A', 'content' => 'B', 'course' => $this->course, 'completion' => 2, 'completionview' => 1]
);
$this->learningmap->placestore = str_replace(99990 + $i, $this->activities[$i]->cmid, $this->learningmap->placestore);
}
$DB->set_field('learningmap', 'placestore', $this->learningmap->placestore, ['id' => $this->learningmap->id]);

$this->users[0] = $this->getDataGenerator()->create_user(
[
'email' => '[email protected]',
'username' => 'user1',
]
);
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
$this->getDataGenerator()->enrol_user($this->users[0]->id, $this->course->id, $studentrole->id);
if ($this->groupmode) {
$this->group = $this->getDataGenerator()->create_group(['courseid' => $this->course->id]);
$this->users[1] = $this->getDataGenerator()->create_user(
[
'email' => '[email protected]',
'username' => 'user2',
]
);
$this->users[2] = $this->getDataGenerator()->create_user(
[
'email' => '[email protected]',
'username' => 'user3',
]
);
$this->getDataGenerator()->enrol_user($this->users[1]->id, $this->course->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($this->users[2]->id, $this->course->id, $studentrole->id);
$this->getDataGenerator()->create_group_member([
'userid' => $this->users[0]->id,
'groupid' => $this->group->id,
]);
$this->getDataGenerator()->create_group_member([
'userid' => $this->users[1]->id,
'groupid' => $this->group->id,
]);
}

$this->modinfo = get_fast_modinfo($this->course, $this->users[0]->id);
$this->completion = new \completion_info($this->modinfo->get_course());
$this->cm = $this->modinfo->get_cm($this->learningmap->cmid);
}

class mod_learningmap_completion_test extends mod_learningmap_testcase {
/**
* Tests completiontype 1 in individual mode
*
Expand Down
Loading

0 comments on commit 7a38f0d

Please sign in to comment.