See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Privacy tests for core_grading. 19 * 20 * @package core_grading 21 * @category test 22 * @copyright 2018 Sara Arjona <sara@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 namespace core_grading\privacy; 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 global $CFG; 30 31 use core_privacy\tests\provider_testcase; 32 use core_privacy\local\request\approved_contextlist; 33 use core_privacy\local\request\transform; 34 use core_privacy\local\request\writer; 35 use core_grading\privacy\provider; 36 37 /** 38 * Privacy tests for core_grading. 39 * 40 * @copyright 2018 Sara Arjona <sara@moodle.com> 41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 42 */ 43 class provider_test extends provider_testcase { 44 45 /** @var stdClass User without data. */ 46 protected $user0; 47 48 /** @var stdClass User with data. */ 49 protected $user1; 50 51 /** @var stdClass User with data. */ 52 protected $user2; 53 54 /** @var context context_module of an activity without grading definitions. */ 55 protected $instancecontext0; 56 57 /** @var context context_module of the activity where the grading definitions are. */ 58 protected $instancecontext1; 59 60 /** @var context context_module of the activity where the grading definitions are. */ 61 protected $instancecontext2; 62 63 /** 64 * Test getting the context for the user ID related to this plugin. 65 */ 66 public function test_get_contexts_for_userid() { 67 global $DB; 68 69 $this->resetAfterTest(); 70 $this->grading_setup_test_scenario_data(); 71 $this->assertCount(2, $DB->get_records('grading_definitions')); 72 73 // User1 has created grading definitions for instance1 and instance2. 74 $contextlist = provider::get_contexts_for_userid($this->user1->id); 75 $this->assertCount(2, $contextlist); 76 $this->assertContainsEquals($this->instancecontext1->id, $contextlist->get_contextids()); 77 $this->assertContainsEquals($this->instancecontext2->id, $contextlist->get_contextids()); 78 $this->assertNotContainsEquals($this->instancecontext0->id, $contextlist->get_contextids()); 79 80 // User2 has only modified grading definitions for instance2. 81 $contextlist = provider::get_contexts_for_userid($this->user2->id); 82 $this->assertCount(1, $contextlist); 83 $this->assertContainsEquals($this->instancecontext2->id, $contextlist->get_contextids()); 84 85 // User0 hasn't created or modified any grading definition. 86 $contextlist = provider::get_contexts_for_userid($this->user0->id); 87 $this->assertCount(0, $contextlist); 88 } 89 90 /** 91 * Test retrieval of user ids in a given context. 92 */ 93 public function test_get_users_in_context() { 94 $this->resetAfterTest(); 95 $this->grading_setup_test_scenario_data(); 96 // Instance two has one user who created the definitions and another who modified it. 97 $userlist = new \core_privacy\local\request\userlist($this->instancecontext2, 'core_grading'); 98 provider::get_users_in_context($userlist); 99 // Check that we get both. 100 $this->assertCount(2, $userlist->get_userids()); 101 } 102 103 /** 104 * Export for a user with no grading definitions created or modified will not have any data exported. 105 */ 106 public function test_export_user_data_no_content() { 107 $this->resetAfterTest(); 108 109 $user = $this->getDataGenerator()->create_user(); 110 $this->setUser($user); 111 $context = \context_system::instance(); 112 113 $writer = writer::with_context($context); 114 $this->assertFalse($writer->has_any_data()); 115 $this->export_context_data_for_user($user->id, $context, 'core_grading'); 116 $this->assertFalse(writer::with_context($context)->has_any_data()); 117 } 118 119 /** 120 * Test that data is exported correctly for this plugin. 121 */ 122 public function test_export_user_data() { 123 global $DB; 124 125 $this->resetAfterTest(); 126 $now = time(); 127 $defnameprefix = 'fakename'; 128 $this->grading_setup_test_scenario_data($defnameprefix, $now); 129 $this->assertCount(2, $DB->get_records('grading_definitions')); 130 131 // Validate exported data: instance1 - user0 has NO data. 132 $this->setUser($this->user0); 133 writer::reset(); 134 $writer = writer::with_context($this->instancecontext1); 135 $this->assertFalse($writer->has_any_data()); 136 $this->export_context_data_for_user($this->user0->id, $this->instancecontext1, 'core_grading'); 137 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 138 $this->assertEmpty($data); 139 140 // Validate exported data: instance0 - user1 has NO data. 141 $this->setUser($this->user1); 142 writer::reset(); 143 $writer = writer::with_context($this->instancecontext0); 144 $this->assertFalse($writer->has_any_data()); 145 $this->export_context_data_for_user($this->user1->id, $this->instancecontext0, 'core_grading'); 146 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 147 $this->assertEmpty($data); 148 149 // Validate exported data: instance1 - user1 has data (user has created and modified it). 150 writer::reset(); 151 $writer = writer::with_context($this->instancecontext1); 152 $this->assertFalse($writer->has_any_data()); 153 $this->export_context_data_for_user($this->user1->id, $this->instancecontext1, 'core_grading'); 154 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 155 $this->assertCount(1, $data->definitions); 156 157 $firstkey = reset($data->definitions); 158 $this->assertNotEmpty($firstkey->name); 159 $this->assertEquals('test_method', $firstkey->method); 160 $this->assertEquals(transform::datetime($now), $firstkey->timecreated); 161 $this->assertEquals($this->user1->id, $firstkey->usercreated); 162 $this->assertEquals($defnameprefix.'1', $firstkey->name); 163 164 // Validate exported data: instance2 - user1 has data (user has created it). 165 writer::reset(); 166 $writer = writer::with_context($this->instancecontext2); 167 $this->assertFalse($writer->has_any_data()); 168 $this->export_context_data_for_user($this->user1->id, $this->instancecontext2, 'core_grading'); 169 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 170 $this->assertCount(1, $data->definitions); 171 172 $firstkey = reset($data->definitions); 173 $this->assertNotEmpty($firstkey->name); 174 $this->assertEquals('test_method', $firstkey->method); 175 $this->assertEquals(transform::datetime($now), $firstkey->timecreated); 176 $this->assertEquals($this->user1->id, $firstkey->usercreated); 177 $this->assertEquals($defnameprefix.'2', $firstkey->name); 178 179 // Validate exported data: instance1 - user2 has NO data. 180 $this->setUser($this->user2); 181 writer::reset(); 182 $writer = writer::with_context($this->instancecontext1); 183 $this->assertFalse($writer->has_any_data()); 184 $this->export_context_data_for_user($this->user2->id, $this->instancecontext1, 'core_grading'); 185 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 186 $this->assertEmpty($data); 187 188 // Validate exported data: instance2 - user2 has data (user has modified it). 189 $this->setUser($this->user2); 190 writer::reset(); 191 $writer = writer::with_context($this->instancecontext2); 192 $this->assertFalse($writer->has_any_data()); 193 $this->export_context_data_for_user($this->user2->id, $this->instancecontext2, 'core_grading'); 194 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 195 $this->assertCount(1, $data->definitions); 196 } 197 198 /** 199 * Test for provider::delete_data_for_all_users_in_context(). 200 */ 201 public function test_delete_data_for_all_users_in_context() { 202 global $DB; 203 204 $this->resetAfterTest(); 205 $this->grading_setup_test_scenario_data(); 206 207 // Before deletion, we should have 2 grading_definitions. 208 $this->assertCount(2, $DB->get_records('grading_definitions')); 209 210 // Delete data. 211 provider::delete_data_for_all_users_in_context($this->instancecontext0); 212 provider::delete_data_for_all_users_in_context($this->instancecontext1); 213 provider::delete_data_for_all_users_in_context($this->instancecontext2); 214 215 // Before deletion, we should have same grading_definitions (nothing was deleted). 216 $this->assertCount(2, $DB->get_records('grading_definitions')); 217 } 218 219 /** 220 * Test for provider::delete_data_for_user(). 221 */ 222 public function test_delete_data_for_user() { 223 global $DB; 224 225 $this->resetAfterTest(); 226 $this->grading_setup_test_scenario_data(); 227 228 // Before deletion, we should have 2 grading_definitions. 229 $this->assertCount(2, $DB->get_records('grading_definitions')); 230 231 // Delete data for $user0. 232 $contextlist = provider::get_contexts_for_userid($this->user0->id); 233 $approvedcontextlist = new approved_contextlist( 234 $this->user0, 235 'core_grading', 236 $contextlist->get_contextids() 237 ); 238 provider::delete_data_for_user($approvedcontextlist); 239 240 // Delete data for $user1. 241 $contextlist = provider::get_contexts_for_userid($this->user1->id); 242 $approvedcontextlist = new approved_contextlist( 243 $this->user1, 244 'core_grading', 245 $contextlist->get_contextids() 246 ); 247 provider::delete_data_for_user($approvedcontextlist); 248 249 // Delete data for $user2. 250 $contextlist = provider::get_contexts_for_userid($this->user2->id); 251 $approvedcontextlist = new approved_contextlist( 252 $this->user2, 253 'core_grading', 254 $contextlist->get_contextids() 255 ); 256 provider::delete_data_for_user($approvedcontextlist); 257 258 // Before deletion, we should have same grading_definitions (nothing was deleted). 259 $this->assertCount(2, $DB->get_records('grading_definitions')); 260 } 261 262 /** 263 * Test exporting user data relating to an item ID. 264 */ 265 public function test_export_item_data() { 266 global $DB; 267 $this->resetAfterTest(); 268 $course = $this->getDataGenerator()->create_course(); 269 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 270 $user = $this->getDataGenerator()->create_user(); 271 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 272 273 $this->setUser($user); 274 275 $modulecontext = \context_module::instance($module->cmid); 276 $controller = $guidegenerator->get_test_guide($modulecontext); 277 278 // In the situation of mod_assign this would be the id from assign_grades. 279 $itemid = 1; 280 $instance = $controller->create_instance($user->id, $itemid); 281 $data = $guidegenerator->get_test_form_data( 282 $controller, 283 $itemid, 284 5, 'This user made several mistakes.', 285 10, 'This user has two pictures.' 286 ); 287 288 $instance->update($data); 289 $instanceid = $instance->get_data('id'); 290 291 provider::export_item_data($modulecontext, $itemid, ['Test']); 292 $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide', $instance->get_data('id')]); 293 $this->assertCount(2, $data); 294 $this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark); 295 $this->assertEquals(5, $data['Spelling mistakes']->score); 296 $this->assertEquals('This user has two pictures.', $data['Pictures']->remark); 297 $this->assertEquals(10, $data['Pictures']->score); 298 } 299 300 /** 301 * Test deleting user data related to a context and item ID. 302 */ 303 public function test_delete_instance_data() { 304 global $DB; 305 $this->resetAfterTest(); 306 $course = $this->getDataGenerator()->create_course(); 307 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 308 $user = $this->getDataGenerator()->create_user(); 309 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 310 311 $this->setUser($user); 312 313 $modulecontext = \context_module::instance($module->cmid); 314 $controller = $guidegenerator->get_test_guide($modulecontext); 315 316 // In the situation of mod_assign this would be the id from assign_grades. 317 $itemid = 1; 318 $instance = $controller->create_instance($user->id, $itemid); 319 $data = $guidegenerator->get_test_form_data( 320 $controller, 321 $itemid, 322 5, 'This user made several mistakes.', 323 10, 'This user has two pictures.' 324 ); 325 $instance->update($data); 326 327 $itemid = 2; 328 $instance = $controller->create_instance($user->id, $itemid); 329 $data = $guidegenerator->get_test_form_data( 330 $controller, 331 $itemid, 332 25, 'This user made no mistakes.', 333 5, 'This user has one picture.' 334 ); 335 $instance->update($data); 336 337 // Check how many records we have in the fillings table. 338 $records = $DB->get_records('gradingform_guide_fillings'); 339 $this->assertCount(4, $records); 340 // Let's delete one of the instances (the last one would be the easiest). 341 provider::delete_instance_data($modulecontext, $itemid); 342 $records = $DB->get_records('gradingform_guide_fillings'); 343 $this->assertCount(2, $records); 344 foreach ($records as $record) { 345 $this->assertNotEquals($instance->get_id(), $record->instanceid); 346 } 347 // This will delete all the rest of the instances for this context. 348 provider::delete_instance_data($modulecontext); 349 $records = $DB->get_records('gradingform_guide_fillings'); 350 $this->assertEmpty($records); 351 } 352 353 /** 354 * Test the deletion of multiple instances at once. 355 */ 356 public function test_delete_data_for_instances() { 357 global $DB; 358 $this->resetAfterTest(); 359 $course = $this->getDataGenerator()->create_course(); 360 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 361 $user1 = $this->getDataGenerator()->create_user(); 362 $user2 = $this->getDataGenerator()->create_user(); 363 $user3 = $this->getDataGenerator()->create_user(); 364 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 365 366 $this->setUser($user1); 367 368 $modulecontext = \context_module::instance($module->cmid); 369 $controller = $guidegenerator->get_test_guide($modulecontext); 370 371 // In the situation of mod_assign this would be the id from assign_grades. 372 $itemid1 = 1; 373 $instance1 = $controller->create_instance($user1->id, $itemid1); 374 $data = $guidegenerator->get_test_form_data( 375 $controller, 376 $itemid1, 377 5, 'This user made several mistakes.', 378 10, 'This user has two pictures.' 379 ); 380 $instance1->update($data); 381 382 $itemid2 = 2; 383 $instance2 = $controller->create_instance($user2->id, $itemid2); 384 $data = $guidegenerator->get_test_form_data( 385 $controller, 386 $itemid2, 387 15, 'This user made a couple of mistakes.', 388 10, 'This user has one picture.' 389 ); 390 $instance2->update($data); 391 392 $itemid3 = 3; 393 $instance3 = $controller->create_instance($user3->id, $itemid3); 394 $data = $guidegenerator->get_test_form_data( 395 $controller, 396 $itemid3, 397 20, 'This user made one mistakes.', 398 10, 'This user has one picture.' 399 ); 400 $instance3->update($data); 401 402 $records = $DB->get_records('gradingform_guide_fillings'); 403 $this->assertCount(6, $records); 404 405 // Delete all user data for items 1 and 3. 406 provider::delete_data_for_instances($modulecontext, [$itemid1, $itemid3]); 407 408 $records = $DB->get_records('gradingform_guide_fillings'); 409 $this->assertCount(2, $records); 410 $instanceid = $instance2->get_data('id'); 411 // The instance id should match for all remaining records. 412 foreach ($records as $record) { 413 $this->assertEquals($instanceid, $record->instanceid); 414 } 415 } 416 417 /** 418 * Helper function to setup the environment. 419 * 420 * course 421 * | 422 * +--instance0 (assignment) 423 * | | 424 * +--instance1 (assignment) 425 * | | 426 * | +--grading_definition1 (created and modified by user1) 427 * | | 428 * +--instance2 (assignment) 429 * | | 430 * | +--grading_definition2 (created by user1 and modified by user2) 431 * 432 * 433 * user0 hasn't any data. 434 * 435 * @param string $defnameprefix 436 * @param timestamp $now 437 */ 438 protected function grading_setup_test_scenario_data($defnameprefix = null, $now = null) { 439 global $DB; 440 441 $this->user0 = $this->getDataGenerator()->create_user(); 442 $this->user1 = $this->getDataGenerator()->create_user(); 443 $this->user2 = $this->getDataGenerator()->create_user(); 444 445 // Create a course. 446 $course = $this->getDataGenerator()->create_course(); 447 $coursecontext = \context_course::instance($course->id); 448 449 // Create some assignment instances. 450 $params = (object)array( 451 'course' => $course->id, 452 'name' => 'Testing instance' 453 ); 454 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 455 $instance0 = $generator->create_instance($params); 456 $cm0 = get_coursemodule_from_instance('assign', $instance0->id); 457 $this->instancecontext0 = \context_module::instance($cm0->id); 458 $instance1 = $generator->create_instance($params); 459 $cm1 = get_coursemodule_from_instance('assign', $instance1->id); 460 $this->instancecontext1 = \context_module::instance($cm1->id); 461 $instance2 = $generator->create_instance($params); 462 $cm2 = get_coursemodule_from_instance('assign', $instance2->id); 463 $this->instancecontext2 = \context_module::instance($cm2->id); 464 465 // Create fake grading areas. 466 $fakearea1 = (object)array( 467 'contextid' => $this->instancecontext1->id, 468 'component' => 'mod_assign', 469 'areaname' => 'submissions', 470 'activemethod' => 'test_method' 471 ); 472 $fakeareaid1 = $DB->insert_record('grading_areas', $fakearea1); 473 $fakearea2 = clone($fakearea1); 474 $fakearea2->contextid = $this->instancecontext2->id; 475 $fakeareaid2 = $DB->insert_record('grading_areas', $fakearea2); 476 477 // Create fake grading definitions. 478 if (empty($now)) { 479 $now = time(); 480 } 481 if (empty($defnameprefix)) { 482 $defnameprefix = 'fakename'; 483 } 484 $fakedefinition1 = (object)array( 485 'areaid' => $fakeareaid1, 486 'method' => 'test_method', 487 'name' => $defnameprefix.'1', 488 'status' => 0, 489 'timecreated' => $now, 490 'usercreated' => $this->user1->id, 491 'timemodified' => $now + 1, 492 'usermodified' => $this->user1->id, 493 ); 494 $fakedefid1 = $DB->insert_record('grading_definitions', $fakedefinition1); 495 $fakedefinition2 = clone($fakedefinition1); 496 $fakedefinition2->areaid = $fakeareaid2; 497 $fakedefinition2->name = $defnameprefix.'2'; 498 $fakedefinition2->usermodified = $this->user2->id; 499 $fakedefid2 = $DB->insert_record('grading_definitions', $fakedefinition2); 500 } 501 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body