You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1604 lines
79 KiB

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Data provider tests.
*
* @package core_grades
* @category test
* @copyright 2018 Frédéric Massart
* @author Frédéric Massart <fred@branchup.tech>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
use core_privacy\tests\provider_testcase;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\transform;
use core_privacy\local\request\writer;
use core_grades\privacy\provider;
require_once($CFG->libdir . '/gradelib.php');
/**
* Data provider testcase class.
*
* @package core_grades
* @category test
* @copyright 2018 Frédéric Massart
* @author Frédéric Massart <fred@branchup.tech>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_grades_privacy_testcase extends provider_testcase {
public function setUp() {
global $PAGE;
$this->resetAfterTest();
$PAGE->get_renderer('core');
}
public function test_get_contexts_for_userid_gradebook_edits() {
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u5 = $dg->create_user();
$u6 = $dg->create_user();
$u7 = $dg->create_user();
$u8 = $dg->create_user();
$u9 = $dg->create_user();
$u10 = $dg->create_user();
$u11 = $dg->create_user();
$sysctx = context_system::instance();
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
$go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
'fullname' => 'go2']), false);
// Nothing as of now.
foreach ([$u1, $u2, $u3, $u4, $u5, $u6, $u7, $u8, $u9, $u10, $u11] as $u) {
$contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids());
$this->assertEmpty($contexts);
}
$go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
$go0->insert();
$go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]);
$go1->insert();
// Create scales.
$s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
$s1->insert();
$s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
$s2->insert();
// User 2 creates history.
$this->setUser($u2);
$go0->shortname .= ' edited';
$go0->update();
$gc1a->fullname .= ' edited';
$gc1a->update();
// User 3 creates history.
$this->setUser($u3);
$go1->shortname .= ' edited';
$go1->update();
$gc2a->fullname .= ' a';
$gc2a->update();
// User 4 updates an outcome in course (creates history).
$this->setUser($u4);
$go2->shortname .= ' edited';
$go2->update();
// User 5 updates an item.
$this->setUser($u5);
$gi1a->itemname .= ' edited';
$gi1a->update();
// User 6 creates history.
$this->setUser($u6);
$gi2a->delete();
// User 9 creates history.
$this->setUser($u9);
$s1->name .= ' edited';
$s1->update();
// Assert contexts.
$contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($sysctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u11->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids());
$this->assertCount(2, $contexts);
$this->assertArrayHasKey($sysctx->id, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids());
$this->assertCount(2, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$this->assertArrayHasKey($c2ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c2ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c2ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u7->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($sysctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u8->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u9->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($sysctx->id, $contexts);
// User 10 creates history.
$this->setUser($u10);
$s2->delete();
$contexts = array_flip(provider::get_contexts_for_userid($u10->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
}
public function test_get_contexts_for_userid_grades_and_history() {
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u5 = $dg->create_user();
$u6 = $dg->create_user();
$sysctx = context_system::instance();
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
// Nothing as of now.
foreach ([$u1, $u2, $u3, $u4, $u5, $u6] as $u) {
$contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids());
$this->assertEmpty($contexts);
}
// User 1 is graded in course 1.
$gi1a->update_final_grade($u1->id, 1, 'test');
// User 2 is graded in course 2.
$gi2a->update_final_grade($u2->id, 10, 'test');
// User 3 is set as modifier.
$gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id);
// User 4 is set as modifier, and creates history..
$this->setUser($u4);
$gi1a->update_final_grade($u2->id, 1, 'test');
// User 5 creates history, user 6 is the known modifier, and we delete the item.
$this->setUser($u5);
$gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id);
$gi2b->delete();
// Assert contexts.
$contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids());
$this->assertCount(3, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$this->assertArrayHasKey($c2ctx->id, $contexts);
$this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey($c1ctx->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids());
$this->assertCount(2, $contexts);
$this->assertArrayHasKey($c2ctx->id, $contexts);
$this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts);
$contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids());
$this->assertCount(1, $contexts);
$this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts);
}
/**
* Test that the appropriate user IDs are returned for a given context.
*/
public function test_get_users_in_context_gradebook_edits() {
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u5 = $dg->create_user();
$u6 = $dg->create_user();
$u7 = $dg->create_user();
$u8 = $dg->create_user();
$u9 = $dg->create_user();
$u10 = $dg->create_user();
$u11 = $dg->create_user();
$sysctx = context_system::instance();
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
$go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
'fullname' => 'go2']), false);
$go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
$go0->insert();
$go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]);
$go1->insert();
// Create scales.
$s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
$s1->insert();
$s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
$s2->insert();
// User 2 creates history.
$this->setUser($u2);
$go0->shortname .= ' edited';
$go0->update();
$gc1a->fullname .= ' edited';
$gc1a->update();
// User 3 creates history.
$this->setUser($u3);
$go1->shortname .= ' edited';
$go1->update();
$gc2a->fullname .= ' a';
$gc2a->update();
// User 4 updates an outcome in course (creates history).
$this->setUser($u4);
$go2->shortname .= ' edited';
$go2->update();
// User 5 updates an item.
$this->setUser($u5);
$gi1a->itemname .= ' edited';
$gi1a->update();
// User 6 creates history.
$this->setUser($u6);
$gi2a->delete();
// User 9 creates history.
$this->setUser($u9);
$s1->name .= ' edited';
$s1->update();
$userlist = new \core_privacy\local\request\userlist($sysctx, 'core_grades');
provider::get_users_in_context($userlist);
$systemcontextuserids = [$u1->id, $u2->id, $u7->id, $u9->id];
$this->assertEquals($systemcontextuserids, $userlist->get_userids());
$userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades');
provider::get_users_in_context($userlist);
$course1userids = [$u11->id, $u3->id, $u8->id, $u5->id, $u2->id];
$this->assertEquals($course1userids, $userlist->get_userids());
$userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades');
provider::get_users_in_context($userlist);
$course2userids = [$u4->id, $u6->id, $u3->id];
$this->assertEquals($course2userids, $userlist->get_userids());
}
/**
* Test that the appropriate user IDs are returned for a given context.
*/
public function test_get_users_in_context_grades_and_history() {
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u5 = $dg->create_user();
$u6 = $dg->create_user();
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
$u2ctx = context_user::instance($u2->id);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
// User 1 is graded in course 1.
$gi1a->update_final_grade($u1->id, 1, 'test');
// User 2 is graded in course 2.
$gi2a->update_final_grade($u2->id, 10, 'test');
// User 3 is set as modifier.
$gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id);
// User 4 is set as modifier, and creates history..
$this->setUser($u4);
$gi1a->update_final_grade($u2->id, 1, 'test');
// User 5 creates history, user 6 is the known modifier, and we delete the item.
$this->setUser($u5);
$gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id);
$gi2b->delete();
$userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades');
provider::get_users_in_context($userlist);
$course1userids = [$u1->id, $u2->id, $u3->id, $u4->id];
$this->assertEquals($course1userids, $userlist->get_userids(), '', 0.0, 10, true);
$userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades');
provider::get_users_in_context($userlist);
$course2userids = [$u5->id, $u2->id];
$this->assertEquals($course2userids, $userlist->get_userids(), '', 0.0, 10, true);
$userlist = new \core_privacy\local\request\userlist($u2ctx, 'core_grades');
provider::get_users_in_context($userlist);
$this->assertEquals([$u2->id], $userlist->get_userids());
}
public function test_delete_data_for_all_users_in_context() {
global $DB;
$fs = new file_storage();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u1ctx = context_user::instance($u1->id);
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
$a1 = $dg->create_module('assign', ['course' => $c1->id]);
$a2 = $dg->create_module('assign', ['course' => $c1->id]);
$a3 = $dg->create_module('assign', ['course' => $c2->id]);
$a4 = $dg->create_module('assign', ['course' => $c2->id]);
$a1context = context_module::instance($a1->cmid);
$a2context = context_module::instance($a2->cmid);
$a3context = context_module::instance($a3->cmid);
$a4context = context_module::instance($a4->cmid);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(
[
'courseid' => $c1->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a1->id
]
), false);
$gi1b = new grade_item($dg->create_grade_item(
[
'courseid' => $c1->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a2->id
]
), false);
$gi2a = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a3->id
]
), false);
$gi2b = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a4->id
]
), false);
$this->add_feedback_file_to_copy();
$grades['feedback'] = 'Nice feedback!';
$grades['feedbackformat'] = FORMAT_MOODLE;
$grades['feedbackfiles'] = [
'contextid' => 1,
'component' => 'test',
'filearea' => 'testarea',
'itemid' => 1
];
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
$gi1a->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
$gi1a->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance,
$gi1b->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
$gi2a->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
$gi2a->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
$gi2b->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
$gi2b->itemnumber, $grades);
$gi2b->delete();
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
provider::delete_data_for_all_users_in_context($c1ctx);
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
provider::delete_data_for_all_users_in_context($u1ctx);
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// The user context is only reported when there are orphan historical grades, so we only delete those files.
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// User 2 still has historical files.
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
provider::delete_data_for_all_users_in_context($c2ctx);
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
}
public function test_delete_data_for_user() {
global $DB;
$fs = new file_storage();
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u1ctx = context_user::instance($u1->id);
$u2ctx = context_user::instance($u2->id);
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
$a1 = $dg->create_module('assign', ['course' => $c1->id]);
$a2 = $dg->create_module('assign', ['course' => $c1->id]);
$a3 = $dg->create_module('assign', ['course' => $c2->id]);
$a4 = $dg->create_module('assign', ['course' => $c2->id]);
$a1context = context_module::instance($a1->cmid);
$a2context = context_module::instance($a2->cmid);
$a3context = context_module::instance($a3->cmid);
$a4context = context_module::instance($a4->cmid);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(
[
'courseid' => $c1->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a1->id
]
), false);
$gi1b = new grade_item($dg->create_grade_item(
[
'courseid' => $c1->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a2->id
]
), false);
$gi2a = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a3->id
]
), false);
$gi2b = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a4->id
]
), false);
$this->add_feedback_file_to_copy();
$grades['feedback'] = 'Nice feedback!';
$grades['feedbackfiles'] = [
'contextid' => 1,
'component' => 'test',
'filearea' => 'testarea',
'itemid' => 1
];
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
$gi1a->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance,
$gi1a->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance,
$gi1b->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
$gi2a->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
$gi2a->itemnumber, $grades);
$grades['userid'] = $u1->id;
grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
$gi2b->itemnumber, $grades);
$grades['userid'] = $u2->id;
grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
$gi2b->itemnumber, $grades);
$gi2b->delete();
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$c1ctx->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u1ctx->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(4, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u2ctx->id, $c2ctx->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
// Feedback file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
// History file area.
$files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
$files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
$files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(2, count($files));
// Grade item 2 was deleted, so the associated files were as well.
$files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA);
$this->assertEquals(0, count($files));
}
/**
* Test deleting multiple users for a context works.
*/
public function test_delete_data_for_users() {
global $DB;
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u1ctx = context_user::instance($u1->id);
$u2ctx = context_user::instance($u2->id);
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gi1a->update_final_grade($u1->id, 1, 'test');
$gi1a->update_final_grade($u2->id, 1, 'test');
$gi1a->update_final_grade($u3->id, 1, 'test');
$gi1b->update_final_grade($u1->id, 1, 'test');
$gi1b->update_final_grade($u4->id, 1, 'test');
$gi2a->update_final_grade($u1->id, 1, 'test');
$gi2a->update_final_grade($u2->id, 1, 'test');
$gi2a->update_final_grade($u4->id, 1, 'test');
$gi2b->update_final_grade($u1->id, 1, 'test');
$gi2b->update_final_grade($u2->id, 1, 'test');
$gi2b->update_final_grade($u3->id, 1, 'test');
$gi2b->delete();
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2b->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2b->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi2b->id]));
$userlist = new \core_privacy\local\request\approved_userlist($c1ctx, 'core_grades', [$u1->id, $u2->id]);
provider::delete_data_for_users($userlist);
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
$userlist = new \core_privacy\local\request\approved_userlist($c2ctx, 'core_grades', [$u2->id, $u4->id]);
provider::delete_data_for_users($userlist);
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id]));
$this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id]));
$this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id]));
}
public function test_export_data_for_user_about_grades_and_history() {
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
// Users being graded.
$ug1 = $dg->create_user();
$ug2 = $dg->create_user();
$ug3 = $dg->create_user();
// Users performing actions.
$ua1 = $dg->create_user();
$ua2 = $dg->create_user();
$ua3 = $dg->create_user();
$ug1ctx = context_user::instance($ug1->id);
$ug2ctx = context_user::instance($ug2->id);
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
$rootpath = [get_string('grades', 'core_grades')];
$relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
// Create the course minimal stuff.
grade_category::fetch_course_category($c1->id);
$ci1 = grade_item::fetch_course_item($c1->id);
grade_category::fetch_course_category($c2->id);
$ci2 = grade_item::fetch_course_item($c2->id);
$this->add_feedback_file_to_copy();
$grades['feedbackfiles'] = [
'contextid' => 1,
'component' => 'test',
'filearea' => 'testarea',
'itemid' => 1
];
$a1 = $dg->create_module('assign', ['course' => $c1->id]);
// Create data that will sit in the user context because we will delete the grate item.
$gi1 = new grade_item($dg->create_grade_item(
[
'courseid' => $c1->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a1->id,
'aggregationcoef2' => 1
]
), false);
$grades['feedback'] = 'Well done!';
$grades['feedbackformat'] = FORMAT_PLAIN;
$grades['userid'] = $ug1->id;
$grades['usermodified'] = $ua2->id;
$grades['rawgrade'] = 100;
grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
$gi1->itemnumber, $grades);
$grades['feedback'] = 'Hi';
$grades['userid'] = $ug1->id;
$grades['usermodified'] = $ua2->id;
$grades['rawgrade'] = 1;
grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
$gi1->itemnumber, $grades);
$grades['feedback'] = 'Hello';
$grades['userid'] = $ug3->id;
$grades['usermodified'] = $ua2->id;
$grades['rawgrade'] = 12;
grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance,
$gi1->itemnumber, $grades);
// Create another set for another user.
$a2 = $dg->create_module('assign', ['course' => $c2->id]);
$a3 = $dg->create_module('assign', ['course' => $c2->id]);
$gi2a = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a2->id
]
), false);
$gi2b = new grade_item($dg->create_grade_item(
[
'courseid' => $c2->id,
'itemtype' => 'mod',
'itemmodule' => 'assign',
'iteminstance' => $a3->id
]
), false);
$grades['feedback'] = '';
$grades['userid'] = $ug1->id;
$grades['usermodified'] = $ua2->id;
$grades['rawgrade'] = 15;
grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance,
$gi2a->itemnumber, $grades);
$grades['feedback'] = 'Well played!';
$grades['userid'] = $ug1->id;
$grades['usermodified'] = $ua2->id;
$grades['rawgrade'] = 30;
grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance,
$gi2b->itemnumber, $grades);
// Export action user 1 everywhere.
provider::export_user_data(new approved_contextlist($ua1, 'core_grades', [$ug1ctx->id, $ug2ctx->id,
$c1ctx->id, $c2ctx->id]));
$this->assert_context_has_no_data($ug1ctx);
$this->assert_context_has_no_data($ug2ctx);
$this->assert_context_has_no_data($c1ctx);
$this->assert_context_has_no_data($c2ctx);
// Export action user 2 in course 1.
writer::reset();
provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$c1ctx->id]));
$this->assert_context_has_no_data($ug1ctx);
$this->assert_context_has_no_data($ug2ctx);
$this->assert_context_has_no_data($c2ctx);
$data = writer::with_context($c1ctx)->get_data($rootpath);
$this->assertEmpty($data);
// Here we are testing the export of grades that we've changed.
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades');
$this->assertCount(2, $data->grades);
$this->assertEquals($gi1->get_name(), $data->grades[0]['item']);
$this->assertEquals(1, $data->grades[0]['grade']);
$this->assertEquals('Hi', $data->grades[0]['feedback']);
$this->assertEquals(transform::yesno(true), $data->grades[0]['created_or_modified_by_you']);
$this->assertEquals($gi1->get_name(), $data->grades[1]['item']);
$this->assertEquals(12, $data->grades[1]['grade']);
$this->assertEquals('Hello', $data->grades[1]['feedback']);
$this->assertEquals(transform::yesno(true), $data->grades[1]['created_or_modified_by_you']);
$pathtofiles = [
get_string('grades', 'core_grades'),
get_string('feedbackfiles', 'core_grades')
];
$file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt'];
$this->assertInstanceOf('stored_file', $file);
$this->assertEquals('feedback1.txt', $file->get_filename());
$relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
// Here we are testing the export of history of grades that we've changed.
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history');
$this->assertCount(3, $data->modified_records);
$grade = $data->modified_records[0];
$this->assertEquals($ug1->id, $grade['userid']);
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(100, $grade['grade']);
$this->assertEquals('Well done!', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$grade = $data->modified_records[1];
$this->assertEquals($ug1->id, $grade['userid']);
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$grade = $data->modified_records[2];
$this->assertEquals($ug3->id, $grade['userid']);
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(12, $grade['grade']);
$this->assertEquals('Hello', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$pathtofiles = [
get_string('grades', 'core_grades'),
get_string('feedbackhistoryfiles', 'core_grades')
];
$file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt'];
$this->assertInstanceOf('stored_file', $file);
$this->assertEquals('feedback1.txt', $file->get_filename());
// Create a history record with logged user.
$this->setUser($ua3);
$gi1->update_final_grade($ug3->id, 50, 'test', '...', FORMAT_PLAIN, $ua2->id);
writer::reset();
provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$c1ctx->id]));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history');
$this->assertCount(1, $data->modified_records);
$grade = $data->modified_records[0];
$this->assertEquals($ug3->id, $grade['userid']);
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(50, $grade['grade']);
$this->assertEquals('...', $grade['feedback']);
$this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
// Test that we export our own grades.
writer::reset();
provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$c1ctx->id]));
$data = writer::with_context($c1ctx)->get_data($rootpath);
$this->assert_context_has_no_data($c2ctx);
$this->assertCount(3, $data->grades);
$grade = $data->grades[0];
$this->assertEquals($ci1->get_name(), $grade['item']);
$this->assertEquals(1, $grade['grade']);
$grade = $data->grades[2];
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
// Test that we export our own grades in two courses.
writer::reset();
provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id]));
$this->assert_context_has_no_data($ug1ctx);
$data = writer::with_context($c1ctx)->get_data($rootpath);
$this->assertCount(3, $data->grades);
$grade = $data->grades[0];
$this->assertEquals($ci1->get_name(), $grade['item']);
$this->assertEquals(1, $grade['grade']);
$grade = $data->grades[2];
$this->assertEquals($gi1->get_name(), $grade['item']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$data = writer::with_context($c2ctx)->get_data($rootpath);
$this->assertCount(5, $data->grades);
$grade = $data->grades[0];
$this->assertEquals($ci2->get_name(), $grade['item']);
$grade = $data->grades[3];
$this->assertEquals($gi2a->get_name(), $grade['item']);
$this->assertEquals(15, $grade['grade']);
$this->assertEquals('', $grade['feedback']);
$grade = $data->grades[4];
$this->assertEquals($gi2b->get_name(), $grade['item']);
$this->assertEquals(30, $grade['grade']);
$this->assertEquals('Well played!', $grade['feedback']);
// Delete a grade item.
$this->setUser($ua3);
$gi1->delete();
// Now, we should find history of grades in our own context.
writer::reset();
provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id]));
$data = writer::with_context($c1ctx)->get_data($rootpath);
$this->assertCount(2, $data->grades);
$this->assertEquals($ci1->get_name(), $data->grades[0]['item']);
$data = writer::with_context($c2ctx)->get_data($rootpath);
$this->assertCount(5, $data->grades);
$data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
$this->assertCount(3, $data->grades);
$grade = $data->grades[0];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(100, $grade['grade']);
$this->assertEquals('Well done!', $grade['feedback']);
$this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']);
$grade = $data->grades[1];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']);
$grade = $data->grades[2];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
// The action user 3 should have a record of the deletion in the user's context.
writer::reset();
provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$ug1ctx->id]));
$data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
$this->assertCount(1, $data->grades);
$grade = $data->grades[0];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
// The action user 2 should have a record of their edits in the user's context.
writer::reset();
provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$ug1ctx->id]));
$data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history');
$this->assertCount(3, $data->grades);
$grade = $data->grades[0];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(100, $grade['grade']);
$this->assertEquals('Well done!', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']);
$grade = $data->grades[1];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']);
$grade = $data->grades[2];
$this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']);
$this->assertEquals(1, $grade['grade']);
$this->assertEquals('Hi', $grade['feedback']);
$this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']);
$this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']);
}
public function test_export_data_for_user_with_scale() {
global $DB;
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$scale = $dg->create_scale(['scale' => 'Awesome,OK,Reasonable,Bad']);
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u1ctx = context_user::instance($u1->id);
$c1ctx = context_course::instance($c1->id);
$rootpath = [get_string('grades', 'core_grades')];
// Create another set for another user.
$gi1 = new grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false);
$gi1->update_final_grade($u1->id, 1, 'test', '', FORMAT_PLAIN, $u2->id);
$gi2 = new grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false);
$gi2->update_final_grade($u1->id, 3, 'test', '', FORMAT_PLAIN, $u2->id);
// Export user's data.
writer::reset();
provider::export_user_data(new approved_contextlist($u1, 'core_grades', [$c1ctx->id]));
$data = writer::with_context($c1ctx)->get_data($rootpath);
$this->assertCount(3, $data->grades);
$this->assertEquals(grade_item::fetch_course_item($c1->id)->get_name(), $data->grades[0]['item']);
$this->assertEquals($gi1->get_name(), $data->grades[1]['item']);
$this->assertEquals(1, $data->grades[1]['grade']);
$this->assertEquals('Awesome', $data->grades[1]['grade_formatted']);
$this->assertEquals($gi2->get_name(), $data->grades[2]['item']);
$this->assertEquals(3, $data->grades[2]['grade']);
$this->assertEquals('Reasonable', $data->grades[2]['grade_formatted']);
}
public function test_export_data_for_user_about_gradebook_edits() {
global $DB;
$dg = $this->getDataGenerator();
$c1 = $dg->create_course();
$c2 = $dg->create_course();
$u1 = $dg->create_user();
$u2 = $dg->create_user();
$u3 = $dg->create_user();
$u4 = $dg->create_user();
$u5 = $dg->create_user();
$u6 = $dg->create_user();
$u7 = $dg->create_user();
$u8 = $dg->create_user();
$u9 = $dg->create_user();
$u10 = $dg->create_user();
$sysctx = context_system::instance();
$u1ctx = context_user::instance($u1->id);
$u2ctx = context_user::instance($u2->id);
$u3ctx = context_user::instance($u3->id);
$u4ctx = context_user::instance($u4->id);
$u5ctx = context_user::instance($u5->id);
$u6ctx = context_user::instance($u6->id);
$c1ctx = context_course::instance($c1->id);
$c2ctx = context_course::instance($c2->id);
$rootpath = [get_string('grades', 'core_grades')];
$relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
$allcontexts = [$sysctx->id, $c1ctx->id, $c2ctx->id, $u1ctx->id, $u2ctx->id, $u3ctx->id, $u4ctx->id,
$u5ctx->id, $u6ctx->id];
$updateactionstr = get_string('privacy:request:historyactionupdate', 'core_grades');
// Create some stuff.
$gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false);
$gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false);
$gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false);
$gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false);
$go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2',
'fullname' => 'go2']), false);
$go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]);
$go0->insert();
$go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u1->id]);
$go1->insert();
// Create scales.
$s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']);
$s1->insert();
$s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']);
$s2->insert();
$s3 = new grade_scale(['name' => 's3', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c2->id, 'description' => '']);
$s3->insert();
// User 2 creates history.
$this->setUser($u2);
$go0->shortname .= ' edited';
$go0->update();
$gc1a->fullname .= ' edited';
$gc1a->update();
// User 3 creates history.
$this->setUser($u3);
$go1->shortname .= ' edited';
$go1->update();
$gc2a->fullname .= ' a';
$gc2a->update();
// User 4 updates an outcome in course (creates history).
$this->setUser($u4);
$go2->shortname .= ' edited';
$go2->update();
// User 5 updates an item.
$this->setUser($u5);
$gi1a->itemname .= ' edited';
$gi1a->update();
// User 6 creates history.
$this->setUser($u6);
$gi2a->delete();
// User 9 creates history.
$this->setUser($u9);
$s1->name .= ' edited';
$s1->update();
// User 10 creates history.
$this->setUser($u10);
$s3->delete();
$this->setAdminUser();
// Export data for u1.
writer::reset();
provider::export_user_data(new approved_contextlist($u1, 'core_grades', $allcontexts));
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes');
$this->assertCount(1, $data->outcomes);
$this->assertEquals($go0->shortname, $data->outcomes[0]['shortname']);
$this->assertEquals($go0->fullname, $data->outcomes[0]['fullname']);
$this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes');
$this->assertCount(1, $data->outcomes);
$this->assertEquals($go1->shortname, $data->outcomes[0]['shortname']);
$this->assertEquals($go1->fullname, $data->outcomes[0]['fullname']);
$this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history');
$this->assertEmpty($data);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history');
$this->assertEmpty($data);
// Export data for u2.
writer::reset();
provider::export_user_data(new approved_contextlist($u2, 'core_grades', $allcontexts));
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes');
$this->assertEmpty($data);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($go0->shortname, $data->modified_records[0]['shortname']);
$this->assertEquals($go0->fullname, $data->modified_records[0]['fullname']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'categories_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($gc1a->fullname, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
// Export data for u3.
writer::reset();
provider::export_user_data(new approved_contextlist($u3, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($go1->shortname, $data->modified_records[0]['shortname']);
$this->assertEquals($go1->fullname, $data->modified_records[0]['fullname']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'categories_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($gc2a->fullname, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
// Export data for u4.
writer::reset();
provider::export_user_data(new approved_contextlist($u4, 'core_grades', $allcontexts));
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'outcomes_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($go2->shortname, $data->modified_records[0]['shortname']);
$this->assertEquals($go2->fullname, $data->modified_records[0]['fullname']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
// Export data for u5.
writer::reset();
provider::export_user_data(new approved_contextlist($u5, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($gi1a->itemname, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals($updateactionstr, $data->modified_records[0]['action']);
// Export data for u6.
writer::reset();
provider::export_user_data(new approved_contextlist($u6, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history');
$this->assertEmpty($data);
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'items_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($gi2a->itemname, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
$data->modified_records[0]['action']);
// Export data for u7.
writer::reset();
provider::export_user_data(new approved_contextlist($u7, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
$this->assertCount(1, $data->scales);
$this->assertEquals($s1->name, $data->scales[0]['name']);
$this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']);
// Export data for u8.
writer::reset();
provider::export_user_data(new approved_contextlist($u8, 'core_grades', $allcontexts));
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
$this->assertCount(1, $data->scales);
$this->assertEquals($s2->name, $data->scales[0]['name']);
$this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']);
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history');
$this->assertCount(2, $data->modified_records);
$this->assertEquals($s3->name, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_change_was_you']);
$this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_action_was_you']);
$this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'),
$data->modified_records[0]['action']);
$this->assertEquals($s3->name, $data->modified_records[1]['name']);
$this->assertEquals(transform::yesno(true), $data->modified_records[1]['author_of_change_was_you']);
$this->assertEquals(transform::yesno(false), $data->modified_records[1]['author_of_action_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
$data->modified_records[1]['action']);
// Export data for u9.
writer::reset();
provider::export_user_data(new approved_contextlist($u9, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($s1->name, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']);
$this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'),
$data->modified_records[0]['action']);
// Export data for u10.
writer::reset();
provider::export_user_data(new approved_contextlist($u10, 'core_grades', $allcontexts));
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales');
$this->assertEmpty($data);
$data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales_history');
$this->assertEmpty($data);
$data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history');
$this->assertEmpty($data);
$data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history');
$this->assertCount(1, $data->modified_records);
$this->assertEquals($s3->name, $data->modified_records[0]['name']);
$this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']);
$this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']);
$this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'),
$data->modified_records[0]['action']);
}
/**
* Assert there is no grade data in the context.
*
* @param context $context The context.
* @return void
*/
protected function assert_context_has_no_data(context $context) {
$rootpath = [get_string('grades', 'core_grades')];
$relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]);
$data = writer::with_context($context)->get_data($rootpath);
$this->assertEmpty($data);
$data = writer::with_context($context)->get_related_data($rootpath, 'history');
$this->assertEmpty($data);
$files = ['categories_history', 'items_history', 'outcomes', 'outcomes_history', 'grades', 'grades_history', 'history'];
foreach ($files as $file) {
$data = writer::with_context($context)->get_related_data($relatedtomepath, $file);
$this->assertEmpty($data);
}
}
/**
* Creates a feedback file to copy to the gradebook area.
*/
private function add_feedback_file_to_copy() {
$dummy = array(
'contextid' => 1,
'component' => 'test',
'filearea' => 'testarea',
'itemid' => 1,
'filepath' => '/',
'filename' => 'feedback1.txt'
);
$fs = get_file_storage();
$fs->create_file_from_string($dummy, '');
}
}