MDL-75156 gradebook: Functions to calculate grade averages.

Also include unit tests.
This commit is contained in:
Ilya Tregubov 2022-08-18 12:16:45 +04:00
parent 24f97edd91
commit c8d950bde7
2 changed files with 719 additions and 0 deletions

View File

@ -577,5 +577,183 @@ abstract class grade_report {
$result = $this->blank_hidden_total_and_adjust_bounds($courseid, $course_item, $finalgrade);
return $result['grade'];
}
/**
* Calculate average grade for a given grade item.
* Based on calculate_averages function from grade/report/user/lib.php
*
* @param grade_item $gradeitem Grade item
* @param array $info Ungraded grade items counts and report preferences.
* @return array Average grade and meancount.
*/
public static function calculate_average(grade_item $gradeitem, array $info): array {
$meanselection = $info['report']['meanselection'];
$totalcount = $info['report']['totalcount'];
$ungradedcounts = $info['ungradedcounts'];
$sumarray = $info['sumarray'];
if (empty($sumarray[$gradeitem->id])) {
$sumarray[$gradeitem->id] = 0;
}
if (empty($ungradedcounts[$gradeitem->id])) {
$ungradedcounts = 0;
} else {
$ungradedcounts = $ungradedcounts[$gradeitem->id]->count;
}
// If they want the averages to include all grade items.
if ($meanselection == GRADE_REPORT_MEAN_GRADED) {
$meancount = $totalcount - $ungradedcounts;
} else {
// Bump up the sum by the number of ungraded items * grademin.
$sumarray[$gradeitem->id] += ($ungradedcounts * $gradeitem->grademin);
$meancount = $totalcount;
}
$aggr['meancount'] = $meancount;
if (empty($sumarray[$gradeitem->id]) || $meancount == 0) {
$aggr['average'] = null;
} else {
$sum = $sumarray[$gradeitem->id];
$aggr['average'] = $sum / $meancount;
}
return $aggr;
}
/**
* Get ungraded grade items info and sum of all grade items in a course.
* Based on calculate_averages function from grade/report/user/lib.php
*
* @return array Ungraded grade items counts with report preferences.
*/
public function ungraded_counts(): array {
global $DB;
$groupid = null;
if (isset($this->gpr->groupid)) {
$groupid = $this->gpr->groupid;
}
$info = [];
$info['report'] = [
'averagesdisplaytype' => $this->get_pref('averagesdisplaytype'),
'averagesdecimalpoints' => $this->get_pref('averagesdecimalpoints'),
'meanselection' => $this->get_pref('meanselection'),
'shownumberofgrades' => $this->get_pref('shownumberofgrades'),
'totalcount' => $this->get_numusers(!is_null($groupid)),
];
// We want to query both the current context and parent contexts.
list($relatedctxsql, $relatedctxparams) =
$DB->get_in_or_equal($this->context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx');
// Limit to users with a gradeable role ie students.
list($gradebookrolessql, $gradebookrolesparams) =
$DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
// Limit to users with an active enrolment.
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
$showonlyactiveenrol = $showonlyactiveenrol ||
!has_capability('moodle/course:viewsuspendedusers', $this->context);
list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context, '', 0, $showonlyactiveenrol);
$params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams, $relatedctxparams);
$params['courseid'] = $this->courseid;
// Aggregate on whole course only.
if (empty($groupid)) {
$this->groupsql = null;
$this->groupwheresql = null;
}
// Empty grades must be evaluated as grademin, NOT always 0.
// This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table).
// No join condition when joining grade_items and user to get a grade item row for every user.
// Then left join with grade_grades and look for rows with null final grade
// (which includes grade items with no grade_grade).
$sql = "SELECT gi.id, COUNT(u.id) AS count
FROM {grade_items} gi
JOIN {user} u ON u.deleted = 0
JOIN ($enrolledsql) je ON je.id = u.id
JOIN (
SELECT DISTINCT ra.userid
FROM {role_assignments} ra
WHERE ra.roleid $gradebookrolessql
AND ra.contextid $relatedctxsql
) rainner ON rainner.userid = u.id
LEFT JOIN {grade_grades} gg
ON (gg.itemid = gi.id AND gg.userid = u.id AND gg.finalgrade IS NOT NULL AND gg.hidden = 0)
$this->groupsql
WHERE gi.courseid = :courseid
AND gg.finalgrade IS NULL
$this->groupwheresql
GROUP BY gi.id";
$info['ungradedcounts'] = $DB->get_records_sql($sql, $params);
// Find sums of all grade items in course.
$sql = "SELECT gg.itemid, SUM(gg.finalgrade) AS sum
FROM {grade_items} gi
JOIN {grade_grades} gg ON gg.itemid = gi.id
JOIN {user} u ON u.id = gg.userid
JOIN ($enrolledsql) je ON je.id = gg.userid
JOIN (
SELECT DISTINCT ra.userid
FROM {role_assignments} ra
WHERE ra.roleid $gradebookrolessql
AND ra.contextid $relatedctxsql
) rainner ON rainner.userid = u.id
$this->groupsql
WHERE gi.courseid = :courseid
AND u.deleted = 0
AND gg.finalgrade IS NOT NULL
AND gg.hidden = 0
$this->groupwheresql
GROUP BY gg.itemid";
$sumarray = [];
$sums = $DB->get_recordset_sql($sql, $params);
foreach ($sums as $itemid => $csum) {
$sumarray[$itemid] = $csum->sum;
}
$sums->close();
$info['sumarray'] = $sumarray;
return $info;
}
/**
* Get grade item type names in a course to use in filter dropdown.
*
* @return array Item types.
*/
public function item_types(): array {
global $DB, $CFG;
$modnames = [];
$sql = "(SELECT gi.itemmodule
FROM {grade_items} gi
WHERE gi.courseid = :courseid1
AND gi.itemmodule IS NOT NULL)
UNION
(SELECT gi1.itemtype
FROM {grade_items} gi1
WHERE gi1.courseid = :courseid2
AND gi1.itemtype = 'manual')";
$itemtypes = $DB->get_records_sql($sql, ['courseid1' => $this->courseid, 'courseid2' => $this->courseid]);
foreach ($itemtypes as $itemtype => $value) {
if (file_exists("$CFG->dirroot/mod/$itemtype/lib.php")) {
$modnames[$itemtype] = get_string("modulename", $itemtype, null, true);
} else if ($itemtype == 'manual') {
$modnames[$itemtype] = get_string('manualitem', 'grades', null, true);
}
}
return $modnames;
}
}

