mirror of
https://github.com/moodle/moodle.git
synced 2025-01-29 19:50:14 +01:00
Merge branch 'MDL-63564-master' of git://github.com/mihailges/moodle
This commit is contained in:
commit
5b2856864d
@ -23,6 +23,8 @@
|
||||
*/
|
||||
namespace mod_quiz\privacy;
|
||||
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
@ -63,4 +65,13 @@ trait legacy_quizaccess_polyfill {
|
||||
public static function delete_quizaccess_data_for_user(\quiz $quiz, \stdClass $user) {
|
||||
static::_delete_quizaccess_data_for_user($quiz, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all user data for the specified users, in the specified context.
|
||||
*
|
||||
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||
*/
|
||||
public static function delete_quizaccess_data_for_users(approved_userlist $userlist) {
|
||||
static::_delete_quizaccess_data_for_users($userlist);
|
||||
}
|
||||
}
|
||||
|
@ -18,19 +18,22 @@
|
||||
* Privacy Subsystem implementation for mod_quiz.
|
||||
*
|
||||
* @package mod_quiz
|
||||
* @category privacy
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_quiz\privacy;
|
||||
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\request\transform;
|
||||
use \core_privacy\local\request\contextlist;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use \core_privacy\local\request\deletion_criteria;
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\manager;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
use core_privacy\local\request\contextlist;
|
||||
use core_privacy\local\request\deletion_criteria;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\metadata\collection;
|
||||
use core_privacy\local\request\userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
use core_privacy\manager;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -48,7 +51,10 @@ class provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
|
||||
// This plugin currently implements the original plugin_provider interface.
|
||||
\core_privacy\local\request\plugin\provider {
|
||||
\core_privacy\local\request\plugin\provider,
|
||||
|
||||
// This plugin is capable of determining which users have data within it.
|
||||
\core_privacy\local\request\core_userlist_provider {
|
||||
|
||||
/**
|
||||
* Get the list of contexts that contain user information for the specified user.
|
||||
@ -176,6 +182,52 @@ class provider implements
|
||||
return $resultset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of users who have data within a context.
|
||||
*
|
||||
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
|
||||
*/
|
||||
public static function get_users_in_context(userlist $userlist) {
|
||||
$context = $userlist->get_context();
|
||||
|
||||
if (!$context instanceof \context_module) {
|
||||
return;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'cmid' => $context->instanceid,
|
||||
'modname' => 'quiz',
|
||||
];
|
||||
|
||||
// Users who attempted the quiz.
|
||||
$sql = "SELECT qa.userid
|
||||
FROM {course_modules} cm
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
|
||||
JOIN {quiz} q ON q.id = cm.instance
|
||||
JOIN {quiz_attempts} qa ON qa.quiz = q.id
|
||||
WHERE cm.id = :cmid AND qa.preview = 0";
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
|
||||
// Users with quiz overrides.
|
||||
$sql = "SELECT qo.userid
|
||||
FROM {course_modules} cm
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
|
||||
JOIN {quiz} q ON q.id = cm.instance
|
||||
JOIN {quiz_overrides} qo ON qo.quiz = q.id
|
||||
WHERE cm.id = :cmid";
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
|
||||
// Question usages in context.
|
||||
// This includes where a user is the manual marker on a question attempt.
|
||||
$sql = "SELECT qa.uniqueid
|
||||
FROM {course_modules} cm
|
||||
JOIN {modules} m ON m.id = cm.module AND m.name = :modname
|
||||
JOIN {quiz} q ON q.id = cm.instance
|
||||
JOIN {quiz_attempts} qa ON qa.quiz = q.id
|
||||
WHERE cm.id = :cmid AND qa.preview = 0";
|
||||
\core_question\privacy\provider::get_users_in_context_from_sql($userlist, 'qn', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -366,6 +418,56 @@ class provider implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple users within a single context.
|
||||
*
|
||||
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||
*/
|
||||
public static function delete_data_for_users(approved_userlist $userlist) {
|
||||
global $DB;
|
||||
|
||||
$context = $userlist->get_context();
|
||||
|
||||
if ($context->contextlevel != CONTEXT_MODULE) {
|
||||
// Only quiz module will be handled.
|
||||
return;
|
||||
}
|
||||
|
||||
$cm = get_coursemodule_from_id('quiz', $context->instanceid);
|
||||
if (!$cm) {
|
||||
// Only quiz module will be handled.
|
||||
return;
|
||||
}
|
||||
|
||||
$quizobj = \quiz::create($cm->instance);
|
||||
$quiz = $quizobj->get_quiz();
|
||||
|
||||
$userids = $userlist->get_userids();
|
||||
|
||||
// Handle the 'quizaccess' quizaccess.
|
||||
manager::plugintype_class_callback(
|
||||
'quizaccess',
|
||||
quizaccess_user_provider::class,
|
||||
'delete_quizaccess_data_for_users',
|
||||
[$userlist]
|
||||
);
|
||||
|
||||
foreach ($userids as $userid) {
|
||||
// Remove overrides for this user.
|
||||
$overrides = $DB->get_records('quiz_overrides' , [
|
||||
'quiz' => $quizobj->get_quizid(),
|
||||
'userid' => $userid,
|
||||
]);
|
||||
|
||||
foreach ($overrides as $override) {
|
||||
quiz_delete_override($quiz, $override->id, false);
|
||||
}
|
||||
|
||||
// This will delete all question attempts, quiz attempts, and quiz grades for this user in the given quiz.
|
||||
quiz_delete_user_attempts($quizobj, (object)['id' => $userid]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store all quiz attempts for the contextlist.
|
||||
*
|
||||
|
41
mod/quiz/classes/privacy/quizaccess_user_provider.php
Normal file
41
mod/quiz/classes/privacy/quizaccess_user_provider.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* The quizaccess_user_provider interface provides the expected interface for all 'quizaccess' quizaccesss.
|
||||
*
|
||||
* Quiz sub plugins should implement this if they store personal information and can retrieve a userid.
|
||||
*
|
||||
* @package mod_quiz
|
||||
* @copyright 2018 Shamim Rezaie <shamim@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace mod_quiz\privacy;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
|
||||
interface quizaccess_user_provider extends \core_privacy\local\request\plugin\subplugin_provider {
|
||||
|
||||
/**
|
||||
* Delete multiple users data within a single context.
|
||||
*
|
||||
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||
*/
|
||||
public static function delete_quizaccess_data_for_users(approved_userlist $userlist);
|
||||
}
|
@ -73,7 +73,7 @@ class core_privacy_legacy_quizaccess_polyfill_test extends advanced_testcase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the _delete_quizaccess_for_context shim.
|
||||
* Test the _delete_quizaccess_for_user shim.
|
||||
*/
|
||||
public function test_delete_quizaccess_for_user() {
|
||||
$context = context_system::instance();
|
||||
@ -89,6 +89,23 @@ class core_privacy_legacy_quizaccess_polyfill_test extends advanced_testcase {
|
||||
test_privacy_legacy_quizaccess_polyfill_provider::$mock = $mock;
|
||||
test_privacy_legacy_quizaccess_polyfill_provider::delete_quizaccess_data_for_user($quiz, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the _delete_quizaccess_for_users shim.
|
||||
*/
|
||||
public function test_delete_quizaccess_for_users() {
|
||||
$context = $this->createMock(context_module::class);
|
||||
$user = (object) [];
|
||||
$approveduserlist = new \core_privacy\local\request\approved_userlist($context, 'mod_quiz', [$user]);
|
||||
|
||||
$mock = $this->createMock(test_privacy_legacy_quizaccess_polyfill_mock_wrapper::class);
|
||||
$mock->expects($this->once())
|
||||
->method('get_return_value')
|
||||
->with('_delete_quizaccess_data_for_users', [$approveduserlist]);
|
||||
|
||||
test_privacy_legacy_quizaccess_polyfill_provider::$mock = $mock;
|
||||
test_privacy_legacy_quizaccess_polyfill_provider::delete_quizaccess_data_for_users($approveduserlist);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +116,8 @@ class core_privacy_legacy_quizaccess_polyfill_test extends advanced_testcase {
|
||||
*/
|
||||
class test_privacy_legacy_quizaccess_polyfill_provider implements
|
||||
\core_privacy\local\metadata\provider,
|
||||
\mod_quiz\privacy\quizaccess_provider {
|
||||
\mod_quiz\privacy\quizaccess_provider,
|
||||
\mod_quiz\privacy\quizaccess_user_provider {
|
||||
|
||||
use \mod_quiz\privacy\legacy_quizaccess_polyfill;
|
||||
use \core_privacy\local\legacy_polyfill;
|
||||
@ -138,6 +156,15 @@ class test_privacy_legacy_quizaccess_polyfill_provider implements
|
||||
static::$mock->get_return_value(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all user data for the specified users, in the specified context.
|
||||
*
|
||||
* @param \core_privacy\local\request\approved_userlist $userlist
|
||||
*/
|
||||
protected static function _delete_quizaccess_data_for_users($userlist) {
|
||||
static::$mock->get_return_value(__FUNCTION__, func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns metadata about this plugin.
|
||||
*
|
||||
|
@ -457,4 +457,99 @@ class mod_quiz_privacy_provider_testcase extends \core_privacy\tests\provider_te
|
||||
|
||||
return [$quizobj, $quba, $attemptobj];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::get_users_in_context().
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$anotheruser = $this->getDataGenerator()->create_user();
|
||||
$extrauser = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Make a quiz.
|
||||
$this->setUser();
|
||||
$quiz = $this->create_test_quiz($course);
|
||||
|
||||
// Create an override for user1.
|
||||
$DB->insert_record('quiz_overrides', [
|
||||
'quiz' => $quiz->id,
|
||||
'userid' => $user->id,
|
||||
'timeclose' => 1300,
|
||||
'timelimit' => null,
|
||||
]);
|
||||
|
||||
// Make an attempt on the quiz as user2.
|
||||
list($quizobj, $quba, $attemptobj) = $this->attempt_quiz($quiz, $anotheruser);
|
||||
$context = $quizobj->get_context();
|
||||
|
||||
// Fetch users - user1 and user2 should be returned.
|
||||
$userlist = new \core_privacy\local\request\userlist($context, 'mod_quiz');
|
||||
\mod_quiz\privacy\provider::get_users_in_context($userlist);
|
||||
$this->assertEquals(
|
||||
[$user->id, $anotheruser->id],
|
||||
$userlist->get_userids(),
|
||||
'', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_users().
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
|
||||
$course1 = $this->getDataGenerator()->create_course();
|
||||
$course2 = $this->getDataGenerator()->create_course();
|
||||
|
||||
// Make a quiz in each course.
|
||||
$quiz1 = $this->create_test_quiz($course1);
|
||||
$quiz2 = $this->create_test_quiz($course2);
|
||||
|
||||
// Attempt quiz1 as user1 and user2.
|
||||
list($quiz1obj) = $this->attempt_quiz($quiz1, $user1);
|
||||
$this->attempt_quiz($quiz1, $user2);
|
||||
|
||||
// Create an override in quiz1 for user3.
|
||||
$DB->insert_record('quiz_overrides', [
|
||||
'quiz' => $quiz1->id,
|
||||
'userid' => $user3->id,
|
||||
'timeclose' => 1300,
|
||||
'timelimit' => null,
|
||||
]);
|
||||
|
||||
// Attempt quiz2 as user1.
|
||||
$this->attempt_quiz($quiz2, $user1);
|
||||
|
||||
// Delete the data for user1 and user3 in course1 and check it is removed.
|
||||
$quiz1context = $quiz1obj->get_context();
|
||||
$approveduserlist = new \core_privacy\local\request\approved_userlist($quiz1context, 'mod_quiz',
|
||||
[$user1->id, $user3->id]);
|
||||
provider::delete_data_for_users($approveduserlist);
|
||||
|
||||
// Only the attempt of user2 should be remained in quiz1.
|
||||
$this->assertEquals(
|
||||
[$user2->id],
|
||||
$DB->get_fieldset_select('quiz_attempts', 'userid', 'quiz = ?', [$quiz1->id])
|
||||
);
|
||||
|
||||
// The attempt that user1 made in quiz2 should be remained.
|
||||
$this->assertEquals(
|
||||
[$user1->id],
|
||||
$DB->get_fieldset_select('quiz_attempts', 'userid', 'quiz = ?', [$quiz2->id])
|
||||
);
|
||||
|
||||
// The quiz override in quiz1 that we had for user3 should be deleted.
|
||||
$this->assertEquals(
|
||||
[],
|
||||
$DB->get_fieldset_select('quiz_overrides', 'userid', 'quiz = ?', [$quiz1->id])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -18,17 +18,20 @@
|
||||
* Privacy Subsystem implementation for core_question.
|
||||
*
|
||||
* @package core_question
|
||||
* @category privacy
|
||||
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace core_question\privacy;
|
||||
|
||||
use \core_privacy\local\metadata\collection;
|
||||
use \core_privacy\local\request\writer;
|
||||
use \core_privacy\local\request\transform;
|
||||
use \core_privacy\local\request\contextlist;
|
||||
use \core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\metadata\collection;
|
||||
use core_privacy\local\request\approved_contextlist;
|
||||
use core_privacy\local\request\approved_userlist;
|
||||
use core_privacy\local\request\contextlist;
|
||||
use core_privacy\local\request\transform;
|
||||
use core_privacy\local\request\userlist;
|
||||
use core_privacy\local\request\writer;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -55,7 +58,10 @@ class provider implements
|
||||
\core_privacy\local\request\subsystem\provider,
|
||||
|
||||
// This is a subsysytem which provides information to plugins.
|
||||
\core_privacy\local\request\subsystem\plugin_provider
|
||||
\core_privacy\local\request\subsystem\plugin_provider,
|
||||
|
||||
// This plugin is capable of determining which users have data within it.
|
||||
\core_privacy\local\request\core_userlist_provider
|
||||
{
|
||||
|
||||
/**
|
||||
@ -344,6 +350,30 @@ class provider implements
|
||||
return $contextlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of users who have data within a context.
|
||||
*
|
||||
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
|
||||
*/
|
||||
public static function get_users_in_context(userlist $userlist) {
|
||||
$context = $userlist->get_context();
|
||||
|
||||
// A user may have created or updated a question.
|
||||
// Questions are linked against a question category, which has a contextid field.
|
||||
$sql = "SELECT q.createdby, q.modifiedby
|
||||
FROM {question} q
|
||||
JOIN {question_categories} cat
|
||||
ON cat.id = q.category
|
||||
WHERE cat.contextid = :contextid";
|
||||
|
||||
$params = [
|
||||
'contextid' => $context->id
|
||||
];
|
||||
|
||||
$userlist->add_from_sql('createdby', $sql, $params);
|
||||
$userlist->add_from_sql('modifiedby', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine related question usages for a user.
|
||||
*
|
||||
@ -367,6 +397,32 @@ class provider implements
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the list of users who have rated in the specified constraints.
|
||||
*
|
||||
* @param userlist $userlist The userlist to add the users to.
|
||||
* @param string $prefix A unique prefix to add to the table alias to avoid interference with your own sql.
|
||||
* @param string $insql The SQL to use in a sub-select for the question_usages.id query.
|
||||
* @param array $params The params required for the insql.
|
||||
* @param int|null $contextid An optional context id, in case the $sql query is not already filtered by that.
|
||||
*/
|
||||
public static function get_users_in_context_from_sql(userlist $userlist, string $prefix, string $insql, $params,
|
||||
int $contextid = null) {
|
||||
|
||||
$sql = "SELECT {$prefix}_qas.userid
|
||||
FROM {question_attempt_steps} {$prefix}_qas
|
||||
JOIN {question_attempts} {$prefix}_qa ON {$prefix}_qas.questionattemptid = {$prefix}_qa.id
|
||||
JOIN {question_usages} {$prefix}_qu ON {$prefix}_qa.questionusageid = {$prefix}_qu.id
|
||||
WHERE {$prefix}_qu.id IN ({$insql})";
|
||||
|
||||
if ($contextid) {
|
||||
$sql .= " AND {$prefix}_qu.contextid = :{$prefix}_contextid";
|
||||
$params["{$prefix}_contextid"] = $contextid;
|
||||
}
|
||||
|
||||
$userlist->add_from_sql('userid', $sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Export all user data for the specified user, in the specified contexts.
|
||||
*
|
||||
@ -476,4 +532,33 @@ class provider implements
|
||||
category IN (SELECT id FROM {question_categories} WHERE contextid {$contextsql})
|
||||
AND modifiedby = :modifiedby", $contextparams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple users within a single context.
|
||||
*
|
||||
* @param approved_userlist $userlist The approved context and user information to delete information for.
|
||||
*/
|
||||
public static function delete_data_for_users(approved_userlist $userlist) {
|
||||
global $DB;
|
||||
|
||||
// Questions are considered to be 'owned' by the institution, even if they were originally written by a specific
|
||||
// user. They are still exported in the list of a users data, but they are not removed.
|
||||
// The userid is instead anonymised.
|
||||
|
||||
$context = $userlist->get_context();
|
||||
$userids = $userlist->get_userids();
|
||||
|
||||
list($createdbysql, $createdbyparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
list($modifiedbysql, $modifiedbyparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
|
||||
$params = ['contextid' => $context->id];
|
||||
|
||||
$DB->set_field_select('question', 'createdby', 0, "
|
||||
category IN (SELECT id FROM {question_categories} WHERE contextid = :contextid)
|
||||
AND createdby {$createdbysql}", $params + $createdbyparams);
|
||||
|
||||
$DB->set_field_select('question', 'modifiedby', 0, "
|
||||
category IN (SELECT id FROM {question_categories} WHERE contextid = :contextid)
|
||||
AND modifiedby {$modifiedbysql}", $params + $modifiedbyparams);
|
||||
}
|
||||
}
|
||||
|
@ -425,4 +425,115 @@ class core_question_privacy_provider_testcase extends \core_privacy\tests\provid
|
||||
$this->assertEquals($user->id, $qrecord->createdby);
|
||||
$this->assertEquals($user->id, $qrecord->modifiedby);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::get_users_in_context().
|
||||
*/
|
||||
public function test_get_users_in_context() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
|
||||
// Create three test users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create one question as each user in different contexts.
|
||||
$this->setUser($user1);
|
||||
$user1data = $questiongenerator->setup_course_and_questions();
|
||||
$this->setUser($user2);
|
||||
$user2data = $questiongenerator->setup_course_and_questions();
|
||||
|
||||
$course1context = \context_course::instance($user1data[1]->id);
|
||||
$course1questions = $user1data[3];
|
||||
|
||||
// Log in as user3 and update the questions in course1.
|
||||
$this->setUser($user3);
|
||||
|
||||
foreach ($course1questions as $question) {
|
||||
$questiongenerator->update_question($question);
|
||||
}
|
||||
|
||||
$userlist = new \core_privacy\local\request\userlist($course1context, 'core_question');
|
||||
provider::get_users_in_context($userlist);
|
||||
|
||||
// User1 has created questions and user3 has edited them.
|
||||
$this->assertCount(2, $userlist);
|
||||
$this->assertEquals(
|
||||
[$user1->id, $user3->id],
|
||||
$userlist->get_userids(),
|
||||
'', 0.0, 10, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for provider::delete_data_for_users().
|
||||
*/
|
||||
public function test_delete_data_for_users() {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$questiongenerator = $this->getDataGenerator()->get_plugin_generator('core_question');
|
||||
|
||||
// Create three test users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
$user3 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Create one question as each user in different contexts.
|
||||
$this->setUser($user1);
|
||||
$course1data = $questiongenerator->setup_course_and_questions();
|
||||
$course1 = $course1data[1];
|
||||
$course1qcat = $course1data[2];
|
||||
$course1questions = $course1data[3];
|
||||
$course1context = \context_course::instance($course1->id);
|
||||
|
||||
// Log in as user2 and update the questions in course1.
|
||||
$this->setUser($user2);
|
||||
|
||||
foreach ($course1questions as $question) {
|
||||
$questiongenerator->update_question($question);
|
||||
}
|
||||
|
||||
// Add 2 more questions to course1 by user3.
|
||||
$this->setUser($user3);
|
||||
$questiongenerator->create_question('shortanswer', null, ['category' => $course1qcat->id]);
|
||||
$questiongenerator->create_question('shortanswer', null, ['category' => $course1qcat->id]);
|
||||
|
||||
// Now, log in as user1 again, and then create a new course and add questions to that.
|
||||
$this->setUser($user1);
|
||||
$questiongenerator->setup_course_and_questions();
|
||||
|
||||
$approveduserlist = new \core_privacy\local\request\approved_userlist($course1context, 'core_question',
|
||||
[$user1->id, $user2->id]);
|
||||
provider::delete_data_for_users($approveduserlist);
|
||||
|
||||
// Now, there should be no question related to user1 or user2 in course1.
|
||||
$this->assertEquals(
|
||||
0,
|
||||
$DB->count_records_sql("SELECT COUNT(q.id)
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON q.category = qc.id
|
||||
WHERE qc.contextid = ?
|
||||
AND (q.createdby = ? OR q.modifiedby = ? OR q.createdby = ? OR q.modifiedby = ?)",
|
||||
[$course1context->id, $user1->id, $user1->id, $user2->id, $user2->id])
|
||||
);
|
||||
|
||||
// User3 data in course1 should not change.
|
||||
$this->assertEquals(
|
||||
2,
|
||||
$DB->count_records_sql("SELECT COUNT(q.id)
|
||||
FROM {question} q
|
||||
JOIN {question_categories} qc ON q.category = qc.id
|
||||
WHERE qc.contextid = ? AND (q.createdby = ? OR q.modifiedby = ?)",
|
||||
[$course1context->id, $user3->id, $user3->id])
|
||||
);
|
||||
|
||||
// User1 has authored 2 questions in another course.
|
||||
$this->assertEquals(
|
||||
2,
|
||||
$DB->count_records_select('question', "createdby = ? OR modifiedby = ?", [$user1->id, $user1->id])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user