mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-76588 core_grades: Refactor calculate_average for hidden grades case.
On grader report we include hidden grades in averages calculations. On user report we don't include hidden grades. So to allow using of calculate_averages it needs to be refactored for this case. We also have to add group id param to calculate_average since for grader report we calculate both overall average and group average
This commit is contained in:
parent
e4d1369475
commit
d47c36b28b
@ -763,7 +763,6 @@ abstract class grade_report {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate average grade for a given grade item.
|
* 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 grade_item $gradeitem Grade item
|
||||||
* @param array $info Ungraded grade items counts and report preferences.
|
* @param array $info Ungraded grade items counts and report preferences.
|
||||||
@ -807,16 +806,33 @@ abstract class grade_report {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ungraded grade items info and sum of all grade items in a course.
|
* To check if we only need to include active enrolments.
|
||||||
* Based on calculate_averages function from grade/report/user/lib.php
|
|
||||||
*
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function show_only_active(): bool {
|
||||||
|
global $CFG;
|
||||||
|
|
||||||
|
// Limit to users with an active enrolment.
|
||||||
|
$defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
|
||||||
|
$showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
|
||||||
|
return $showonlyactiveenrol ||
|
||||||
|
!has_capability('moodle/course:viewsuspendedusers', $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ungraded grade items info and sum of all grade items in a course.
|
||||||
|
*
|
||||||
|
* @param bool $grouponly If we want to compute group average only.
|
||||||
|
* @param bool $includehiddengrades Include hidden grades.
|
||||||
|
* @param bool $showonlyactiveenrol Whether to only include active enrolments.
|
||||||
* @return array Ungraded grade items counts with report preferences.
|
* @return array Ungraded grade items counts with report preferences.
|
||||||
*/
|
*/
|
||||||
public function ungraded_counts(): array {
|
public function ungraded_counts(bool $grouponly = false, bool $includehiddengrades = false, $showonlyactiveenrol = true): array {
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$groupid = null;
|
$groupid = null;
|
||||||
if (isset($this->gpr->groupid)) {
|
if ($grouponly && isset($this->gpr->groupid)) {
|
||||||
$groupid = $this->gpr->groupid;
|
$groupid = $this->gpr->groupid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,22 +853,22 @@ abstract class grade_report {
|
|||||||
list($gradebookrolessql, $gradebookrolesparams) =
|
list($gradebookrolessql, $gradebookrolesparams) =
|
||||||
$DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0');
|
$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);
|
list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context, '', 0, $showonlyactiveenrol);
|
||||||
|
|
||||||
$params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams, $relatedctxparams);
|
$params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams, $relatedctxparams);
|
||||||
$params['courseid'] = $this->courseid;
|
$params['courseid'] = $this->courseid;
|
||||||
|
|
||||||
// Aggregate on whole course only.
|
|
||||||
if (empty($groupid)) {
|
if (empty($groupid)) {
|
||||||
|
// Aggregate on whole course only.
|
||||||
$this->groupsql = null;
|
$this->groupsql = null;
|
||||||
$this->groupwheresql = null;
|
$this->groupwheresql = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$includesql = '';
|
||||||
|
if (!$includehiddengrades) {
|
||||||
|
$includesql = 'AND gg.hidden = 0';
|
||||||
|
}
|
||||||
|
|
||||||
// Empty grades must be evaluated as grademin, NOT always 0.
|
// 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).
|
// 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.
|
// No join condition when joining grade_items and user to get a grade item row for every user.
|
||||||
@ -869,7 +885,7 @@ abstract class grade_report {
|
|||||||
AND ra.contextid $relatedctxsql
|
AND ra.contextid $relatedctxsql
|
||||||
) rainner ON rainner.userid = u.id
|
) rainner ON rainner.userid = u.id
|
||||||
LEFT JOIN {grade_grades} gg
|
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)
|
ON (gg.itemid = gi.id AND gg.userid = u.id AND gg.finalgrade IS NOT NULL $includesql)
|
||||||
$this->groupsql
|
$this->groupsql
|
||||||
WHERE gi.courseid = :courseid
|
WHERE gi.courseid = :courseid
|
||||||
AND gg.finalgrade IS NULL
|
AND gg.finalgrade IS NULL
|
||||||
@ -893,7 +909,7 @@ abstract class grade_report {
|
|||||||
WHERE gi.courseid = :courseid
|
WHERE gi.courseid = :courseid
|
||||||
AND u.deleted = 0
|
AND u.deleted = 0
|
||||||
AND gg.finalgrade IS NOT NULL
|
AND gg.finalgrade IS NOT NULL
|
||||||
AND gg.hidden = 0
|
$includesql
|
||||||
$this->groupwheresql
|
$this->groupwheresql
|
||||||
GROUP BY gg.itemid";
|
GROUP BY gg.itemid";
|
||||||
|
|
||||||
@ -938,5 +954,69 @@ abstract class grade_report {
|
|||||||
|
|
||||||
return $modnames;
|
return $modnames;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a row of grade items averages
|
||||||
|
*
|
||||||
|
* @param array $ungradedcounts Ungraded grade items counts with report preferences.
|
||||||
|
* @return html_table_row Row with averages
|
||||||
|
*/
|
||||||
|
protected function format_averages(array $ungradedcounts): html_table_row {
|
||||||
|
|
||||||
|
$avgrow = new html_table_row();
|
||||||
|
$avgrow->attributes['class'] = 'avg';
|
||||||
|
|
||||||
|
$averagesdisplaytype = $ungradedcounts['report']['averagesdisplaytype'];
|
||||||
|
$averagesdecimalpoints = $ungradedcounts['report']['averagesdecimalpoints'];
|
||||||
|
$shownumberofgrades = $ungradedcounts['report']['shownumberofgrades'];
|
||||||
|
|
||||||
|
foreach ($this->gtree->items as $gradeitem) {
|
||||||
|
if ($gradeitem->needsupdate) {
|
||||||
|
$avgrow->cells[$gradeitem->id] = $this->format_average_cell($gradeitem);
|
||||||
|
} else {
|
||||||
|
$aggr = $this->calculate_average($gradeitem, $ungradedcounts);
|
||||||
|
|
||||||
|
if (empty($aggr['average'])) {
|
||||||
|
$avgrow->cells[$gradeitem->id] =
|
||||||
|
$this->format_average_cell($gradeitem, $aggr, $ungradedcounts['report']['shownumberofgrades']);
|
||||||
|
} else {
|
||||||
|
// Determine which display type to use for this average.
|
||||||
|
if (isset($USER->editing) && $USER->editing) {
|
||||||
|
$displaytype = GRADE_DISPLAY_TYPE_REAL;
|
||||||
|
} else if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) {
|
||||||
|
// No ==0 here, please resave the report and user preferences.
|
||||||
|
$displaytype = $gradeitem->get_displaytype();
|
||||||
|
} else {
|
||||||
|
$displaytype = $averagesdisplaytype;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override grade_item setting if a display preference (not inherit) was set for the averages.
|
||||||
|
if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) {
|
||||||
|
$decimalpoints = $gradeitem->get_decimals();
|
||||||
|
} else {
|
||||||
|
$decimalpoints = $averagesdecimalpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
$aggr['average'] = grade_format_gradevalue($aggr['average'],
|
||||||
|
$gradeitem, true, $displaytype, $decimalpoints);
|
||||||
|
|
||||||
|
$avgrow->cells[$gradeitem->id] = $this->format_average_cell($gradeitem, $aggr, $shownumberofgrades);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $avgrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a row of grade items averages. Override this method to change the format of the average cell.
|
||||||
|
*
|
||||||
|
* @param grade_item $gradeitem Grade item.
|
||||||
|
* @param array|null $aggr Average value and meancount information.
|
||||||
|
* @param bool|null $shownumberofgrades Whether to show number of grades.
|
||||||
|
* @return html_table_cell table cell.
|
||||||
|
*/
|
||||||
|
protected function format_average_cell(grade_item $gradeitem, ?array $aggr = null, ?bool $shownumberofgrades = null): html_table_cell {
|
||||||
|
return new html_table_cell();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -2,6 +2,9 @@ This files describes API changes in /grade/report/*,
|
|||||||
information provided here is intended especially for developers.
|
information provided here is intended especially for developers.
|
||||||
|
|
||||||
=== 4.3 ===
|
=== 4.3 ===
|
||||||
|
* The method grade_report::ungraded_counts() now has 2 parameters - group ID and includehidden. First is needed since
|
||||||
|
for grader report we calculate averages for overall and for a group at same time. Second is used to decide if we want
|
||||||
|
to include hidden items in the count or not (For grader and summary reports they are included, for user report - not).
|
||||||
* The load_users() method in the gradereport_singleview\local\screen class has been deprecated. Please use
|
* The load_users() method in the gradereport_singleview\local\screen class has been deprecated. Please use
|
||||||
get_gradable_users() instead.
|
get_gradable_users() instead.
|
||||||
* The \gradereport_singleview\local\screen\select has been deprecated. This class generates the output for the initial
|
* The \gradereport_singleview\local\screen\select has been deprecated. This class generates the output for the initial
|
||||||
|
@ -9,42 +9,117 @@ Feature: Average grades are displayed in the gradebook
|
|||||||
| fullname | shortname | format |
|
| fullname | shortname | format |
|
||||||
| Course 1 | C1 | topics |
|
| Course 1 | C1 | topics |
|
||||||
And the following "users" exist:
|
And the following "users" exist:
|
||||||
|
# Teacher 1 is user without preferences set, Teacher 2 is user with preferences set
|
||||||
| username | firstname | lastname | email |
|
| username | firstname | lastname | email |
|
||||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||||
|
| teacher2 | Teacher | 2 | teacher2@example.com |
|
||||||
| student1 | Student | 1 | student1@example.com |
|
| student1 | Student | 1 | student1@example.com |
|
||||||
| student2 | Student | 2 | student2@example.com |
|
| student2 | Student | 2 | student2@example.com |
|
||||||
| student3 | Student | 3 | student3@example.com |
|
| student3 | Student | 3 | student3@example.com |
|
||||||
|
| student4 | Student | 4 | student4@example.com |
|
||||||
|
| student5 | Student | 5 | student5@example.com |
|
||||||
And the following "course enrolments" exist:
|
And the following "course enrolments" exist:
|
||||||
| user | course | role |
|
| user | course | role |
|
||||||
| teacher1 | C1 | editingteacher |
|
| teacher1 | C1 | editingteacher |
|
||||||
|
| teacher2 | C1 | editingteacher |
|
||||||
| student1 | C1 | student |
|
| student1 | C1 | student |
|
||||||
| student2 | C1 | student |
|
| student2 | C1 | student |
|
||||||
| student3 | C1 | student |
|
| student3 | C1 | student |
|
||||||
|
| student4 | C1 | student |
|
||||||
|
| student5 | C1 | student |
|
||||||
And the following "grade item" exists:
|
And the following "grade item" exists:
|
||||||
| course | C1 |
|
| course | C1 |
|
||||||
| itemname | Manual item 1 |
|
| itemname | Manual item 1 |
|
||||||
And the following "grade grades" exist:
|
And the following "grade grades" exist:
|
||||||
| gradeitem | user | grade |
|
| gradeitem | user | grade | hidden |
|
||||||
| Manual item 1 | student1 | 50.00 |
|
| Manual item 1 | student1 | 10.00 | 0 |
|
||||||
| Manual item 1 | student2 | 50.00 |
|
| Manual item 1 | student2 | 20.00 | 0 |
|
||||||
| Manual item 1 | student3 | 50.00 |
|
| Manual item 1 | student3 | 30.00 | 0 |
|
||||||
|
| Manual item 1 | student4 | 40.00 | 1 |
|
||||||
|
| Manual item 1 | student5 | 50.00 | 0 |
|
||||||
And the following "course enrolments" exist:
|
And the following "course enrolments" exist:
|
||||||
| user | course | role | status |
|
| user | course | role | status |
|
||||||
| student2 | C1 | student | suspended |
|
| student2 | C1 | student | suspended |
|
||||||
|
And I log in as "admin"
|
||||||
|
And I navigate to "Users > Accounts > Browse list of users" in site administration
|
||||||
|
And I set the following fields to these values:
|
||||||
|
| username | student5 |
|
||||||
|
And I press "Add filter"
|
||||||
|
And I click on "Delete" "link"
|
||||||
|
And I press "Delete"
|
||||||
# Enable averages
|
# Enable averages
|
||||||
And I am on the "Course 1" "grades > course grade settings" page logged in as "admin"
|
And I am on the "Course 1" "grades > course grade settings" page
|
||||||
And I set the following fields to these values:
|
And I set the following fields to these values:
|
||||||
| Show average | Show |
|
| Show average | Show |
|
||||||
And I press "Save changes"
|
And I press "Save changes"
|
||||||
|
|
||||||
Scenario: Grade a grade item and ensure the results display correctly in the gradebook
|
Scenario: Grade averages display correctly in the gradebook according to various settings
|
||||||
# Check the admin grade table
|
# Check the admin grade table
|
||||||
Given I am on the "Course 1" "grades > Grader report > View" page logged in as "admin"
|
Given I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
|
||||||
Then I should see "50.00" in the ".avg.r0.lastrow .c1" "css_element"
|
# Average is (10 + 30 + 40)/3 = 26.67 for manual and total since hidden items are included on grader report
|
||||||
Then I should see "50.00" in the ".avg.r0.lastrow .c2" "css_element"
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 26.67 | 26.67 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "26.67" in the "Manual item 1" "table_row"
|
||||||
|
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher2"
|
||||||
|
And the following "user preferences" exist:
|
||||||
|
| user | preference | value |
|
||||||
|
| teacher2 | grade_report_showonlyactiveenrol | 1 |
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page
|
||||||
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 26.67 | 26.67 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "26.67" in the "Manual item 1" "table_row"
|
||||||
|
And the following "user preferences" exist:
|
||||||
|
| user | preference | value |
|
||||||
|
| teacher2 | grade_report_showonlyactiveenrol | 0 |
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page
|
||||||
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 25.00 | 25.00 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "25.00" in the "Manual item 1" "table_row"
|
||||||
|
|
||||||
# Check the user grade table
|
# Check the user grade table
|
||||||
When I am on the "Course 1" "grades > user > View" page logged in as "student1"
|
When I am on the "Course 1" "grades > user > View" page logged in as "student1"
|
||||||
Then I should see "50.00" in the ".level2.column-grade" "css_element"
|
# Average of manual item is (10 + 30)/2 = 20.00 since hidden items are not included on user report.
|
||||||
Then I should see "50.00" in the ".level2.column-average" "css_element"
|
# But total is calculated and its settings allow using hidden grades so it will stay the same.
|
||||||
|
Then the following should exist in the "user-grade" table:
|
||||||
|
| Grade item | Calculated weight | Grade | Range | Percentage | Average | Contribution to course total |
|
||||||
|
| Manual item 1 | 100.00 % | 10.00 | 0–100 | 10.00 % | 20.00 | 10.00 % |
|
||||||
|
| Course total | - | 10.00 | 0–100 | 10.00 % | 26.67 | - |
|
||||||
|
|
||||||
|
# Default grade_report_showonlyactiveenrol is 1 so change that
|
||||||
|
And the following config values are set as admin:
|
||||||
|
| grade_report_showonlyactiveenrol | 0 |
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher2"
|
||||||
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 25.00 | 25.00 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "25.00" in the "Manual item 1" "table_row"
|
||||||
|
And the following "user preferences" exist:
|
||||||
|
| user | preference | value |
|
||||||
|
| teacher2 | grade_report_showonlyactiveenrol | 1 |
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page
|
||||||
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 26.67 | 26.67 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "26.67" in the "Manual item 1" "table_row"
|
||||||
|
|
||||||
|
And I am on the "Course 1" "grades > Grader report > View" page logged in as "teacher1"
|
||||||
|
And the following should exist in the "user-grades" table:
|
||||||
|
| -1- | -2- | -3- |
|
||||||
|
| Overall average | 25.00 | 25.00 |
|
||||||
|
And I am on the "Course 1" "grades > Grade summary > View" page
|
||||||
|
And I should see "25.00" in the "Manual item 1" "table_row"
|
||||||
|
|
||||||
|
And I am on the "Course 1" "grades > user > View" page logged in as "student1"
|
||||||
|
And the following should exist in the "user-grade" table:
|
||||||
|
| Grade item | Calculated weight | Grade | Range | Percentage | Average | Contribution to course total |
|
||||||
|
| Manual item 1 | 100.00 % | 10.00 | 0–100 | 10.00 % | 20.00 | 10.00 % |
|
||||||
|
| Course total | - | 10.00 | 0–100 | 10.00 % | 26.67 | - |
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
namespace core_grades;
|
namespace core_grades;
|
||||||
|
|
||||||
use assign;
|
use assign;
|
||||||
|
use block_globalsearch\globalsearch_test;
|
||||||
use cm_info;
|
use cm_info;
|
||||||
use grade_item;
|
use grade_item;
|
||||||
use grade_plugin_return;
|
use grade_plugin_return;
|
||||||
@ -307,8 +308,8 @@ class lib_test extends \advanced_testcase {
|
|||||||
$report2 = new grade_report_summary($course2->id, $gpr2, $context2);
|
$report2 = new grade_report_summary($course2->id, $gpr2, $context2);
|
||||||
|
|
||||||
$ungradedcounts = [];
|
$ungradedcounts = [];
|
||||||
$ungradedcounts[$course1->id] = $report1->ungraded_counts();
|
$ungradedcounts[$course1->id] = $report1->ungraded_counts(false);
|
||||||
$ungradedcounts[$course2->id] = $report2->ungraded_counts();
|
$ungradedcounts[$course2->id] = $report2->ungraded_counts(false);
|
||||||
|
|
||||||
foreach ($ungradedcounts as $key => $ungradedcount) {
|
foreach ($ungradedcounts as $key => $ungradedcount) {
|
||||||
$gradeitems = grade_item::fetch_all(['courseid' => $key]);
|
$gradeitems = grade_item::fetch_all(['courseid' => $key]);
|
||||||
@ -368,6 +369,110 @@ class lib_test extends \advanced_testcase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that ungraded_counts calculates count and sum of grades correctly when there are hidden grades.
|
||||||
|
* @dataProvider ungraded_counts_hidden_grades_data()
|
||||||
|
* @param bool $hidden Whether to inlcude hidden grades or not.
|
||||||
|
* @param array $expectedcount expected count value (i.e. number of ugraded grades)
|
||||||
|
* @param array $expectedsumarray expceted sum of grades
|
||||||
|
*
|
||||||
|
* @covers \grade_report::ungraded_counts
|
||||||
|
*/
|
||||||
|
public function test_ungraded_counts_hidden_grades(bool $hidden, array $expectedcount, array $expectedsumarray) {
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
|
||||||
|
// 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, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($student3->id, $course->id, 'student');
|
||||||
|
|
||||||
|
// Create grade items in course.
|
||||||
|
$manuaitem = new \grade_item($this->getDataGenerator()->create_grade_item([
|
||||||
|
'itemname' => 'Grade item1',
|
||||||
|
'idnumber' => 'git1',
|
||||||
|
'courseid' => $course->id,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Grade users.
|
||||||
|
$manuaitem->update_final_grade($student1->id, 1);
|
||||||
|
$manuaitem->update_final_grade($student3->id, 2);
|
||||||
|
|
||||||
|
// Create a hidden grade.
|
||||||
|
$manuaitem->update_final_grade($student2->id, 3);
|
||||||
|
$grade = \grade_grade::fetch(['itemid' => $manuaitem->id, 'userid' => $student2->id]);
|
||||||
|
$grade->hidden = 1;
|
||||||
|
$grade->update();
|
||||||
|
|
||||||
|
// Trigger a regrade.
|
||||||
|
grade_force_full_regrading($course->id);
|
||||||
|
grade_regrade_final_grades($course->id);
|
||||||
|
|
||||||
|
// Initialise reports.
|
||||||
|
$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(false, $hidden);
|
||||||
|
|
||||||
|
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
||||||
|
|
||||||
|
foreach ($gradeitems as $gradeitem) {
|
||||||
|
$sumgrades = null;
|
||||||
|
if (array_key_exists($gradeitem->id, $ungradedcounts['ungradedcounts'])) {
|
||||||
|
$ungradeditem = $ungradedcounts['ungradedcounts'][$gradeitem->id];
|
||||||
|
if ($gradeitem->itemtype === 'course') {
|
||||||
|
$this->assertEquals($expectedcount['course'], $ungradeditem->count);
|
||||||
|
} else if ($gradeitem->itemtype === 'manual') {
|
||||||
|
$this->assertEquals($expectedcount['Grade item1'], $ungradeditem->count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($gradeitem->id, $ungradedcounts['sumarray'])) {
|
||||||
|
$sumgrades = $ungradedcounts['sumarray'][$gradeitem->id];
|
||||||
|
if ($gradeitem->itemtype === 'course') {
|
||||||
|
$this->assertEquals($expectedsumarray['course'], $sumgrades);
|
||||||
|
} else if ($gradeitem->itemtype === 'manual') {
|
||||||
|
$this->assertEquals($expectedsumarray['Grade item1'], $sumgrades);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for test_ungraded_counts_hidden_grades
|
||||||
|
*
|
||||||
|
* @return array of testing scenarios
|
||||||
|
*/
|
||||||
|
public function ungraded_counts_hidden_grades_data() : array {
|
||||||
|
return [
|
||||||
|
'nohidden' => [
|
||||||
|
'hidden' => false,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 6.00000, 'Grade item1' => 3.00000],
|
||||||
|
],
|
||||||
|
'includehidden' => [
|
||||||
|
'hidden' => true,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 2],
|
||||||
|
'sumarray' => ['course' => 6.00000, 'Grade item1' => 6.00000],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that ungraded_counts calculates count and sum of grades correctly for groups when there are graded users.
|
* Tests that ungraded_counts calculates count and sum of grades correctly for groups when there are graded users.
|
||||||
*
|
*
|
||||||
@ -376,14 +481,13 @@ class lib_test extends \advanced_testcase {
|
|||||||
public function test_ungraded_count_sumgrades_groups() {
|
public function test_ungraded_count_sumgrades_groups() {
|
||||||
global $DB;
|
global $DB;
|
||||||
|
|
||||||
$this->resetAfterTest(true);
|
$this->resetAfterTest();
|
||||||
|
|
||||||
$course = $this->getDataGenerator()->create_course();
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
|
||||||
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
|
$studentrole = $DB->get_record('role', ['shortname' => 'student'], '*', MUST_EXIST);
|
||||||
|
|
||||||
// Create users.
|
// Create users.
|
||||||
|
|
||||||
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
|
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
|
||||||
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
|
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
|
||||||
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
|
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
|
||||||
@ -400,7 +504,7 @@ class lib_test extends \advanced_testcase {
|
|||||||
$this->getDataGenerator()->create_group_member(['userid' => $student3->id, 'groupid' => $group2->id]);
|
$this->getDataGenerator()->create_group_member(['userid' => $student3->id, 'groupid' => $group2->id]);
|
||||||
$DB->set_field('course', 'groupmode', SEPARATEGROUPS, ['id' => $course->id]);
|
$DB->set_field('course', 'groupmode', SEPARATEGROUPS, ['id' => $course->id]);
|
||||||
|
|
||||||
// Create grade items in course 1.
|
// Create grade items.
|
||||||
$assign1 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
|
$assign1 = $this->getDataGenerator()->create_module('assign', ['course' => $course->id]);
|
||||||
$assign2 = $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]);
|
$quiz1 = $this->getDataGenerator()->create_module('quiz', ['course' => $course->id]);
|
||||||
@ -411,7 +515,7 @@ class lib_test extends \advanced_testcase {
|
|||||||
'courseid' => $course->id,
|
'courseid' => $course->id,
|
||||||
]));
|
]));
|
||||||
|
|
||||||
// Grade users in first course.
|
// Grade users.
|
||||||
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign1->id));
|
$cm = cm_info::create(get_coursemodule_from_instance('assign', $assign1->id));
|
||||||
$assigninstance = new assign($cm->context, $cm, $course);
|
$assigninstance = new assign($cm->context, $cm, $course);
|
||||||
$grade = $assigninstance->get_user_grade($student1->id, true);
|
$grade = $assigninstance->get_user_grade($student1->id, true);
|
||||||
@ -456,8 +560,8 @@ class lib_test extends \advanced_testcase {
|
|||||||
$report2 = new grade_report_summary($course->id, $gpr2, $context);
|
$report2 = new grade_report_summary($course->id, $gpr2, $context);
|
||||||
|
|
||||||
$ungradedcounts = [];
|
$ungradedcounts = [];
|
||||||
$ungradedcounts[$group1->id] = $report1->ungraded_counts();
|
$ungradedcounts[$group1->id] = $report1->ungraded_counts(true);
|
||||||
$ungradedcounts[$group2->id] = $report2->ungraded_counts();
|
$ungradedcounts[$group2->id] = $report2->ungraded_counts(true);
|
||||||
|
|
||||||
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
||||||
|
|
||||||
@ -525,6 +629,162 @@ class lib_test extends \advanced_testcase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that ungraded_counts calculates count and sum of grades correctly when there are hidden grades.
|
||||||
|
* @dataProvider ungraded_counts_only_active_enrol_data()
|
||||||
|
* @param bool $onlyactive Site setting to show only active users.
|
||||||
|
* @param int $hascapability Capability constant
|
||||||
|
* @param bool|null $showonlyactiveenrolpref Show only active user preference.
|
||||||
|
* @param array $expectedcount expected count value (i.e. number of ugraded grades)
|
||||||
|
* @param array $expectedsumarray expected sum of grades
|
||||||
|
*
|
||||||
|
* @covers \grade_report::ungraded_counts
|
||||||
|
*/
|
||||||
|
public function test_ungraded_counts_only_active_enrol(bool $onlyactive,
|
||||||
|
int $hascapability, ?bool $showonlyactiveenrolpref, array $expectedcount, array $expectedsumarray) {
|
||||||
|
global $CFG, $DB;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
$CFG->grade_report_showonlyactiveenrol = $onlyactive;
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
|
||||||
|
// Create users.
|
||||||
|
$student1 = $this->getDataGenerator()->create_user(['username' => 'student1']);
|
||||||
|
$student2 = $this->getDataGenerator()->create_user(['username' => 'student2']);
|
||||||
|
$student3 = $this->getDataGenerator()->create_user(['username' => 'student3']);
|
||||||
|
$teacher = $this->getDataGenerator()->create_and_enrol($course, 'teacher');
|
||||||
|
|
||||||
|
// Enrol students.
|
||||||
|
$this->getDataGenerator()->enrol_user($student1->id, $course->id, 'student');
|
||||||
|
$this->getDataGenerator()->enrol_user($student2->id, $course->id, 'student');
|
||||||
|
|
||||||
|
// Give teacher 'viewsuspendedusers' capability and set a preference to display suspended users.
|
||||||
|
$roleteacher = $DB->get_record('role', ['shortname' => 'teacher'], '*', MUST_EXIST);
|
||||||
|
$coursecontext = \context_course::instance($course->id);
|
||||||
|
assign_capability('moodle/course:viewsuspendedusers', $hascapability, $roleteacher->id, $coursecontext, true);
|
||||||
|
set_user_preference('grade_report_showonlyactiveenrol', $showonlyactiveenrolpref, $teacher);
|
||||||
|
accesslib_clear_all_caches_for_unit_testing();
|
||||||
|
|
||||||
|
$this->setUser($teacher);
|
||||||
|
|
||||||
|
// Suspended student.
|
||||||
|
$this->getDataGenerator()->enrol_user($student3->id, $course->id, 'student', 'manual', 0, 0, ENROL_USER_SUSPENDED);
|
||||||
|
|
||||||
|
// Create grade items in course.
|
||||||
|
$manuaitem = new \grade_item($this->getDataGenerator()->create_grade_item([
|
||||||
|
'itemname' => 'Grade item1',
|
||||||
|
'idnumber' => 'git1',
|
||||||
|
'courseid' => $course->id,
|
||||||
|
]));
|
||||||
|
|
||||||
|
// Grade users.
|
||||||
|
$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 reports.
|
||||||
|
$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);
|
||||||
|
|
||||||
|
$showonlyactiveenrol = $report->show_only_active();
|
||||||
|
$ungradedcounts = $report->ungraded_counts(false, false, $showonlyactiveenrol);
|
||||||
|
|
||||||
|
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
||||||
|
|
||||||
|
foreach ($gradeitems as $gradeitem) {
|
||||||
|
$sumgrades = null;
|
||||||
|
if (array_key_exists($gradeitem->id, $ungradedcounts['ungradedcounts'])) {
|
||||||
|
$ungradeditem = $ungradedcounts['ungradedcounts'][$gradeitem->id];
|
||||||
|
if ($gradeitem->itemtype === 'course') {
|
||||||
|
$this->assertEquals($expectedcount['course'], $ungradeditem->count);
|
||||||
|
} else if ($gradeitem->itemtype === 'manual') {
|
||||||
|
$this->assertEquals($expectedcount['Grade item1'], $ungradeditem->count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($gradeitem->id, $ungradedcounts['sumarray'])) {
|
||||||
|
$sumgrades = $ungradedcounts['sumarray'][$gradeitem->id];
|
||||||
|
if ($gradeitem->itemtype === 'course') {
|
||||||
|
$this->assertEquals($expectedsumarray['course'], $sumgrades);
|
||||||
|
} else if ($gradeitem->itemtype === 'manual') {
|
||||||
|
$this->assertEquals($expectedsumarray['Grade item1'], $sumgrades);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data provider for test_ungraded_counts_hidden_grades
|
||||||
|
*
|
||||||
|
* @return array of testing scenarios
|
||||||
|
*/
|
||||||
|
public function ungraded_counts_only_active_enrol_data(): array {
|
||||||
|
return [
|
||||||
|
'Show only active and no user preference' => [
|
||||||
|
'onlyactive' => true,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => null,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 1, 'Grade item1' => 1.00000],
|
||||||
|
],
|
||||||
|
'Show only active and user preference set to true' => [
|
||||||
|
'onlyactive' => true,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => true,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 1, 'Grade item1' => 1.00000],
|
||||||
|
],
|
||||||
|
'Show only active and user preference set to false' => [
|
||||||
|
'onlyactive' => true,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => false,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 3.00000, 'Grade item1' => 3.00000],
|
||||||
|
],
|
||||||
|
'Include suspended with capability and user preference set to true' => [
|
||||||
|
'onlyactive' => false,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => true,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 1.00000, 'Grade item1' => 1.00000],
|
||||||
|
],
|
||||||
|
'Include suspended with capability and user preference set to false' => [
|
||||||
|
'onlyactive' => false,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => false,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 3.00000, 'Grade item1' => 3.00000],
|
||||||
|
],
|
||||||
|
'Include suspended with capability and no user preference' => [
|
||||||
|
'onlyactive' => false,
|
||||||
|
'hascapability' => 1,
|
||||||
|
'showonlyactiveenrolpref' => null,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 3.00000, 'Grade item1' => 3.00000],
|
||||||
|
],
|
||||||
|
'Include suspended without capability' => [
|
||||||
|
'onlyactive' => false,
|
||||||
|
'hascapability' => -1,
|
||||||
|
'showonlyactiveenrolpref' => null,
|
||||||
|
'count' => ['course' => 1, 'Grade item1' => 1],
|
||||||
|
'sumarray' => ['course' => 1.00000, 'Grade item1' => 1.00000],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for calculate_average.
|
* Tests for calculate_average.
|
||||||
* @dataProvider calculate_average_data()
|
* @dataProvider calculate_average_data()
|
||||||
@ -600,7 +860,7 @@ class lib_test extends \advanced_testcase {
|
|||||||
|
|
||||||
$report = new grade_report_summary($course->id, $gpr, $context);
|
$report = new grade_report_summary($course->id, $gpr, $context);
|
||||||
|
|
||||||
$ungradedcounts = $report->ungraded_counts();
|
$ungradedcounts = $report->ungraded_counts(false);
|
||||||
$ungradedcounts['report']['meanselection'] = $meanselection;
|
$ungradedcounts['report']['meanselection'] = $meanselection;
|
||||||
|
|
||||||
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
$gradeitems = grade_item::fetch_all(['courseid' => $course->id]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user