Skip to content

Commit

Permalink
Merge branch 'MDL-74231' of https://github.com/stronk7/moodle
Browse files Browse the repository at this point in the history
  • Loading branch information
junpataleta committed Mar 30, 2022
2 parents 6b071a0 + 4e2b4a1 commit 3ec0b78
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 11 deletions.
38 changes: 27 additions & 11 deletions grade/report/grader/lib.php
Expand Up @@ -1768,9 +1768,10 @@ public function process_action($target, $action) {
*/
protected static function filter_collapsed_categories($courseid, $collapsed) {
global $DB;
if (empty($collapsed)) {
$collapsed = array('aggregatesonly' => array(), 'gradesonly' => array());
}
// Ensure we always have an element for aggregatesonly and another for gradesonly, no matter it's empty.
$collapsed['aggregatesonly'] = $collapsed['aggregatesonly'] ?? [];
$collapsed['gradesonly'] = $collapsed['gradesonly'] ?? [];

if (empty($collapsed['aggregatesonly']) && empty($collapsed['gradesonly'])) {
return $collapsed;
}
Expand All @@ -1791,12 +1792,23 @@ protected static function filter_collapsed_categories($courseid, $collapsed) {
*/
protected static function get_collapsed_preferences($courseid) {
if ($collapsed = get_user_preferences('grade_report_grader_collapsed_categories'.$courseid)) {
return json_decode($collapsed, true);
$collapsed = json_decode($collapsed, true);
// Ensure we always have an element for aggregatesonly and another for gradesonly, no matter it's empty.
$collapsed['aggregatesonly'] = $collapsed['aggregatesonly'] ?? [];
$collapsed['gradesonly'] = $collapsed['gradesonly'] ?? [];
return $collapsed;
}

// Try looking for old location of user setting that used to store all courses in one serialized user preference.
$collapsed = ['aggregatesonly' => [], 'gradesonly' => []]; // Use this if old settings are not found.
$collapsedall = [];
$oldprefexists = false;
if (($oldcollapsedpref = get_user_preferences('grade_report_grader_collapsed_categories')) !== null) {
$oldprefexists = true;
if ($collapsedall = unserialize_array($oldcollapsedpref)) {
// Ensure we always have an element for aggregatesonly and another for gradesonly, no matter it's empty.
$collapsedall['aggregatesonly'] = $collapsedall['aggregatesonly'] ?? [];
$collapsedall['gradesonly'] = $collapsedall['gradesonly'] ?? [];
// We found the old-style preference, filter out only categories that belong to this course and update the prefs.
$collapsed = static::filter_collapsed_categories($courseid, $collapsedall);
if (!empty($collapsed['aggregatesonly']) || !empty($collapsed['gradesonly'])) {
Expand All @@ -1805,17 +1817,21 @@ protected static function get_collapsed_preferences($courseid) {
$collapsedall['gradesonly'] = array_diff($collapsedall['gradesonly'], $collapsed['gradesonly']);
if (!empty($collapsedall['aggregatesonly']) || !empty($collapsedall['gradesonly'])) {
set_user_preference('grade_report_grader_collapsed_categories', serialize($collapsedall));
} else {
unset_user_preference('grade_report_grader_collapsed_categories');
}
}
} else {
// We found the old-style preference, but it is unreadable, discard it.
unset_user_preference('grade_report_grader_collapsed_categories');
}
} else {
$collapsed = array('aggregatesonly' => array(), 'gradesonly' => array());
}

// Arrived here, if the old pref exists and it doesn't contain
// more information, it means that the migration of all the
// data to new, by course, preferences is completed, so
// the old one can be safely deleted.
if ($oldprefexists &&
empty($collapsedall['aggregatesonly']) &&
empty($collapsedall['gradesonly'])) {
unset_user_preference('grade_report_grader_collapsed_categories');
}

return $collapsed;
}

Expand Down
220 changes: 220 additions & 0 deletions grade/tests/report_graderlib_test.php
Expand Up @@ -230,6 +230,226 @@ public function test_collapsed_preferences() {
$this->assertEquals(count($toobigvalue['gradesonly']) - 1, count($report1->collapsed['gradesonly']));
}

/**
* Test some special cases of the conversion from old preferences to new ones
*
* @covers \grade_report_grader::get_collapsed_preferences
* @covers \grade_report_grader::filter_collapsed_categories
*/
public function test_old_collapsed_preferences() {
$this->resetAfterTest(true);

$user1 = $this->getDataGenerator()->create_user();
$course1 = $this->getDataGenerator()->create_course();
$course2 = $this->getDataGenerator()->create_course();
$course3 = $this->getDataGenerator()->create_course();

$course1cats = $course2cats = $course3cats = [];
for ($i = 0; $i < 10; $i++) {
$course1cats[] = $this->create_grade_category($course1)->id;
$course2cats[] = $this->create_grade_category($course2)->id;
$course3cats[] = $this->create_grade_category($course3)->id;
}

$report1 = $this->create_report($course1);
// Collapse all the cats in course1.
foreach ($course1cats as $catid) {
$report1->process_action('cg'. $catid, 'switch_minus');
}

// Expand all the cats in course2.
$report2 = $this->create_report($course2);
foreach ($course2cats as $catid) {
$report2->process_action('cg'.$catid, 'switch_minus');
$report2->process_action('cg'.$catid, 'switch_plus');
}

// Collapse odd cats and expand even cats in course3.
$report3 = $this->create_report($course3);
foreach ($course3cats as $catid) {
$report3->process_action('cg'.$catid, 'switch_minus');
if (($i++) % 2) {
$report3->process_action('cg'.$catid, 'switch_plus');
}
}

$report1 = $this->create_report($course1);
$this->assertEquals(10, count($report1->collapsed['aggregatesonly']));
$this->assertEquals(0, count($report1->collapsed['gradesonly']));
$report2 = $this->create_report($course2);
$this->assertEquals(0, count($report2->collapsed['aggregatesonly']));
$this->assertEquals(10, count($report2->collapsed['gradesonly']));
$report3 = $this->create_report($course3);
$this->assertEquals(5, count($report3->collapsed['aggregatesonly']));
$this->assertEquals(5, count($report3->collapsed['gradesonly']));

// Use the preferences generated for user1 and set it in the old format for other users.

// User2: both gradesonly and aggregatesonly.
$user2 = $this->getDataGenerator()->create_user();
$alldata = [
'gradesonly' => array_merge(
$report1->collapsed['gradesonly'],
$report2->collapsed['gradesonly'],
$report3->collapsed['gradesonly']),
'aggregatesonly' => array_merge(
$report1->collapsed['aggregatesonly'],
$report2->collapsed['aggregatesonly'],
$report3->collapsed['aggregatesonly']),
];
set_user_preference('grade_report_grader_collapsed_categories', serialize($alldata), $user2);

$this->setUser($user2);
$convertedreport1 = $this->create_report($course1);
$this->assertEquals($report1->collapsed['gradesonly'], $convertedreport1->collapsed['gradesonly']);
$this->assertEquals($report1->collapsed['aggregatesonly'], $convertedreport1->collapsed['aggregatesonly']);
$newprefs1 = get_user_preferences('grade_report_grader_collapsed_categories' . $course1->id); // Also verify new prefs.
$this->assertEquals($report1->collapsed['gradesonly'], json_decode($newprefs1, true)['gradesonly']);
$this->assertEquals($report1->collapsed['aggregatesonly'], json_decode($newprefs1, true)['aggregatesonly']);

$convertedreport2 = $this->create_report($course2);
$this->assertEquals($report2->collapsed['gradesonly'], $convertedreport2->collapsed['gradesonly']);
$this->assertEquals($report2->collapsed['aggregatesonly'], $convertedreport2->collapsed['aggregatesonly']);
$newprefs2 = get_user_preferences('grade_report_grader_collapsed_categories' . $course2->id); // Also verify new prefs.
$this->assertEquals($report2->collapsed['gradesonly'], json_decode($newprefs2, true)['gradesonly']);
$this->assertEquals($report2->collapsed['aggregatesonly'], json_decode($newprefs2, true)['aggregatesonly']);

$convertedreport3 = $this->create_report($course3);
$this->assertEquals($report3->collapsed['gradesonly'], $convertedreport3->collapsed['gradesonly']);
$this->assertEquals($report3->collapsed['aggregatesonly'], $convertedreport3->collapsed['aggregatesonly']);
$newprefs3 = get_user_preferences('grade_report_grader_collapsed_categories' . $course3->id); // Also verify new prefs.
$this->assertEquals($report3->collapsed['gradesonly'], json_decode($newprefs3, true)['gradesonly']);
$this->assertEquals($report3->collapsed['aggregatesonly'], json_decode($newprefs3, true)['aggregatesonly']);

// Make sure the old style user preference is removed now.
$this->assertEmpty(get_user_preferences('grade_report_grader_collapsed_categories'));

// User3: only gradesonly (missing aggregatesonly).
$user3 = $this->getDataGenerator()->create_user();
$alldata = [
'gradesonly' => array_merge(
$report1->collapsed['gradesonly'],
$report2->collapsed['gradesonly'],
$report3->collapsed['gradesonly']),
];
set_user_preference('grade_report_grader_collapsed_categories', serialize($alldata), $user3);

$this->setUser($user3);
$convertedreport1 = $this->create_report($course1);
$this->assertEquals($report1->collapsed['gradesonly'], $convertedreport1->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport1->collapsed['aggregatesonly']);
$newprefs1 = get_user_preferences('grade_report_grader_collapsed_categories' . $course1->id); // Also verify new prefs.
$this->assertNull($newprefs1);

$convertedreport2 = $this->create_report($course2);
$this->assertEquals($report2->collapsed['gradesonly'], $convertedreport2->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport2->collapsed['aggregatesonly']);
$newprefs2 = get_user_preferences('grade_report_grader_collapsed_categories' . $course2->id); // Also verify new prefs.
$this->assertEquals($report2->collapsed['gradesonly'], json_decode($newprefs2, true)['gradesonly']);
$this->assertEquals([], json_decode($newprefs2, true)['aggregatesonly']);

$convertedreport3 = $this->create_report($course3);
$this->assertEquals($report3->collapsed['gradesonly'], $convertedreport3->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport3->collapsed['aggregatesonly']);
$newprefs3 = get_user_preferences('grade_report_grader_collapsed_categories' . $course3->id); // Also verify new prefs.
$this->assertEquals($report3->collapsed['gradesonly'], json_decode($newprefs3, true)['gradesonly']);
$this->assertEquals([], json_decode($newprefs3, true)['aggregatesonly']);

// Make sure the old style user preference is removed now.
$this->assertEmpty(get_user_preferences('grade_report_grader_collapsed_categories'));

// User4: only aggregatesonly (missing gradesonly).
$user4 = $this->getDataGenerator()->create_user();
$alldata = [
'aggregatesonly' => array_merge(
$report1->collapsed['aggregatesonly'],
$report2->collapsed['aggregatesonly'],
$report3->collapsed['aggregatesonly']),
];
set_user_preference('grade_report_grader_collapsed_categories', serialize($alldata), $user4);

$this->setUser($user4);
$convertedreport1 = $this->create_report($course1);
$this->assertEquals([], $convertedreport1->collapsed['gradesonly']);
$this->assertEquals($report1->collapsed['aggregatesonly'], $convertedreport1->collapsed['aggregatesonly']);
$newprefs1 = get_user_preferences('grade_report_grader_collapsed_categories' . $course1->id); // Also verify new prefs.
$this->assertEquals([], json_decode($newprefs1, true)['gradesonly']);
$this->assertEquals($report1->collapsed['aggregatesonly'], json_decode($newprefs1, true)['aggregatesonly']);

$convertedreport2 = $this->create_report($course2);
$this->assertEquals([], $convertedreport2->collapsed['gradesonly']);
$this->assertEquals($report2->collapsed['aggregatesonly'], $convertedreport2->collapsed['aggregatesonly']);
$newprefs2 = get_user_preferences('grade_report_grader_collapsed_categories' . $course2->id); // Also verify new prefs.
$this->assertNull($newprefs2);

$convertedreport3 = $this->create_report($course3);
$this->assertEquals([], $convertedreport3->collapsed['gradesonly']);
$this->assertEquals($report3->collapsed['aggregatesonly'], $convertedreport3->collapsed['aggregatesonly']);
$newprefs3 = get_user_preferences('grade_report_grader_collapsed_categories' . $course3->id); // Also verify new prefs.
$this->assertEquals([], json_decode($newprefs3, true)['gradesonly']);
$this->assertEquals($report3->collapsed['aggregatesonly'], json_decode($newprefs3, true)['aggregatesonly']);

// Make sure the old style user preference is removed now.
$this->assertEmpty(get_user_preferences('grade_report_grader_collapsed_categories'));

// User5: both missing gradesonly and aggregatesonly.
$user5 = $this->getDataGenerator()->create_user();
$alldata = [];
set_user_preference('grade_report_grader_collapsed_categories', serialize($alldata), $user5);

$this->setUser($user5);
$convertedreport1 = $this->create_report($course1);
$this->assertEquals([], $convertedreport1->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport1->collapsed['aggregatesonly']);
$newprefs1 = get_user_preferences('grade_report_grader_collapsed_categories' . $course1->id); // Also verify new prefs.
$this->assertNull($newprefs1);

$convertedreport2 = $this->create_report($course2);
$this->assertEquals([], $convertedreport2->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport2->collapsed['aggregatesonly']);
$newprefs2 = get_user_preferences('grade_report_grader_collapsed_categories' . $course2->id); // Also verify new prefs.
$this->assertNull($newprefs2);

$convertedreport3 = $this->create_report($course3);
$this->assertEquals([], $convertedreport3->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport3->collapsed['aggregatesonly']);
$newprefs3 = get_user_preferences('grade_report_grader_collapsed_categories' . $course3->id); // Also verify new prefs.
$this->assertNull($newprefs3);

// Make sure the old style user preference is removed now.
$this->assertEmpty(get_user_preferences('grade_report_grader_collapsed_categories'));

// User6: both empty gradesonly and aggregatesonly.
$user6 = $this->getDataGenerator()->create_user();
$alldata = [
'gradesonly' => [],
'aggregatesonly' => []
];
set_user_preference('grade_report_grader_collapsed_categories', serialize($alldata), $user6);

$this->setUser($user6);
$convertedreport1 = $this->create_report($course1);
$this->assertEquals([], $convertedreport1->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport1->collapsed['aggregatesonly']);
$newprefs1 = get_user_preferences('grade_report_grader_collapsed_categories' . $course1->id); // Also verify new prefs.
$this->assertNull($newprefs1);

$convertedreport2 = $this->create_report($course2);
$this->assertEquals([], $convertedreport2->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport2->collapsed['aggregatesonly']);
$newprefs2 = get_user_preferences('grade_report_grader_collapsed_categories' . $course2->id); // Also verify new prefs.
$this->assertNull($newprefs2);

$convertedreport3 = $this->create_report($course3);
$this->assertEquals([], $convertedreport3->collapsed['gradesonly']);
$this->assertEquals([], $convertedreport3->collapsed['aggregatesonly']);
$newprefs3 = get_user_preferences('grade_report_grader_collapsed_categories' . $course3->id); // Also verify new prefs.
$this->assertNull($newprefs3);

// Make sure the old style user preference is removed now.
$this->assertEmpty(get_user_preferences('grade_report_grader_collapsed_categories'));
}

/**
* Tests the get_right_rows function with one 'normal' and one 'ungraded' quiz.
*
Expand Down

0 comments on commit 3ec0b78

Please sign in to comment.