View File

@ -24,6 +24,12 @@
*/
namespace core_grades;
use assign;
use cm_info;
use grade_item;
use grade_plugin_return;
use grade_report_summary;
defined('MOODLE_INTERNAL') || die();
global $CFG;
@ -170,4 +176,539 @@ class lib_test extends \advanced_testcase {
}
}
}
/**
* Tests that ungraded_counts calculates count and sum of grades correctly when there are graded users.
*
* @covers \grade_report::ungraded_counts
*/
public function test_ungraded_counts_count_sumgrades() {
global $DB;
$this->resetAfterTest(true);
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
$teacherrole = $DB->get_record('role', ['shortname' => 'editingteacher'], '*', MUST_EXIST);
// Custom roles (gradable and non gradable).
$gradeblerole = create_role('New student role', 'gradable',
'Gradable role', 'student');
$nongradeblerole = create_role('New student role', 'nongradable',
'Non gradable role', 'student');
// Set up gradable roles.
set_config('gradebookroles', $studentrole->id . ',' . $gradeblerole);
// Create users.
// These will be gradable users.
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
$student5 = $this->getDataGenerator()->create_user(['username' => 'student5']);
// These will be non-gradable users.
$student4 = $this->getDataGenerator()->create_user(['username' => 'student4']);
$student6 = $this->getDataGenerator()->create_user(['username' => 'student6']);
$teacher = $this->getDataGenerator()->create_user(['username' => 'teacher']);
// Enrol students.
$this->getDataGenerator()->enrol_user($student1->id, $course1->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student2->id, $course1->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student3->id, $course1->id, $gradeblerole);
$this->getDataGenerator()->enrol_user($student5->id, $course1->id, $nongradeblerole);
$this->getDataGenerator()->enrol_user($student6->id, $course1->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($teacher->id, $course1->id, $teacherrole->id);
// User that is enrolled in a different course.
$this->getDataGenerator()->enrol_user($student4->id, $course2->id, $studentrole->id);
// Mark user as deleted.
$student6->deleted = 1;
$DB->update_record('user', $student6);
// Create grade items in course 1.
$assign1 = $this->getDataGenerator()->create_module('assign', ['course' => $course1->id]);
$assign2 = $this->getDataGenerator()->create_module('assign', ['course' => $course1->id]);
$quiz1 = $this->getDataGenerator()->create_module('quiz', ['course' => $course1->id]);
$manuaitem = new \grade_item($this->getDataGenerator()->create_grade_item([
'itemname' => 'Grade item1',
'idnumber' => 'git1',
'courseid' => $course1->id,
]));
// Create grade items in course 2.
$assign3 = $this->getDataGenerator()->create_module('assign', ['course' => $course2->id]);
// Grade users in first course.
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign1->id));
$assigninstance = new assign($cm->context, $cm, $course1);
$grade = $assigninstance->get_user_grade($student1->id, true);
$grade->grade = 40;
$assigninstance->update_grade($grade);
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign2->id));
$assigninstance = new assign($cm->context, $cm, $course1);
$grade = $assigninstance->get_user_grade($student3->id, true);
$grade->grade = 50;
$assigninstance->update_grade($grade);
// Override grade for assignment in gradebook.
$gi = \grade_item::fetch([
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $cm->instance,
'courseid' => $course1->id
]);
$gi->update_final_grade($student3->id, 55);
// Grade user in second course.
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign3->id));
$assigninstance = new assign($cm->context, $cm, $course2);
$grade = $assigninstance->get_user_grade($student4->id, true);
$grade->grade = 40;
$assigninstance->update_grade($grade);
$manuaitem->update_final_grade($student1->id, 1);
$manuaitem->update_final_grade($student3->id, 2);
// Trigger a regrade.
grade_force_full_regrading($course1->id);
grade_force_full_regrading($course2->id);
grade_regrade_final_grades($course1->id);
grade_regrade_final_grades($course2->id);
// Initialise reports.
$context1 = \context_course::instance($course1->id);
$context2 = \context_course::instance($course2->id);
$gpr1 = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course1,
]
);
$gpr2 = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course2,
]
);
$report1 = new grade_report_summary($course1->id, $gpr1, $context1);
$report2 = new grade_report_summary($course2->id, $gpr2, $context2);
$ungradedcounts = [];
$ungradedcounts[$course1->id] = $report1->ungraded_counts();
$ungradedcounts[$course2->id] = $report2->ungraded_counts();
foreach ($ungradedcounts as $key => $ungradedcount) {
$gradeitems = grade_item::fetch_all(['courseid' => $key]);
if ($key == $course1->id) {
$gradeitemkeys = array_keys($gradeitems);
$ungradedcountskeys = array_keys($ungradedcount['ungradedcounts']);
// For each grade item there is some student that is not graded yet in course 1.
$this->assertEmpty(array_diff_key($gradeitemkeys, $ungradedcountskeys));
// Only quiz does not have any grades, the remaning 4 grade items should have some.
// We can do more and match by gradeitem id numbers. But feels like overengeneering.
$this->assertEquals(4, count($ungradedcount['sumarray']));
} else {
// In course 2 there is one student, and he is graded.
$this->assertEmpty($ungradedcount['ungradedcounts']);
// There are 2 grade items and they both have some grades.
$this->assertEquals(2, count($ungradedcount['sumarray']));
}
foreach ($gradeitems as $gradeitem) {
$sumgrades = null;
if (array_key_exists($gradeitem->id, $ungradedcount['ungradedcounts'])) {
$ungradeditem = $ungradedcount['ungradedcounts'][$gradeitem->id];
if ($gradeitem->itemtype === 'course') {
$this->assertEquals(1, $ungradeditem->count);
} else if ($gradeitem->itemmodule === 'assign') {
$this->assertEquals(2, $ungradeditem->count);
} else if ($gradeitem->itemmodule === 'quiz') {
$this->assertEquals(3, $ungradeditem->count);
} else if ($gradeitem->itemtype === 'manual') {
$this->assertEquals(1, $ungradeditem->count);
}
}
if (array_key_exists($gradeitem->id, $ungradedcount['sumarray'])) {
$sumgrades = $ungradedcount['sumarray'][$gradeitem->id];
if ($gradeitem->itemtype === 'course') {
if ($key == $course1->id) {
$this->assertEquals('98.00000', $sumgrades); // 40 + 55 + 1 + 2
} else {
$this->assertEquals('40.00000', $sumgrades);
}
} else if ($gradeitem->itemmodule === 'assign') {
if (($gradeitem->itemname === $assign1->name) || ($gradeitem->itemname === $assign3->name)) {
$this->assertEquals('40.00000', $sumgrades);
} else {
$this->assertEquals('55.00000', $sumgrades);
}
} else if ($gradeitem->itemtype === 'manual') {
$this->assertEquals('3.00000', $sumgrades);
}
}
}
}
}
/**
* Tests that ungraded_counts calculates count and sum of grades correctly for groups when there are graded users.
*
* @covers \grade_report::ungraded_counts
*/
public function test_ungraded_count_sumgrades_groups() {
global $DB;
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
// Create users.
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
// Enrol students.
$this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id);
$group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
$group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
$this->getDataGenerator()->create_group_member(['userid' => $student1->id, 'groupid' => $group1->id]);
$this->getDataGenerator()->create_group_member(['userid' => $student2->id, 'groupid' => $group2->id]);
$this->getDataGenerator()->create_group_member(['userid' => $student3->id, 'groupid' => $group2->id]);
$DB->set_field('course', 'groupmode', SEPARATEGROUPS, ['id' => $course->id]);
// Create grade items in course 1.
$assign1 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$assign2 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$quiz1 = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]);
$manuaitem = new \grade_item($this->getDataGenerator()->create_grade_item([
'itemname' => 'Grade item1',
'idnumber' => 'git1',
'courseid' => $course->id,
]));
// Grade users in first course.
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign1->id));
$assigninstance = new assign($cm->context, $cm, $course);
$grade = $assigninstance->get_user_grade($student1->id, true);
$grade->grade = 40;
$assigninstance->update_grade($grade);
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign2->id));
$assigninstance = new assign($cm->context, $cm, $course);
$grade = $assigninstance->get_user_grade($student3->id, true);
$grade->grade = 50;
$assigninstance->update_grade($grade);
$manuaitem->update_final_grade($student1->id, 1);
$manuaitem->update_final_grade($student3->id, 2);
// Trigger a regrade.
grade_force_full_regrading($course->id);
grade_regrade_final_grades($course->id);
// Initialise report.
$context = \context_course::instance($course->id);
$gpr1 = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course,
'groupid' => $group1->id,
]
);
$gpr2 = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course,
'groupid' => $group2->id,
]
);
$report1 = new grade_report_summary($course->id, $gpr1, $context);
$report2 = new grade_report_summary($course->id, $gpr2, $context);
$ungradedcounts = [];
$ungradedcounts[$group1->id] = $report1->ungraded_counts();
$ungradedcounts[$group2->id] = $report2->ungraded_counts();
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
// In group1 there is 1 student and assign1 and quiz1 are not graded for him.
$this->assertEquals(2, count($ungradedcounts[$group1->id]['ungradedcounts']));
// In group1 manual grade item, assign1 and course total have some grades.
$this->assertEquals(3, count($ungradedcounts[$group1->id]['sumarray']));
// In group2 student2 has no grades at all so all 5 grade items should present.
$this->assertEquals(5, count($ungradedcounts[$group2->id]['ungradedcounts']));
// In group2 manual grade item, assign2 and course total have some grades.
$this->assertEquals(3, count($ungradedcounts[$group2->id]['sumarray']));
foreach ($gradeitems as $gradeitem) {
$sumgrades = null;
foreach ($ungradedcounts as $key => $ungradedcount) {
if (array_key_exists($gradeitem->id, $ungradedcount['ungradedcounts'])) {
$ungradeditem = $ungradedcount['ungradedcounts'][$gradeitem->id];
if ($key == $group1->id) {
// Both assign2 and quiz1 are not graded for student1.
$this->assertEquals(1, $ungradeditem->count);
} else {
if ($gradeitem->itemtype === 'course') {
$this->assertEquals(1, $ungradeditem->count);
} else if ($gradeitem->itemmodule === 'assign') {
if ($gradeitem->itemname === $assign1->name) {
// In group2 assign1 is not graded for anyone.
$this->assertEquals(2, $ungradeditem->count);
} else {
// In group2 assign2 is graded for student3.
$this->assertEquals(1, $ungradeditem->count);
}
} else if ($gradeitem->itemmodule === 'quiz') {
$this->assertEquals(2, $ungradeditem->count);
} else if ($gradeitem->itemtype === 'manual') {
$this->assertEquals(1, $ungradeditem->count);
}
}
}
if (array_key_exists($gradeitem->id, $ungradedcount['sumarray'])) {
$sumgrades = $ungradedcount['sumarray'][$gradeitem->id];
if ($key == $group1->id) {
if ($gradeitem->itemtype === 'course') {
$this->assertEquals('41.00000', $sumgrades);
} else if ($gradeitem->itemmodule === 'assign') {
$this->assertEquals('40.00000', $sumgrades);
} else if ($gradeitem->itemtype === 'manual') {
$this->assertEquals('1.00000', $sumgrades);
}
} else {
if ($gradeitem->itemtype === 'course') {
$this->assertEquals('52.00000', $sumgrades);
} else if ($gradeitem->itemmodule === 'assign') {
$this->assertEquals('50.00000', $sumgrades);
} else if ($gradeitem->itemtype === 'manual') {
$this->assertEquals('2.00000', $sumgrades);
}
}
}
}
}
}
/**
* Tests for calculate_average.
* @dataProvider calculate_average_data()
* @param int $meanselection Whether to inlcude all grades or non-empty grades in aggregation.
* @param array $expectedmeancount expected meancount value
* @param array $expectedaverage expceted average value
*
* @covers \grade_report::calculate_average
*/
public function test_calculate_average(int $meanselection, array $expectedmeancount, array $expectedaverage) {
global $DB;
$this->resetAfterTest(true);
$course = $this->getDataGenerator()->create_course();
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
// Enrol students.
$this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
$this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id);
// Create activities.
$assign1 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$assign2 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
$quiz1 = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]);
// Grade users.
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign1->id));
$assigninstance = new assign($cm->context, $cm, $course);
$grade = $assigninstance->get_user_grade($student1->id, true);
$grade->grade = 40;
$assigninstance->update_grade($grade);
$grade = $assigninstance->get_user_grade($student2->id, true);
$grade->grade = 30;
$assigninstance->update_grade($grade);
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign2->id));
$assigninstance = new assign($cm->context, $cm, $course);
$grade = $assigninstance->get_user_grade($student3->id, true);
$grade->grade = 50;
$assigninstance->update_grade($grade);
$grade = $assigninstance->get_user_grade($student1->id, true);
$grade->grade = 100;
$assigninstance->update_grade($grade);
// Make a manual grade items.
$manuaitem = new \grade_item($this->getDataGenerator()->create_grade_item([
'itemname' => 'Grade item1',
'idnumber' => 'git1',
'courseid' => $course->id,
]));
$manuaitem->update_final_grade($student1->id, 1);
$manuaitem->update_final_grade($student3->id, 2);
// Initialise report.
$context = \context_course::instance($course->id);
$gpr = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course,
]
);
$report = new grade_report_summary($course->id, $gpr, $context);
$ungradedcounts = $report->ungraded_counts();
$ungradedcounts['report']['meanselection'] = $meanselection;
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
foreach ($gradeitems as $gradeitem) {
$name = $gradeitem->itemname . ' ' . $gradeitem->itemtype;
$aggr = $report->calculate_average($gradeitem, $ungradedcounts);
$this->assertEquals($expectedmeancount[$name], $aggr['meancount']);
$this->assertEquals($expectedaverage[$name], $aggr['average']);
}
}
/**
* Data provider for test_calculate_average
*
* @return array of testing scenarios
*/
public function calculate_average_data() : array {
return [
'Non-empty grades' => [
'meanselection' => 1,
'expectedmeancount' => [' course' => 3, 'Assignment 1 mod' => 2, 'Assignment 2 mod' => 2,
'Quiz 1 mod' => 0, 'Grade item1 manual' => 2],
'expectedaverage' => [' course' => 73.33333333333333, 'Assignment 1 mod' => 35.0,
'Assignment 2 mod' => 75.0, 'Quiz 1 mod' => null, 'Grade item1 manual' => 1.5],
],
'All grades' => [
'meanselection' => 0,
'expectedmeancount' => [' course' => 3, 'Assignment 1 mod' => 3, 'Assignment 2 mod' => 3,
'Quiz 1 mod' => 3, 'Grade item1 manual' => 3],
'expectedaverage' => [' course' => 73.33333333333333, 'Assignment 1 mod' => 23.333333333333332,
'Assignment 2 mod' => 50.0, 'Quiz 1 mod' => null, 'Grade item1 manual' => 1.0],
],
];
}
/**
* Tests for item types.
*
* @covers \grade_report::item_types
*/
public function test_item_types() {
$this->resetAfterTest(true);
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
// Create activities.
$this->getDataGenerator()->create_module('assign', ['course' => $course1->id]);
$this->getDataGenerator()->create_module('assign', ['course' => $course1->id]);
$this->getDataGenerator()->create_module('quiz', ['course' => $course1->id]);
$this->getDataGenerator()->create_module('assign', ['course' => $course2->id]);
// Create manual grade items.
new \grade_item($this->getDataGenerator()->create_grade_item([
'itemname' => 'Grade item1',
'idnumber' => 'git1',
'courseid' => $course1->id,
]));
new \grade_item($this->getDataGenerator()->create_grade_item([
'itemname' => 'Grade item2',
'idnumber' => 'git2',
'courseid' => $course2->id,
]));
// Create a grade category (it should not be fetched by item_types).
new \grade_category($this->getDataGenerator()
->create_grade_category(['courseid' => $course1->id]), false);
// Initialise reports.
$context = \context_course::instance($course1->id);
$gpr = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course1,
]
);
$report1 = new grade_report_summary($course1->id, $gpr, $context);
$context = \context_course::instance($course2->id);
$gpr = new grade_plugin_return(
[
'type' => 'report',
'plugin' => 'summary',
'course' => $course2,
]
);
$report2 = new grade_report_summary($course2->id, $gpr, $context);
$gradeitems1 = $report1->item_types();
$gradeitems2 = $report2->item_types();
$this->assertEquals(3, count($gradeitems1));
$this->assertEquals(2, count($gradeitems2));
$this->assertArrayHasKey('assign', $gradeitems1);
$this->assertArrayHasKey('quiz', $gradeitems1);
$this->assertArrayHasKey('manual', $gradeitems1);
$this->assertArrayHasKey('assign', $gradeitems2);
$this->assertArrayHasKey('manual', $gradeitems2);
}
}