mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 00:42:54 +02:00
Merge branch 'wip-MDL-45390-master' of git://github.com/abgreeve/moodle
This commit is contained in:
commit
9d00c6e9e5
@ -493,6 +493,8 @@ class restore_gradebook_structure_step extends restore_structure_step {
|
||||
$gradebookcalculationsfreeze = get_config('core', 'gradebook_calculations_freeze_' . $this->get_courseid());
|
||||
preg_match('/(\d{8})/', $this->get_task()->get_info()->moodle_release, $matches);
|
||||
$backupbuild = (int)$matches[1];
|
||||
// The function floatval will return a float even if there is text mixed with the release number.
|
||||
$backuprelease = floatval($this->get_task()->get_info()->backup_release);
|
||||
|
||||
// Extra credits need adjustments only for backups made between 2.8 release (20141110) and the fix release (20150619).
|
||||
if (!$gradebookcalculationsfreeze && $backupbuild >= 20141110 && $backupbuild < 20150619) {
|
||||
@ -504,6 +506,14 @@ class restore_gradebook_structure_step extends restore_structure_step {
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
upgrade_calculated_grade_items($this->get_courseid());
|
||||
}
|
||||
// Courses from before 3.1 (20160518) may have a letter boundary problem and should be checked for this issue.
|
||||
// Backups from before and including 2.9 could have a build number that is greater than 20160518 and should
|
||||
// be checked for this problem.
|
||||
if (!$gradebookcalculationsfreeze && ($backupbuild < 20160518 || $backuprelease <= 2.9)) {
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
upgrade_course_letter_boundary($this->get_courseid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
43
grade/tests/behat/grade_letter_boundary.feature
Normal file
43
grade/tests/behat/grade_letter_boundary.feature
Normal file
@ -0,0 +1,43 @@
|
||||
@core @core_grades
|
||||
Feature: We can customise the letter boundary of a course.
|
||||
In order to change the letter boundary of a course
|
||||
As a teacher
|
||||
I need to add assessments to the gradebook.
|
||||
|
||||
@javascript
|
||||
Scenario: I edit the letter boundaries of a course and grade a student.
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber | alternatename |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | Terry |
|
||||
| student1 | Student | 1 | student1@example.com | s1 | Sally |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | grade |
|
||||
| assign | C1 | a1 | Test assignment one | Submit something! | 100 |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
And I select "Course grade settings" from the "Grade report" singleselect
|
||||
And I set the following fields to these values:
|
||||
| Grade display type | Letter |
|
||||
And I press "Save changes"
|
||||
And I navigate to "Letters" node in "Grade administration"
|
||||
And I follow "Edit grade letters"
|
||||
And I set the following fields to these values:
|
||||
| id_override | 1 |
|
||||
| id_gradeboundary10 | 57 |
|
||||
And I press "Save changes"
|
||||
And I select "Grader report" from the "Grade report" singleselect
|
||||
And I press "Turn editing on"
|
||||
And I give the grade "57" to the user "Student 1" for the grade item "Test assignment one"
|
||||
And I press "Save changes"
|
||||
And I press "Turn editing off"
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -4- | -5- |
|
||||
| Student 1 | D | D |
|
44
grade/tests/behat/grade_letter_boundary_20160518.feature
Normal file
44
grade/tests/behat/grade_letter_boundary_20160518.feature
Normal file
@ -0,0 +1,44 @@
|
||||
@core @core_grades
|
||||
Feature: We can customise the letter boundary of a course.
|
||||
In order to change the letter boundary of a course
|
||||
As a teacher
|
||||
I need to add assessments to the gradebook.
|
||||
|
||||
@javascript
|
||||
Scenario: I edit the letter boundaries of a course and grade a student.
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category |
|
||||
| Course 1 | C1 | 0 |
|
||||
And gradebook calculations for the course "C1" are frozen at version "20160518"
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email | idnumber | alternatename |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com | t1 | Terry |
|
||||
| student1 | Student | 1 | student1@example.com | s1 | Sally |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "activities" exist:
|
||||
| activity | course | idnumber | name | intro | grade |
|
||||
| assign | C1 | a1 | Test assignment one | Submit something! | 100 |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
And I select "Course grade settings" from the "Grade report" singleselect
|
||||
And I set the following fields to these values:
|
||||
| Grade display type | Letter |
|
||||
And I press "Save changes"
|
||||
And I navigate to "Letters" node in "Grade administration"
|
||||
And I follow "Edit grade letters"
|
||||
And I set the following fields to these values:
|
||||
| id_override | 1 |
|
||||
| id_gradeboundary10 | 57 |
|
||||
And I press "Save changes"
|
||||
And I select "Grader report" from the "Grade report" singleselect
|
||||
And I press "Turn editing on"
|
||||
And I give the grade "57" to the user "Student 1" for the grade item "Test assignment one"
|
||||
And I press "Save changes"
|
||||
And I press "Turn editing off"
|
||||
Then the following should exist in the "user-grades" table:
|
||||
| -1- | -4- | -5- |
|
||||
| Student 1 | F | F |
|
@ -134,6 +134,7 @@ function xmldb_main_install() {
|
||||
'upgrade_minmaxgradestepignored' => 1, // New installs should not run this upgrade step.
|
||||
'upgrade_extracreditweightsstepignored' => 1, // New installs should not run this upgrade step.
|
||||
'upgrade_calculatedgradeitemsignored' => 1, // New installs should not run this upgrade step.
|
||||
'upgrade_letterboundarycourses' => 1, // New installs should not run this upgrade step.
|
||||
);
|
||||
foreach($defaults as $key => $value) {
|
||||
set_config($key, $value);
|
||||
|
@ -2053,5 +2053,21 @@ function xmldb_main_upgrade($oldversion) {
|
||||
upgrade_main_savepoint(true, 2016051300.00);
|
||||
}
|
||||
|
||||
if ($oldversion < 2016051700.01) {
|
||||
// This script is included in each major version upgrade process (3.0, 3.1) so make sure we don't run it twice.
|
||||
if (empty($CFG->upgrade_letterboundarycourses)) {
|
||||
// MDL-45390. If a grade is being displayed with letters and the grade boundaries are not being adhered to properly
|
||||
// then this course will also be frozen.
|
||||
// If the changes are accepted then the display of some grades may change.
|
||||
// This is here to freeze the gradebook in affected courses.
|
||||
upgrade_course_letter_boundary();
|
||||
|
||||
// To skip running the same script on the upgrade to the next major version release.
|
||||
set_config('upgrade_letterboundarycourses', 1);
|
||||
}
|
||||
// Main savepoint reached.
|
||||
upgrade_main_savepoint(true, 2016051700.01);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -357,3 +357,159 @@ function make_competence_scale() {
|
||||
$defaultscale->id = $DB->insert_record('scale', $defaultscale);
|
||||
return $defaultscale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all courses that require rounded grade items be updated.
|
||||
*
|
||||
* Used during upgrade and in course restore process.
|
||||
*
|
||||
* This upgrade script is needed because it has been decided that if a grade is rounded up, and it will changed a letter
|
||||
* grade or satisfy a course completion grade criteria, then it should be set as so, and the letter will be awarded and or
|
||||
* the course completion grade will be awarded.
|
||||
*
|
||||
* @param int $courseid Specify a course ID to run this script on just one course.
|
||||
*/
|
||||
function upgrade_course_letter_boundary($courseid = null) {
|
||||
global $DB, $CFG;
|
||||
|
||||
$coursesql = '';
|
||||
$params = array('contextlevel' => CONTEXT_COURSE);
|
||||
if (!empty($courseid)) {
|
||||
$coursesql = 'AND c.id = :courseid';
|
||||
$params['courseid'] = $courseid;
|
||||
}
|
||||
|
||||
// Check to see if the system letter boundaries are borked.
|
||||
$systemcontext = context_system::instance();
|
||||
$systemneedsfreeze = upgrade_letter_boundary_needs_freeze($systemcontext);
|
||||
|
||||
// 3, 13, 23, 31, and 32 are the grade display types that incorporate showing letters. See lib/grade/constants/php.
|
||||
$systemletters = (isset($CFG->grade_displaytype) && in_array($CFG->grade_displaytype, array(3, 13, 23, 31, 32)));
|
||||
|
||||
$contextselect = context_helper::get_preload_record_columns_sql('ctx');
|
||||
|
||||
if ($systemletters && $systemneedsfreeze) {
|
||||
// Select courses with no grade setting for display and a grade item that is using the default display,
|
||||
// but have not altered the course letter boundary configuration. These courses are definitely affected.
|
||||
|
||||
$sql = "SELECT DISTINCT c.id AS courseid
|
||||
FROM {course} c
|
||||
JOIN {grade_items} gi ON c.id = gi.courseid
|
||||
JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
|
||||
LEFT JOIN {grade_settings} gs ON gs.courseid = c.id AND gs.name = 'displaytype'
|
||||
LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
|
||||
WHERE gi.display = 0 AND (gs.value is NULL)
|
||||
AND gl.id is NULL $coursesql";
|
||||
$affectedcourseids = $DB->get_recordset_sql($sql, $params);
|
||||
foreach ($affectedcourseids as $courseid) {
|
||||
set_config('gradebook_calculations_freeze_' . $courseid->courseid, 20160518);
|
||||
}
|
||||
$affectedcourseids->close();
|
||||
|
||||
}
|
||||
|
||||
if ($systemletters || $systemneedsfreeze) {
|
||||
|
||||
// If the system letter boundary is okay proceed to check grade item and course grade display settings.
|
||||
$sql = "SELECT DISTINCT c.id AS courseid, $contextselect
|
||||
FROM {course} c
|
||||
JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
|
||||
JOIN {grade_items} gi ON c.id = gi.courseid
|
||||
LEFT JOIN {grade_settings} gs ON c.id = gs.courseid AND gs.name = 'displaytype'
|
||||
LEFT JOIN {grade_letters} gl ON gl.contextid = ctx.id
|
||||
WHERE gi.display IN (3, 13, 23, 31, 32)
|
||||
OR (" . $DB->sql_compare_text('gs.value') . " IN ('3', '13', '23', '31', '32'))
|
||||
OR gl.id is NOT NULL
|
||||
$coursesql";
|
||||
} else {
|
||||
|
||||
// There is no site setting for letter grades. Just check the modified letter boundaries.
|
||||
$sql = "SELECT DISTINCT c.id AS courseid, $contextselect
|
||||
FROM {grade_letters} l, {course} c
|
||||
JOIN {context} ctx ON ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel
|
||||
WHERE l.contextid = ctx.id
|
||||
AND ctx.instanceid = c.id
|
||||
$coursesql";
|
||||
}
|
||||
|
||||
$potentialcourses = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
foreach ($potentialcourses as $value) {
|
||||
$gradebookfreeze = 'gradebook_calculations_freeze_' . $value->courseid;
|
||||
|
||||
// Check also if this course id has already been frozen.
|
||||
// If we already have this course ID then move on to the next record.
|
||||
if (!property_exists($CFG, $gradebookfreeze)) {
|
||||
// Check for 57 letter grade issue.
|
||||
context_helper::preload_from_record($value);
|
||||
$coursecontext = context_course::instance($value->courseid);
|
||||
if (upgrade_letter_boundary_needs_freeze($coursecontext)) {
|
||||
// We have a course with a possible score standardisation problem. Flag for freeze.
|
||||
// Flag this course as being frozen.
|
||||
set_config('gradebook_calculations_freeze_' . $value->courseid, 20160518);
|
||||
}
|
||||
}
|
||||
}
|
||||
$potentialcourses->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the letter boundary of the provided context to see if it needs freezing.
|
||||
* Each letter boundary is tested to see if receiving that boundary number will
|
||||
* result in achieving the cosponsoring letter.
|
||||
*
|
||||
* @param object $context Context object
|
||||
* @return bool if the letter boundary for this context should be frozen.
|
||||
*/
|
||||
function upgrade_letter_boundary_needs_freeze($context) {
|
||||
global $DB;
|
||||
|
||||
$contexts = $context->get_parent_context_ids();
|
||||
array_unshift($contexts, $context->id);
|
||||
|
||||
foreach ($contexts as $ctxid) {
|
||||
|
||||
$letters = $DB->get_records_menu('grade_letters', array('contextid' => $ctxid), 'lowerboundary DESC',
|
||||
'lowerboundary, letter');
|
||||
|
||||
if (!empty($letters)) {
|
||||
foreach ($letters as $boundary => $notused) {
|
||||
$standardisedboundary = upgrade_standardise_score($boundary, 0, 100, 0, 100);
|
||||
if ($boundary != $standardisedboundary) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// We found letters but we have no boundary problem.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a float value situated between a source minimum and a source maximum, converts it to the
|
||||
* corresponding value situated between a target minimum and a target maximum. Thanks to Darlene
|
||||
* for the formula :-)
|
||||
*
|
||||
* @param float $rawgrade
|
||||
* @param float $sourcemin
|
||||
* @param float $sourcemax
|
||||
* @param float $targetmin
|
||||
* @param float $targetmax
|
||||
* @return float Converted value
|
||||
*/
|
||||
function upgrade_standardise_score($rawgrade, $sourcemin, $sourcemax, $targetmin, $targetmax) {
|
||||
if (is_null($rawgrade)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($sourcemax == $sourcemin or $targetmin == $targetmax) {
|
||||
// Prevent division by 0.
|
||||
return $targetmax;
|
||||
}
|
||||
|
||||
$factor = ($rawgrade - $sourcemin) / ($sourcemax - $sourcemin);
|
||||
$diff = $targetmax - $targetmin;
|
||||
$standardisedvalue = $factor * $diff + $targetmin;
|
||||
return $standardisedvalue;
|
||||
}
|
||||
|
@ -846,6 +846,7 @@ function grade_format_gradevalue_percentage($value, $grade_item, $decimals, $loc
|
||||
* @return string
|
||||
*/
|
||||
function grade_format_gradevalue_letter($value, $grade_item) {
|
||||
global $CFG;
|
||||
$context = context_course::instance($grade_item->courseid, IGNORE_MISSING);
|
||||
if (!$letters = grade_get_letters($context)) {
|
||||
return ''; // no letters??
|
||||
@ -857,7 +858,16 @@ function grade_format_gradevalue_letter($value, $grade_item) {
|
||||
|
||||
$value = grade_grade::standardise_score($value, $grade_item->grademin, $grade_item->grademax, 0, 100);
|
||||
$value = bounded_number(0, $value, 100); // just in case
|
||||
|
||||
$gradebookcalculationsfreeze = 'gradebook_calculations_freeze_' . $grade_item->courseid;
|
||||
|
||||
foreach ($letters as $boundary => $letter) {
|
||||
if (property_exists($CFG, $gradebookcalculationsfreeze) && (int)$CFG->{$gradebookcalculationsfreeze} <= 20160518) {
|
||||
// Do nothing.
|
||||
} else {
|
||||
// The boundary is a percentage out of 100 so use 0 as the min and 100 as the max.
|
||||
$boundary = grade_grade::standardise_score($boundary, 0, 100, 0, 100);
|
||||
}
|
||||
if ($value >= $boundary) {
|
||||
return format_string($letter);
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ defined('MOODLE_INTERNAL') || die();
|
||||
global $CFG;
|
||||
require_once($CFG->libdir.'/upgradelib.php');
|
||||
|
||||
|
||||
/**
|
||||
* Tests various classes and functions in upgradelib.php library.
|
||||
*/
|
||||
@ -576,4 +575,258 @@ class core_upgradelib_testcase extends advanced_testcase {
|
||||
$this->assertEquals(array(103, 104), array_values($DB->get_fieldset_select('tag_instance', 'tagid',
|
||||
'itemtype = ? AND itemid = ? ORDER BY tagid', array('course', 3))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the upgrade script correctly flags courses to be frozen due to letter boundary problems.
|
||||
*/
|
||||
public function test_upgrade_course_letter_boundary() {
|
||||
global $CFG, $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
|
||||
// Create a user.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create some courses.
|
||||
$courses = array();
|
||||
$contexts = array();
|
||||
for ($i = 0; $i < 37; $i++) {
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$context = context_course::instance($course->id);
|
||||
if (in_array($i, array(2, 5, 10, 13, 14, 19, 23, 25, 30, 34, 36))) {
|
||||
// Assign good letter boundaries.
|
||||
$this->assign_good_letter_boundary($context->id);
|
||||
}
|
||||
if (in_array($i, array(3, 6, 11, 15, 20, 24, 26, 31, 35))) {
|
||||
// Assign bad letter boundaries.
|
||||
$this->assign_bad_letter_boundary($context->id);
|
||||
}
|
||||
|
||||
if (in_array($i, array(9, 10, 11, 18, 19, 20, 29, 30, 31))) {
|
||||
grade_set_setting($course->id, 'displaytype', '3');
|
||||
} else if (in_array($i, array(8, 17, 28))) {
|
||||
grade_set_setting($course->id, 'displaytype', '2');
|
||||
}
|
||||
|
||||
if ($i >= 7) {
|
||||
$assignrow = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'name' => 'Test!'));
|
||||
$gi = grade_item::fetch(
|
||||
array('itemtype' => 'mod',
|
||||
'itemmodule' => 'assign',
|
||||
'iteminstance' => $assignrow->id,
|
||||
'courseid' => $course->id));
|
||||
if (in_array($i, array(13, 14, 15, 23, 24, 34, 35, 36))) {
|
||||
grade_item::set_properties($gi, array('display', 3));
|
||||
$gi->update();
|
||||
} else if (in_array($i, array(12, 21, 32))) {
|
||||
grade_item::set_properties($gi, array('display', 2));
|
||||
$gi->update();
|
||||
}
|
||||
$gradegrade = new grade_grade();
|
||||
$gradegrade->itemid = $gi->id;
|
||||
$gradegrade->userid = $user->id;
|
||||
$gradegrade->rawgrade = 55.5563;
|
||||
$gradegrade->finalgrade = 55.5563;
|
||||
$gradegrade->rawgrademax = 100;
|
||||
$gradegrade->rawgrademin = 0;
|
||||
$gradegrade->timecreated = time();
|
||||
$gradegrade->timemodified = time();
|
||||
$gradegrade->insert();
|
||||
}
|
||||
|
||||
$contexts[] = $context;
|
||||
$courses[] = $course;
|
||||
}
|
||||
|
||||
upgrade_course_letter_boundary();
|
||||
|
||||
// No system setting for grade letter boundaries.
|
||||
// [0] A course with no letter boundaries.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[0]->id}));
|
||||
// [1] A course with letter boundaries which are default.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[1]->id}));
|
||||
// [2] A course with letter boundaries which are custom but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[2]->id}));
|
||||
// [3] A course with letter boundaries which are custom and will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[3]->id});
|
||||
// [4] A course with no letter boundaries, but with a grade item with letter boundaries which are default.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[4]->id}));
|
||||
// [5] A course with no letter boundaries, but with a grade item with letter boundaries which are not default, but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[5]->id}));
|
||||
// [6] A course with no letter boundaries, but with a grade item with letter boundaries which are not default which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[6]->id});
|
||||
|
||||
// System setting for grade letter boundaries (default).
|
||||
set_config('grade_displaytype', '3');
|
||||
for ($i = 0; $i < 37; $i++) {
|
||||
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
|
||||
}
|
||||
upgrade_course_letter_boundary();
|
||||
|
||||
// [7] A course with no grade display settings for the course or grade items.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[7]->id}));
|
||||
// [8] A course with grade display settings, but for something that isn't letters.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[8]->id}));
|
||||
// [9] A course with grade display settings of letters which are default.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[9]->id}));
|
||||
// [10] A course with grade display settings of letters which are not default, but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[10]->id}));
|
||||
// [11] A course with grade display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[11]->id});
|
||||
// [12] A grade item with display settings that are not letters.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[12]->id}));
|
||||
// [13] A grade item with display settings of letters which are default.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[13]->id}));
|
||||
// [14] A grade item with display settings of letters which are not default, but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[14]->id}));
|
||||
// [15] A grade item with display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[15]->id});
|
||||
|
||||
// System setting for grade letter boundaries (custom with problem).
|
||||
$systemcontext = context_system::instance();
|
||||
$this->assign_bad_letter_boundary($systemcontext->id);
|
||||
for ($i = 0; $i < 37; $i++) {
|
||||
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
|
||||
}
|
||||
upgrade_course_letter_boundary();
|
||||
|
||||
// [16] A course with no grade display settings for the course or grade items.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[16]->id});
|
||||
// [17] A course with grade display settings, but for something that isn't letters.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[17]->id}));
|
||||
// [18] A course with grade display settings of letters which are default.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[18]->id});
|
||||
// [19] A course with grade display settings of letters which are not default, but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[19]->id}));
|
||||
// [20] A course with grade display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[20]->id});
|
||||
// [21] A grade item with display settings which are not letters. Grade total will be affected so should be frozen.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[21]->id});
|
||||
// [22] A grade item with display settings of letters which are default.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[22]->id});
|
||||
// [23] A grade item with display settings of letters which are not default, but not affected. Course uses new letter boundary setting.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[23]->id}));
|
||||
// [24] A grade item with display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[24]->id});
|
||||
// [25] A course which is using the default grade display setting, but has updated the grade letter boundary (not 57) Should not be frozen.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[25]->id}));
|
||||
// [26] A course that is using the default display setting (letters) and altered the letter boundary with 57. Should be frozen.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[26]->id});
|
||||
|
||||
// System setting not showing letters.
|
||||
set_config('grade_displaytype', '2');
|
||||
for ($i = 0; $i < 37; $i++) {
|
||||
unset_config('gradebook_calculations_freeze_' . $courses[$i]->id);
|
||||
}
|
||||
upgrade_course_letter_boundary();
|
||||
|
||||
// [27] A course with no grade display settings for the course or grade items.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[27]->id}));
|
||||
// [28] A course with grade display settings, but for something that isn't letters.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[28]->id}));
|
||||
// [29] A course with grade display settings of letters which are default.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[29]->id});
|
||||
// [30] A course with grade display settings of letters which are not default, but not affected.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[30]->id}));
|
||||
// [31] A course with grade display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[31]->id});
|
||||
// [32] A grade item with display settings which are not letters.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[32]->id}));
|
||||
// [33] All system defaults.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[33]->id}));
|
||||
// [34] A grade item with display settings of letters which are not default, but not affected. Course uses new letter boundary setting.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[34]->id}));
|
||||
// [35] A grade item with display settings of letters which are not default, which will be affected.
|
||||
$this->assertEquals(20160518, $CFG->{'gradebook_calculations_freeze_' . $courses[35]->id});
|
||||
// [36] A course with grade display settings of letters with modified and good boundary (not 57) Should not be frozen.
|
||||
$this->assertTrue(empty($CFG->{'gradebook_calculations_freeze_' . $courses[36]->id}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test upgrade_letter_boundary_needs_freeze function.
|
||||
*/
|
||||
public function test_upgrade_letter_boundary_needs_freeze() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
require_once($CFG->libdir . '/db/upgradelib.php');
|
||||
|
||||
$courses = array();
|
||||
$contexts = array();
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
$courses[] = $this->getDataGenerator()->create_course();
|
||||
$contexts[] = context_course::instance($courses[$i]->id);
|
||||
}
|
||||
|
||||
// Course one is not using a letter boundary.
|
||||
$this->assertFalse(upgrade_letter_boundary_needs_freeze($contexts[0]));
|
||||
|
||||
// Let's make course 2 use the bad boundary.
|
||||
$this->assign_bad_letter_boundary($contexts[1]->id);
|
||||
$this->assertTrue(upgrade_letter_boundary_needs_freeze($contexts[1]));
|
||||
// Course 3 has letter boundaries that are fine.
|
||||
$this->assign_good_letter_boundary($contexts[2]->id);
|
||||
$this->assertFalse(upgrade_letter_boundary_needs_freeze($contexts[2]));
|
||||
// Try the system context not using a letter boundary.
|
||||
$systemcontext = context_system::instance();
|
||||
$this->assertFalse(upgrade_letter_boundary_needs_freeze($systemcontext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns letter boundaries with comparison problems.
|
||||
*
|
||||
* @param int $contextid Context ID.
|
||||
*/
|
||||
private function assign_bad_letter_boundary($contextid) {
|
||||
global $DB;
|
||||
$newlettersscale = array(
|
||||
array('contextid' => $contextid, 'lowerboundary' => 90.00000, 'letter' => 'A'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 85.00000, 'letter' => 'A-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 80.00000, 'letter' => 'B+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 75.00000, 'letter' => 'B'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 70.00000, 'letter' => 'B-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 65.00000, 'letter' => 'C+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 57.00000, 'letter' => 'C'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 50.00000, 'letter' => 'C-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 40.00000, 'letter' => 'D+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 25.00000, 'letter' => 'D'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 0.00000, 'letter' => 'F'),
|
||||
);
|
||||
|
||||
$DB->delete_records('grade_letters', array('contextid' => $contextid));
|
||||
foreach ($newlettersscale as $record) {
|
||||
// There is no API to do this, so we have to manually insert into the database.
|
||||
$DB->insert_record('grade_letters', $record);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns letter boundaries with no comparison problems.
|
||||
*
|
||||
* @param int $contextid Context ID.
|
||||
*/
|
||||
private function assign_good_letter_boundary($contextid) {
|
||||
global $DB;
|
||||
$newlettersscale = array(
|
||||
array('contextid' => $contextid, 'lowerboundary' => 90.00000, 'letter' => 'A'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 85.00000, 'letter' => 'A-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 80.00000, 'letter' => 'B+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 75.00000, 'letter' => 'B'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 70.00000, 'letter' => 'B-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 65.00000, 'letter' => 'C+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 54.00000, 'letter' => 'C'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 50.00000, 'letter' => 'C-'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 40.00000, 'letter' => 'D+'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 25.00000, 'letter' => 'D'),
|
||||
array('contextid' => $contextid, 'lowerboundary' => 0.00000, 'letter' => 'F'),
|
||||
);
|
||||
|
||||
$DB->delete_records('grade_letters', array('contextid' => $contextid));
|
||||
foreach ($newlettersscale as $record) {
|
||||
// There is no API to do this, so we have to manually insert into the database.
|
||||
$DB->insert_record('grade_letters', $record);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2016051700.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2016051700.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user