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
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, '');
|
|
}
|
|
}
|
|
|