if (self::is_site_dpo($requestinguser)) {
// The user making the request is a DPO. Should be fine.
$datarequest->set('dpo', $requestinguser);
- } else {
- // If not a DPO, only users with the capability to make data requests for the user should be allowed.
- // (e.g. users with the Parent role, etc).
- if (!self::can_create_data_request_for_user($foruser)) {
- $forusercontext = \context_user::instance($foruser);
- throw new required_capability_exception($forusercontext,
- 'tool/dataprivacy:makedatarequestsforchildren', 'nopermissions', '');
- }
}
}
// The user making the request.
/**
* Checks whether a non-DPO user can make a data request for another user.
*
- * @param int $user The user ID of the target user.
- * @param int $requester The user ID of the user making the request.
- * @return bool
- * @throws coding_exception
+ * @param int $user The user ID of the target user.
+ * @param int $requester The user ID of the user making the request.
+ * @return bool
*/
public static function can_create_data_request_for_user($user, $requester = null) {
$usercontext = \context_user::instance($user);
+
return has_capability('tool/dataprivacy:makedatarequestsforchildren', $usercontext, $requester);
}
+ /**
+ * Require that the current user can make a data request for the specified other user.
+ *
+ * @param int $user The user ID of the target user.
+ * @param int $requester The user ID of the user making the request.
+ * @return bool
+ */
+ public static function require_can_create_data_request_for_user($user, $requester = null) {
+ $usercontext = \context_user::instance($user);
+
+ require_capability('tool/dataprivacy:makedatarequestsforchildren', $usercontext, $requester);
+
+ return true;
+ }
+
/**
* Checks whether a user can download a data request.
*
* @return \tool_dataprivacy\purpose.
*/
public static function create_purpose(stdClass $record) {
- self::check_can_manage_data_registry();
-
$purpose = new purpose(0, $record);
$purpose->create();
* @return \tool_dataprivacy\purpose.
*/
public static function update_purpose(stdClass $record) {
- self::check_can_manage_data_registry();
-
if (!isset($record->sensitivedatareasons)) {
$record->sensitivedatareasons = '';
}
* @return bool
*/
public static function delete_purpose($id) {
- self::check_can_manage_data_registry();
-
$purpose = new purpose($id);
if ($purpose->is_used()) {
throw new \moodle_exception('Purpose with id ' . $id . ' can not be deleted because it is used.');
* @return \tool_dataprivacy\purpose[]
*/
public static function get_purposes() {
- self::check_can_manage_data_registry();
-
return purpose::get_records([], 'name', 'ASC');
}
* @return \tool_dataprivacy\category.
*/
public static function create_category(stdClass $record) {
- self::check_can_manage_data_registry();
-
$category = new category(0, $record);
$category->create();
* @return \tool_dataprivacy\category.
*/
public static function update_category(stdClass $record) {
- self::check_can_manage_data_registry();
-
$category = new category($record->id);
$category->from_record($record);
* @return bool
*/
public static function delete_category($id) {
- self::check_can_manage_data_registry();
-
$category = new category($id);
if ($category->is_used()) {
throw new \moodle_exception('Category with id ' . $id . ' can not be deleted because it is used.');
* @return \tool_dataprivacy\category[]
*/
public static function get_categories() {
- self::check_can_manage_data_registry();
-
return category::get_records([], 'name', 'ASC');
}
* @return \tool_dataprivacy\context_instance
*/
public static function set_context_instance($record) {
- self::check_can_manage_data_registry($record->contextid);
-
if ($instance = context_instance::get_record_by_contextid($record->contextid, false)) {
// Update.
$instance->from_record($record);
* @return null
*/
public static function unset_context_instance(context_instance $instance) {
- self::check_can_manage_data_registry($instance->get('contextid'));
$instance->delete();
}
public static function set_contextlevel($record) {
global $DB;
- // Only manager at system level can set this.
- self::check_can_manage_data_registry();
-
if ($record->contextlevel != CONTEXT_SYSTEM && $record->contextlevel != CONTEXT_USER) {
throw new \coding_exception('Only context system and context user can set a contextlevel ' .
'purpose and retention');
* @return category|false
*/
public static function get_effective_context_category(\context $context, $forcedvalue=false) {
- self::check_can_manage_data_registry($context->id);
if (!data_registry::defaults_set()) {
return false;
}
* @return purpose|false
*/
public static function get_effective_context_purpose(\context $context, $forcedvalue=false) {
- self::check_can_manage_data_registry($context->id);
if (!data_registry::defaults_set()) {
return false;
}
* @return category|false
*/
public static function get_effective_contextlevel_category($contextlevel, $forcedvalue=false) {
- self::check_can_manage_data_registry(\context_system::instance()->id);
if (!data_registry::defaults_set()) {
return false;
}
* @return purpose|false
*/
public static function get_effective_contextlevel_purpose($contextlevel, $forcedvalue=false) {
- self::check_can_manage_data_registry(\context_system::instance()->id);
if (!data_registry::defaults_set()) {
return false;
}
* @return \tool_dataprivacy\expired_context
*/
public static function create_expired_context($contextid) {
- self::check_can_manage_data_registry();
-
$record = (object)[
'contextid' => $contextid,
'status' => expired_context::STATUS_EXPIRED,
* @return bool True on success.
*/
public static function delete_expired_context($id) {
- self::check_can_manage_data_registry();
-
$expiredcontext = new expired_context($id);
return $expiredcontext->delete();
}
* @return null
*/
public static function set_expired_context_status(expired_context $expiredctx, $status) {
- self::check_can_manage_data_registry();
-
$expiredctx->set('status', $status);
$expiredctx->save();
}
]);
$requestid = $params['requestid'];
- // Validate context.
+ // Validate context and access to manage the registry.
$context = context_user::instance($USER->id);
self::validate_context($context);
// Ensure the request exists.
$select = 'id = :id AND (userid = :userid OR requestedby = :requestedby)';
$params = ['id' => $requestid, 'userid' => $USER->id, 'requestedby' => $USER->id];
- $requestexists = data_request::record_exists_select($select, $params);
+ $requests = data_request::get_records_select($select, $params);
+ $requestexists = count($requests) === 1;
$result = false;
if ($requestexists) {
+ $request = reset($requests);
+ $datasubject = $request->get('userid');
+
+ if ($datasubject !== $USER->id) {
+ // The user is not the subject. Check that they can cancel this request.
+ if (!api::can_create_data_request_for_user($datasubject)) {
+ $forusercontext = \context_user::instance($datasubject);
+ throw new required_capability_exception($forusercontext,
+ 'tool/dataprivacy:makedatarequestsforchildren', 'nopermissions', '');
+ }
+ }
+
// TODO: Do we want a request to be non-cancellable past a certain point? E.g. When it's already approved/processing.
$result = api::update_request_status($requestid, api::DATAREQUEST_STATUS_CANCELLED);
} else {
]);
$requestid = $params['requestid'];
- // Validate context.
+ // Validate context and access to manage the registry.
$context = context_system::instance();
self::validate_context($context);
+ api::check_can_manage_data_registry();
$message = get_string('markedcomplete', 'tool_dataprivacy');
// Update the data request record.
'jsonformdata' => $jsonformdata
]);
+ // Validate context and access to manage the registry.
self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
$serialiseddata = json_decode($params['jsonformdata']);
$data = array();
'id' => $id
]);
+ // Validate context and access to manage the registry.
+ self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
+
$result = api::delete_purpose($params['id']);
return [
'jsonformdata' => $jsonformdata
]);
+ // Validate context and access to manage the registry.
self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
$serialiseddata = json_decode($params['jsonformdata']);
$data = array();
'id' => $id
]);
+ // Validate context and access to manage the registry.
+ self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
+
$result = api::delete_category($params['id']);
return [
'jsonformdata' => $jsonformdata
]);
- // Extra permission checkings are delegated to api::set_contextlevel.
+ // Validate context and access to manage the registry.
self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
$serialiseddata = json_decode($params['jsonformdata']);
$data = array();
$customdata = \tool_dataprivacy\form\context_instance::get_context_instance_customdata($context);
$mform = new \tool_dataprivacy\form\context_instance(null, $customdata, 'post', '', null, true, $data);
if ($validateddata = $mform->get_data()) {
+ api::check_can_manage_data_registry($validateddata->contextid);
$context = api::set_context_instance($validateddata);
} else if ($errors = $mform->is_validated()) {
$warnings[] = json_encode($errors);
]);
$ids = $params['ids'];
- // Validate context.
- $context = context_system::instance();
- self::validate_context($context);
+ // Validate context and access to manage the registry.
+ self::validate_context(\context_system::instance());
+ api::check_can_manage_data_registry();
$result = true;
if (!empty($ids)) {
$context = context_system::instance();
self::validate_context($context);
+ api::check_can_manage_data_registry();
$categories = api::get_categories();
$options = data_registry_page::category_options($categories, $includenotset, $includeinherit);
require_once('../../../config.php');
require_once('lib.php');
-require_once('classes/api.php');
require_once('createdatarequest_form.php');
$manage = optional_param('manage', 0, PARAM_INT);
// Data request submitted.
if ($data = $mform->get_data()) {
+ if ($data->userid != $USER->id) {
+ if (!\tool_dataprivacy\api::can_manage_data_requests($USER->id)) {
+ // If not a DPO, only users with the capability to make data requests for the user should be allowed.
+ // (e.g. users with the Parent role, etc).
+ \tool_dataprivacy\api::require_can_create_data_request_for_user($data->userid);
+ }
+ }
+
\tool_dataprivacy\api::create_data_request($data->userid, $data->type, $data->comments);
if ($manage) {
class tool_dataprivacy_api_testcase extends advanced_testcase {
/**
- * setUp.
+ * Ensure that the check_can_manage_data_registry function fails cap testing when a user without capabilities is
+ * tested with the default context.
*/
- public function setUp() {
+ public function test_check_can_manage_data_registry_admin() {
$this->resetAfterTest();
+
+ $this->setAdminUser();
+ // Technically this actually returns void, but assertNull will suffice to avoid a pointless test.
+ $this->assertNull(api::check_can_manage_data_registry());
+ }
+
+ /**
+ * Ensure that the check_can_manage_data_registry function fails cap testing when a user without capabilities is
+ * tested with the default context.
+ */
+ public function test_check_can_manage_data_registry_without_cap_default() {
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user();
+ $this->setUser($user);
+
+ $this->expectException(required_capability_exception::class);
+ api::check_can_manage_data_registry();
+ }
+
+ /**
+ * Ensure that the check_can_manage_data_registry function fails cap testing when a user without capabilities is
+ * tested with the default context.
+ */
+ public function test_check_can_manage_data_registry_without_cap_system() {
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user();
+ $this->setUser($user);
+
+ $this->expectException(required_capability_exception::class);
+ api::check_can_manage_data_registry(\context_system::instance()->id);
+ }
+
+ /**
+ * Ensure that the check_can_manage_data_registry function fails cap testing when a user without capabilities is
+ * tested with the default context.
+ */
+ public function test_check_can_manage_data_registry_without_cap_own_user() {
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user();
+ $this->setUser($user);
+
+ $this->expectException(required_capability_exception::class);
+ api::check_can_manage_data_registry(\context_user::instance($user->id)->id);
}
/**
* Test for api::update_request_status().
*/
public function test_update_request_status() {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$s1 = $generator->create_user();
$this->setUser($s1);
$requestid = $datarequest->get('id');
+ // Update with a comment.
+ $comment = 'This is an example of a comment';
+ $result = api::update_request_status($requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0, $comment);
+ $this->assertTrue($result);
+ $datarequest = new data_request($requestid);
+ $this->assertStringEndsWith($comment, $datarequest->get('dpocomment'));
+
+ // Update with a comment which will be trimmed.
+ $result = api::update_request_status($requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0, ' ');
+ $this->assertTrue($result);
+ $datarequest = new data_request($requestid);
+ $this->assertStringEndsWith($comment, $datarequest->get('dpocomment'));
+
+ // Update with a comment.
+ $secondcomment = ' - More comments - ';
+ $result = api::update_request_status($requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL, 0, $secondcomment);
+ $this->assertTrue($result);
+ $datarequest = new data_request($requestid);
+ $this->assertRegExp("/.*{$comment}.*{$secondcomment}/s", $datarequest->get('dpocomment'));
+
// Update with a valid status.
$result = api::update_request_status($requestid, api::DATAREQUEST_STATUS_DOWNLOAD_READY);
$this->assertTrue($result);
* Test for api::get_site_dpos() when there are no users with the DPO role.
*/
public function test_get_site_dpos_no_dpos() {
+ $this->resetAfterTest();
+
$admin = get_admin();
$dpos = api::get_site_dpos();
*/
public function test_get_site_dpos() {
global $DB;
+
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$u1 = $generator->create_user();
$u2 = $generator->create_user();
public function test_get_assigned_privacy_officer_roles() {
global $DB;
+ $this->resetAfterTest();
+
// Erroneously set the manager roles as the PO, even if it doesn't have the managedatarequests capability yet.
$managerroleid = $DB->get_field('role', 'id', array('shortname' => 'manager'));
set_config('dporoles', $managerroleid, 'tool_dataprivacy');
public function test_approve_data_request() {
global $DB;
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$s1 = $generator->create_user();
$u1 = $generator->create_user();
public function test_approve_data_request_not_yet_ready() {
global $DB;
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$s1 = $generator->create_user();
$u1 = $generator->create_user();
* Test for api::approve_data_request() when called by a user who doesn't have the DPO role.
*/
public function test_approve_data_request_non_dpo_user() {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$student = $generator->create_user();
$teacher = $generator->create_user();
$datarequest = api::create_data_request($student->id, api::DATAREQUEST_TYPE_EXPORT);
$requestid = $datarequest->get('id');
-
- // Login as a user without DPO role.
- $this->setUser($teacher);
- $this->expectException(required_capability_exception::class);
- api::approve_data_request($requestid);
}
/**
* Test for api::can_contact_dpo()
*/
public function test_can_contact_dpo() {
+ $this->resetAfterTest();
+
// Default ('contactdataprotectionofficer' is disabled by default).
$this->assertFalse(api::can_contact_dpo());
public function test_can_manage_data_requests() {
global $DB;
+ $this->resetAfterTest();
+
// No configured site DPOs yet.
$admin = get_admin();
$this->assertTrue(api::can_manage_data_requests($admin->id));
$this->assertFalse(api::can_manage_data_requests($nondpoincapable->id));
}
+ /**
+ * Test that a user who has no capability to make any data requests for children cannot create data requests for any
+ * other user.
+ */
+ public function test_can_create_data_request_for_user_no() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $otheruser = $this->getDataGenerator()->create_user();
+
+ $this->setUser($parent);
+ $this->assertFalse(api::can_create_data_request_for_user($otheruser->id));
+ }
+
+ /**
+ * Test that a user who has the capability to make any data requests for one other user cannot create data requests
+ * for any other user.
+ */
+ public function test_can_create_data_request_for_user_some() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $child = $this->getDataGenerator()->create_user();
+ $otheruser = $this->getDataGenerator()->create_user();
+
+ $systemcontext = \context_system::instance();
+ $parentrole = $this->getDataGenerator()->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $parent->id, \context_user::instance($child->id));
+
+ $this->setUser($parent);
+ $this->assertFalse(api::can_create_data_request_for_user($otheruser->id));
+ }
+
+ /**
+ * Test that a user who has the capability to make any data requests for one other user cannot create data requests
+ * for any other user.
+ */
+ public function test_can_create_data_request_for_user_own_child() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $child = $this->getDataGenerator()->create_user();
+
+ $systemcontext = \context_system::instance();
+ $parentrole = $this->getDataGenerator()->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $parent->id, \context_user::instance($child->id));
+
+ $this->setUser($parent);
+ $this->assertTrue(api::can_create_data_request_for_user($child->id));
+ }
+
+ /**
+ * Test that a user who has no capability to make any data requests for children cannot create data requests for any
+ * other user.
+ */
+ public function test_require_can_create_data_request_for_user_no() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $otheruser = $this->getDataGenerator()->create_user();
+
+ $this->setUser($parent);
+ $this->expectException('required_capability_exception');
+ api::require_can_create_data_request_for_user($otheruser->id);
+ }
+
+ /**
+ * Test that a user who has the capability to make any data requests for one other user cannot create data requests
+ * for any other user.
+ */
+ public function test_require_can_create_data_request_for_user_some() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $child = $this->getDataGenerator()->create_user();
+ $otheruser = $this->getDataGenerator()->create_user();
+
+ $systemcontext = \context_system::instance();
+ $parentrole = $this->getDataGenerator()->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $parent->id, \context_user::instance($child->id));
+
+ $this->setUser($parent);
+ $this->expectException('required_capability_exception');
+ api::require_can_create_data_request_for_user($otheruser->id);
+ }
+
+ /**
+ * Test that a user who has the capability to make any data requests for one other user cannot create data requests
+ * for any other user.
+ */
+ public function test_require_can_create_data_request_for_user_own_child() {
+ $this->resetAfterTest();
+
+ $parent = $this->getDataGenerator()->create_user();
+ $child = $this->getDataGenerator()->create_user();
+
+ $systemcontext = \context_system::instance();
+ $parentrole = $this->getDataGenerator()->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $parent->id, \context_user::instance($child->id));
+
+ $this->setUser($parent);
+ $this->assertTrue(api::require_can_create_data_request_for_user($child->id));
+ }
+
/**
* Test for api::can_download_data_request_for_user()
*/
public function test_can_download_data_request_for_user() {
+ $this->resetAfterTest();
+
$generator = $this->getDataGenerator();
// Three victims.
* Test for api::create_data_request()
*/
public function test_create_data_request() {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user = $generator->create_user();
$comment = 'sample comment';
public function test_create_data_request_by_dpo() {
global $USER;
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user = $generator->create_user();
$comment = 'sample comment';
public function test_create_data_request_by_parent() {
global $DB;
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user = $generator->create_user();
$parent = $generator->create_user();
* Test for api::deny_data_request()
*/
public function test_deny_data_request() {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user = $generator->create_user();
$comment = 'sample comment';
$this->assertTrue($result);
}
- /**
- * Test for api::deny_data_request()
- */
- public function test_deny_data_request_without_permissions() {
- $generator = new testing_data_generator();
- $user = $generator->create_user();
- $comment = 'sample comment';
-
- // Login as user.
- $this->setUser($user->id);
-
- // Test data request creation.
- $datarequest = api::create_data_request($user->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
-
- // Login as a non-DPO user and try to call deny_data_request.
- $user2 = $generator->create_user();
- $this->setUser($user2);
- $this->expectException(required_capability_exception::class);
- api::deny_data_request($datarequest->get('id'));
- }
-
/**
* Data provider for \tool_dataprivacy_api_testcase::test_get_data_requests().
*
* @param int[] $statuses Status filters.
*/
public function test_get_data_requests($usertype, $fetchall, $statuses) {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user1 = $generator->create_user();
$user2 = $generator->create_user();
* @param bool $expected The expected result.
*/
public function test_has_ongoing_request($status, $expected) {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user1 = $generator->create_user();
public function test_is_site_dpo() {
global $DB;
+ $this->resetAfterTest();
+
// No configured site DPOs yet.
$admin = get_admin();
$this->assertTrue(api::is_site_dpo($admin->id));
* @param string $comments The requestor's message to the DPO.
*/
public function test_notify_dpo($byadmin, $type, $typestringid, $comments) {
+ $this->resetAfterTest();
+
$generator = new testing_data_generator();
$user1 = $generator->create_user();
// Let's just use admin as DPO (It's the default if not set).
$this->assertContains(fullname($user1), $message->fullmessage);
}
- /**
- * Test of creating purpose as a user without privileges.
- */
- public function test_create_purpose_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
-
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::create_purpose((object)[
- 'name' => 'aaa',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1,
- 'retentionperiod' => 'PT1M'
- ]);
- }
-
- /**
- * Test fetching of purposes as a user without privileges.
- */
- public function test_get_purposes_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
- $this->setAdminUser();
- api::create_purpose((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1,
- 'retentionperiod' => 'PT1M',
- 'lawfulbases' => 'gdpr_art_6_1_a'
- ]);
-
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::get_purposes();
- }
-
- /**
- * Test updating of purpose as a user without privileges.
- */
- public function test_update_purposes_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
- $this->setAdminUser();
- $purpose = api::create_purpose((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1,
- 'retentionperiod' => 'PT1M',
- 'lawfulbases' => 'gdpr_art_6_1_a'
- ]);
-
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- $purpose->set('retentionperiod', 'PT2M');
- api::update_purpose($purpose->to_record());
- }
-
- /**
- * Test purpose deletion as a user without privileges.
- */
- public function test_delete_purpose_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
- $this->setAdminUser();
- $purpose = api::create_purpose((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1,
- 'retentionperiod' => 'PT1M',
- 'lawfulbases' => 'gdpr_art_6_1_a'
- ]);
-
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::delete_purpose($purpose->get('id'));
- }
-
/**
* Test data purposes CRUD actions.
*
* @return null
*/
public function test_purpose_crud() {
+ $this->resetAfterTest();
$this->setAdminUser();
$this->assertCount(0, api::get_purposes());
}
- /**
- * Test creation of data categories as a user without privileges.
- */
- public function test_create_category_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
-
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::create_category((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1
- ]);
- }
-
- /**
- * Test fetching of data categories as a user without privileges.
- */
- public function test_get_categories_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
-
- $this->setAdminUser();
- api::create_category((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1
- ]);
-
- // Back to a regular user.
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::get_categories();
- }
-
- /**
- * Test updating of data category as a user without privileges.
- */
- public function test_update_category_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
-
- $this->setAdminUser();
- $category = api::create_category((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1
- ]);
-
- // Back to a regular user.
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- $category->set('name', 'yeah');
- api::update_category($category->to_record());
- }
-
- /**
- * Test deletion of data category as a user without privileges.
- */
- public function test_delete_category_non_dpo_user() {
- $pleb = $this->getDataGenerator()->create_user();
-
- $this->setAdminUser();
- $category = api::create_category((object)[
- 'name' => 'bbb',
- 'description' => '<b>yeah</b>',
- 'descriptionformat' => 1
- ]);
-
- // Back to a regular user.
- $this->setUser($pleb);
- $this->expectException(required_capability_exception::class);
- api::delete_category($category->get('id'));
- $this->fail('Users shouldn\'t be allowed to manage categories by default');
- }
-
/**
* Test data categories CRUD actions.
*
* @return null
*/
public function test_category_crud() {
+ $this->resetAfterTest();
$this->setAdminUser();
public function test_context_instances() {
global $DB;
+ $this->resetAfterTest();
+
$this->setAdminUser();
list($purposes, $categories, $courses, $modules) = $this->add_purposes_and_categories();
public function test_contextlevel() {
global $DB;
+ $this->resetAfterTest();
+
$this->setAdminUser();
list($purposes, $categories, $courses, $modules) = $this->add_purposes_and_categories();
public function test_effective_contextlevel_defaults() {
$this->setAdminUser();
+ $this->resetAfterTest();
+
list($purposes, $categories, $courses, $modules) = $this->add_purposes_and_categories();
list($purposeid, $categoryid) = data_registry::get_effective_default_contextlevel_purpose_and_category(CONTEXT_SYSTEM);
$this->assertEquals($categories[0]->get('id'), $categoryid);
}
+ public function test_get_effective_contextlevel_category() {
+ // Before setup, get_effective_contextlevel_purpose will return false.
+ $this->assertFalse(api::get_effective_contextlevel_category(CONTEXT_SYSTEM));
+ }
+
/**
* Test effective contextlevel return.
- *
- * @return null
*/
public function test_effective_contextlevel() {
$this->setAdminUser();
+ $this->resetAfterTest();
+
+ // Before setup, get_effective_contextlevel_purpose will return false.
+ $this->assertFalse(api::get_effective_contextlevel_purpose(CONTEXT_SYSTEM));
+
list($purposes, $categories, $courses, $modules) = $this->add_purposes_and_categories();
// Set the system context level to purpose 1.
* @return null
*/
public function test_effective_context() {
+ $this->resetAfterTest();
+
$this->setAdminUser();
list($purposes, $categories, $courses, $modules) = $this->add_purposes_and_categories();
* @return null
*/
protected function add_purposes_and_categories() {
+ $this->resetAfterTest();
$purpose1 = api::create_purpose((object)['name' => 'p1', 'retentionperiod' => 'PT1H', 'lawfulbases' => 'gdpr_art_6_1_a']);
$purpose2 = api::create_purpose((object)['name' => 'p2', 'retentionperiod' => 'PT2H', 'lawfulbases' => 'gdpr_art_6_1_b']);
* Test that delete requests filter out protected purpose contexts.
*/
public function test_add_request_contexts_with_status_delete() {
+ $this->resetAfterTest();
+
$data = $this->setup_test_add_request_contexts_with_status(api::DATAREQUEST_TYPE_DELETE);
$contextids = $data->list->get_contextids();
* Test that export requests don't filter out protected purpose contexts.
*/
public function test_add_request_contexts_with_status_export() {
+ $this->resetAfterTest();
+
$data = $this->setup_test_add_request_contexts_with_status(api::DATAREQUEST_TYPE_EXPORT);
$contextids = $data->list->get_contextids();
public function test_set_context_defaults($contextlevel, $inheritcategory, $inheritpurpose, $foractivity, $override) {
$this->setAdminUser();
+ $this->resetAfterTest();
+
$generator = $this->getDataGenerator();
// Generate course cat, course, block, assignment, forum instances.
* @return \stdClass
*/
protected function setup_test_add_request_contexts_with_status($type) {
+ $this->resetAfterTest();
+
$this->setAdminUser();
// User under test.
*/
class tool_dataprivacy_external_testcase extends externallib_advanced_testcase {
- /** @var stdClass The user making the request. */
- protected $requester;
-
- /** @var int The data request ID. */
- protected $requestid;
-
/**
- * Setup function- we will create a course and add an assign instance to it.
+ * Test for external::approve_data_request() with the user not logged in.
*/
- protected function setUp() {
+ public function test_approve_data_request_not_logged_in() {
$this->resetAfterTest();
$generator = new testing_data_generator();
$requester = $generator->create_user();
-
$comment = 'sample comment';
- // Login as user.
- $this->setUser($requester->id);
-
// Test data request creation.
+ $this->setUser($requester);
$datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
- $this->requestid = $datarequest->get('id');
- $this->requester = $requester;
// Log out the user and set force login to true.
$this->setUser();
- }
- /**
- * Test for external::approve_data_request() with the user not logged in.
- */
- public function test_approve_data_request_not_logged_in() {
$this->expectException(require_login_exception::class);
- external::approve_data_request($this->requestid);
+ external::approve_data_request($datarequest->get('id'));
}
/**
* Test for external::approve_data_request() with the user not having a DPO role.
*/
public function test_approve_data_request_not_dpo() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Login as the requester.
- $this->setUser($this->requester->id);
+ $this->setUser($requester);
$this->expectException(required_capability_exception::class);
- external::approve_data_request($this->requestid);
+ external::approve_data_request($datarequest->get('id'));
}
/**
* Test for external::approve_data_request() for request that's not ready for approval
*/
public function test_approve_data_request_not_waiting_for_approval() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
$this->expectException(moodle_exception::class);
- external::approve_data_request($this->requestid);
+ external::approve_data_request($datarequest->get('id'));
}
/**
* Test for external::approve_data_request()
*/
public function test_approve_data_request() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
- api::update_request_status($this->requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::approve_data_request($this->requestid);
+ api::update_request_status($datarequest->get('id'), api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ $result = external::approve_data_request($datarequest->get('id'));
$return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
$this->assertTrue($return->result);
$this->assertEmpty($return->warnings);
* Test for external::approve_data_request() for a non-existent request ID.
*/
public function test_approve_data_request_non_existent() {
+ $this->resetAfterTest();
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
- api::update_request_status($this->requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::approve_data_request($this->requestid + 1);
+
+ $result = external::approve_data_request(1);
+
$return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
$this->assertFalse($return->result);
$this->assertCount(1, $return->warnings);
* Test for external::cancel_data_request() of another user.
*/
public function test_cancel_data_request_other_user() {
- $generator = $this->getDataGenerator();
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
$otheruser = $generator->create_user();
+ $comment = 'sample comment';
- // Login as another user.
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ // Login as other user.
$this->setUser($otheruser);
- $result = external::cancel_data_request($this->requestid);
+ $result = external::cancel_data_request($datarequest->get('id'));
$return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
$this->assertFalse($return->result);
$this->assertCount(1, $return->warnings);
$this->assertEquals('errorrequestnotfound', $warning['warningcode']);
}
+ /**
+ * Test cancellation of a request where you are the requester of another user's data.
+ */
+ public function test_cancel_data_request_other_user_as_requester() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $otheruser = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Assign requester as otheruser'sparent.
+ $systemcontext = \context_system::instance();
+ $parentrole = $generator->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ $result = external::cancel_data_request($datarequest->get('id'));
+ $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
+ $this->assertTrue($return->result);
+ $this->assertEmpty($return->warnings);
+ }
+
+ /**
+ * Test cancellation of a request where you are the requester of another user's data.
+ */
+ public function test_cancel_data_request_requester_lost_permissions() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $otheruser = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Assign requester as otheruser'sparent.
+ $systemcontext = \context_system::instance();
+ $parentrole = $generator->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ // Unassign the role.
+ role_unassign($parentrole, $requester->id, \context_user::instance($otheruser->id)->id);
+
+ // This user can no longer make the request.
+ $this->expectException(required_capability_exception::class);
+
+ $result = external::cancel_data_request($datarequest->get('id'));
+ }
+
+ /**
+ * Test cancellation of a request where you are the requester of another user's data.
+ */
+ public function test_cancel_data_request_other_user_as_child() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $otheruser = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Assign requester as otheruser'sparent.
+ $systemcontext = \context_system::instance();
+ $parentrole = $generator->create_role();
+ assign_capability('tool/dataprivacy:makedatarequestsforchildren', CAP_ALLOW, $parentrole, $systemcontext);
+ role_assign($parentrole, $requester->id, \context_user::instance($otheruser->id));
+
+ // Test data request creation.
+ $this->setUser($otheruser);
+ $datarequest = api::create_data_request($otheruser->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ $result = external::cancel_data_request($datarequest->get('id'));
+ $return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
+ $this->assertTrue($return->result);
+ $this->assertEmpty($return->warnings);
+ }
+
/**
* Test for external::cancel_data_request()
*/
public function test_cancel_data_request() {
- // Login as the requester.
- $this->setUser($this->requester);
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ // Test cancellation.
+ $this->setUser($requester);
+ $result = external::cancel_data_request($datarequest->get('id'));
- $result = external::cancel_data_request($this->requestid);
$return = (object) external_api::clean_returnvalue(external::approve_data_request_returns(), $result);
$this->assertTrue($return->result);
$this->assertEmpty($return->warnings);
* Test contact DPO.
*/
public function test_contact_dpo() {
- $generator = $this->getDataGenerator();
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
$user = $generator->create_user();
- $this->setUser($user);
+ $this->setUser($user);
$message = 'Hello world!';
$result = external::contact_dpo($message);
$return = (object) external_api::clean_returnvalue(external::contact_dpo_returns(), $result);
* Test contact DPO with message containing invalid input.
*/
public function test_contact_dpo_with_nasty_input() {
- $generator = $this->getDataGenerator();
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
$user = $generator->create_user();
- $this->setUser($user);
+ $this->setUser($user);
$this->expectException('invalid_parameter_exception');
external::contact_dpo('de<>\\..scription');
}
* Test for external::deny_data_request() with the user not logged in.
*/
public function test_deny_data_request_not_logged_in() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ // Test data request creation.
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ // Log out.
+ $this->setUser();
$this->expectException(require_login_exception::class);
- external::deny_data_request($this->requestid);
+ external::deny_data_request($datarequest->get('id'));
}
/**
* Test for external::deny_data_request() with the user not having a DPO role.
*/
public function test_deny_data_request_not_dpo() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Login as the requester.
- $this->setUser($this->requester->id);
+ $this->setUser($requester);
$this->expectException(required_capability_exception::class);
- external::deny_data_request($this->requestid);
+ external::deny_data_request($datarequest->get('id'));
}
/**
* Test for external::deny_data_request() for request that's not ready for approval
*/
public function test_deny_data_request_not_waiting_for_approval() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
$this->expectException(moodle_exception::class);
- external::deny_data_request($this->requestid);
+ external::deny_data_request($datarequest->get('id'));
}
/**
* Test for external::deny_data_request()
*/
public function test_deny_data_request() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
- api::update_request_status($this->requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::approve_data_request($this->requestid);
+ api::update_request_status($datarequest->get('id'), api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ $result = external::approve_data_request($datarequest->get('id'));
$return = (object) external_api::clean_returnvalue(external::deny_data_request_returns(), $result);
$this->assertTrue($return->result);
$this->assertEmpty($return->warnings);
* Test for external::deny_data_request() for a non-existent request ID.
*/
public function test_deny_data_request_non_existent() {
+ $this->resetAfterTest();
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
- api::update_request_status($this->requestid, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::deny_data_request($this->requestid + 1);
+ $result = external::deny_data_request(1);
+
$return = (object) external_api::clean_returnvalue(external::deny_data_request_returns(), $result);
$this->assertFalse($return->result);
$this->assertCount(1, $return->warnings);
* Test for external::get_data_request() with the user not logged in.
*/
public function test_get_data_request_not_logged_in() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ $this->setUser();
$this->expectException(require_login_exception::class);
- external::get_data_request($this->requestid);
+ external::get_data_request($datarequest->get('id'));
}
/**
* Test for external::get_data_request() with the user not having a DPO role.
*/
public function test_get_data_request_not_dpo() {
- $generator = $this->getDataGenerator();
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
$otheruser = $generator->create_user();
- // Login as the requester.
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
+ // Login as the otheruser.
$this->setUser($otheruser);
$this->expectException(required_capability_exception::class);
- external::get_data_request($this->requestid);
+ external::get_data_request($datarequest->get('id'));
}
/**
* Test for external::get_data_request()
*/
public function test_get_data_request() {
+ $this->resetAfterTest();
+
+ $generator = new testing_data_generator();
+ $requester = $generator->create_user();
+ $comment = 'sample comment';
+
+ $this->setUser($requester);
+ $datarequest = api::create_data_request($requester->id, api::DATAREQUEST_TYPE_EXPORT, $comment);
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
- $result = external::get_data_request($this->requestid);
+ $result = external::get_data_request($datarequest->get('id'));
+
$return = (object) external_api::clean_returnvalue(external::get_data_request_returns(), $result);
$this->assertEquals(api::DATAREQUEST_TYPE_EXPORT, $return->result['type']);
$this->assertEquals('sample comment', $return->result['comments']);
- $this->assertEquals($this->requester->id, $return->result['userid']);
- $this->assertEquals($this->requester->id, $return->result['requestedby']);
+ $this->assertEquals($requester->id, $return->result['userid']);
+ $this->assertEquals($requester->id, $return->result['requestedby']);
$this->assertEmpty($return->warnings);
}
* Test for external::get_data_request() for a non-existent request ID.
*/
public function test_get_data_request_non_existent() {
+ $this->resetAfterTest();
+
// Admin as DPO. (The default when no one's assigned as a DPO in the site).
$this->setAdminUser();
$this->expectException(dml_missing_record_exception::class);
- external::get_data_request($this->requestid + 1);
+ external::get_data_request(1);
}
/**
* when called by a user that doesn't have the manage registry capability.
*/
public function test_set_context_defaults_no_capability() {
+ $this->resetAfterTest();
+
$generator = $this->getDataGenerator();
$user = $generator->create_user();
$this->setUser($user);
* @param bool $override Whether to override instances.
*/
public function test_set_context_defaults($modulelevel, $override) {
+ $this->resetAfterTest();
+
$this->setAdminUser();
$generator = $this->getDataGenerator();
* when called by a user that doesn't have the manage registry capability.
*/
public function test_get_category_options_no_capability() {
- $generator = $this->getDataGenerator();
- $user = $generator->create_user();
+ $this->resetAfterTest();
+
+ $user = $this->getDataGenerator()->create_user();
$this->setUser($user);
+
$this->expectException(required_capability_exception::class);
external::get_category_options(true, true);
}
* @param bool $includenotset Whether "Not set" would be included to the options.
*/
public function test_get_category_options($includeinherit, $includenotset) {
+ $this->resetAfterTest();
$this->setAdminUser();
// Prepare our expected options.
* when called by a user that doesn't have the manage registry capability.
*/
public function test_get_purpose_options_no_capability() {
+ $this->resetAfterTest();
$generator = $this->getDataGenerator();
$user = $generator->create_user();
$this->setUser($user);
* @param bool $includenotset Whether "Not set" would be included to the options.
*/
public function test_get_purpose_options($includeinherit, $includenotset) {
+ $this->resetAfterTest();
$this->setAdminUser();
// Prepare our expected options.
* @param bool $nodefaults Whether to fetch only activities that don't have defaults.
*/
public function test_get_activity_options($inheritcategory, $inheritpurpose, $nodefaults) {
+ $this->resetAfterTest();
$this->setAdminUser();
$category = api::create_category((object)['name' => 'Test category']);
* Test for external::bulk_approve_data_requests().
*/
public function test_bulk_approve_data_requests() {
- $generator = new testing_data_generator();
- $requester1 = $generator->create_user();
- $comment1 = 'sample comment';
- // Login as requester2.
- $this->setUser($requester1->id);
- // Create delete data request.
- $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, $comment1);
+ $this->resetAfterTest();
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
$requestid1 = $datarequest1->get('id');
- $requestid2 = $this->requestid;
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ // Approve the requests.
$this->setAdminUser();
api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
$result = external::bulk_approve_data_requests([$requestid1, $requestid2]);
+
$return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
$this->assertTrue($return->result);
$this->assertEmpty($return->warnings);
* Test for external::bulk_approve_data_requests() for a non-existent request ID.
*/
public function test_bulk_approve_data_requests_non_existent() {
- $generator = new testing_data_generator();
- $requester1 = $generator->create_user();
- $comment1 = 'sample comment';
- // Login as requester2.
- $this->setUser($requester1->id);
- // Create delete data request.
- $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, $comment1);
-
- $requestid1 = $datarequest1->get('id');
- $requestid2 = $this->requestid;
+ $this->resetAfterTest();
$this->setAdminUser();
- api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::bulk_approve_data_requests([$requestid1 + 1, $requestid2]);
+
+ $result = external::bulk_approve_data_requests([42]);
+
$return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
$this->assertFalse($return->result);
$this->assertCount(1, $return->warnings);
$warning = reset($return->warnings);
$this->assertEquals('errorrequestnotfound', $warning['warningcode']);
- $this->assertEquals($requestid1 + 1, $warning['item']);
+ $this->assertEquals(42, $warning['item']);
+ }
+
+ /**
+ * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
+ */
+ public function test_bulk_approve_data_requests_no_permission() {
+ $this->resetAfterTest();
+
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid1 = $datarequest1->get('id');
+
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ $this->setAdminUser();
+ api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+
+ // Approve the requests.
+ $uut = $this->getDataGenerator()->create_user();
+ $this->setUser($uut);
+
+ $this->expectException(required_capability_exception::class);
+ $result = external::bulk_approve_data_requests([$requestid1, $requestid2]);
+ }
+
+ /**
+ * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
+ */
+ public function test_bulk_approve_data_requests_own_request() {
+ $this->resetAfterTest();
+
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid1 = $datarequest1->get('id');
+
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ $this->setAdminUser();
+ api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+
+ // Deny the requests.
+ $this->setUser($requester1);
+
+ $this->expectException(required_capability_exception::class);
+ $result = external::bulk_approve_data_requests([$requestid1]);
}
/**
* Test for external::bulk_deny_data_requests().
*/
public function test_bulk_deny_data_requests() {
- $generator = new testing_data_generator();
- $requester1 = $generator->create_user();
- $comment1 = 'sample comment';
- // Login as requester2.
- $this->setUser($requester1->id);
- // Create delete data request.
- $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, $comment1);
+ $this->resetAfterTest();
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
$requestid1 = $datarequest1->get('id');
- $requestid2 = $this->requestid;
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ // Deny the requests.
$this->setAdminUser();
api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
$result = external::bulk_deny_data_requests([$requestid1, $requestid2]);
+
$return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
$this->assertTrue($return->result);
$this->assertEmpty($return->warnings);
* Test for external::bulk_deny_data_requests() for a non-existent request ID.
*/
public function test_bulk_deny_data_requests_non_existent() {
- $generator = new testing_data_generator();
- $requester1 = $generator->create_user();
- $comment1 = 'sample comment';
- // Login as requester2.
- $this->setUser($requester1->id);
- // Create delete data request.
- $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, $comment1);
-
- $requestid1 = $datarequest1->get('id');
- $requestid2 = $this->requestid;
+ $this->resetAfterTest();
$this->setAdminUser();
- api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
- $result = external::bulk_deny_data_requests([$requestid1 + 1, $requestid2]);
+ $result = external::bulk_deny_data_requests([42]);
$return = (object) external_api::clean_returnvalue(external::bulk_approve_data_requests_returns(), $result);
+
$this->assertFalse($return->result);
$this->assertCount(1, $return->warnings);
$warning = reset($return->warnings);
$this->assertEquals('errorrequestnotfound', $warning['warningcode']);
- $this->assertEquals($requestid1 + 1, $warning['item']);
+ $this->assertEquals(42, $warning['item']);
+ }
+
+ /**
+ * Test for external::bulk_deny_data_requests() for a user without permission to deny requests.
+ */
+ public function test_bulk_deny_data_requests_no_permission() {
+ $this->resetAfterTest();
+
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid1 = $datarequest1->get('id');
+
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ $this->setAdminUser();
+ api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+
+ // Deny the requests.
+ $uut = $this->getDataGenerator()->create_user();
+ $this->setUser($uut);
+
+ $this->expectException(required_capability_exception::class);
+ $result = external::bulk_deny_data_requests([$requestid1, $requestid2]);
+ }
+
+ /**
+ * Test for external::bulk_deny_data_requests() for a user cannot approve their own request.
+ */
+ public function test_bulk_deny_data_requests_own_request() {
+ $this->resetAfterTest();
+
+ // Create delete data requests.
+ $requester1 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester1->id);
+ $datarequest1 = api::create_data_request($requester1->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid1 = $datarequest1->get('id');
+
+ $requester2 = $this->getDataGenerator()->create_user();
+ $this->setUser($requester2->id);
+ $datarequest2 = api::create_data_request($requester2->id, api::DATAREQUEST_TYPE_DELETE, 'Example comment');
+ $requestid2 = $datarequest2->get('id');
+
+ $this->setAdminUser();
+ api::update_request_status($requestid1, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+ api::update_request_status($requestid2, api::DATAREQUEST_STATUS_AWAITING_APPROVAL);
+
+ // Deny the requests.
+ $this->setUser($requester1);
+
+ $this->expectException(required_capability_exception::class);
+ $result = external::bulk_deny_data_requests([$requestid1]);
}
}