Differences Between: [Versions 311 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 /** @var \core_privacy\tests\request\content_writer $writer */ 114 $writer = writer::with_context($context); 115 $this->assertFalse($writer->has_any_data()); 116 $this->export_context_data_for_user($user->id, $context, 'core_grading'); 117 $this->assertFalse(writer::with_context($context)->has_any_data()); 118 } 119 120 /** 121 * Test that data is exported correctly for this plugin. 122 */ 123 public function test_export_user_data() { 124 global $DB; 125 126 $this->resetAfterTest(); 127 $now = time(); 128 $defnameprefix = 'fakename'; 129 $this->grading_setup_test_scenario_data($defnameprefix, $now); 130 $this->assertCount(2, $DB->get_records('grading_definitions')); 131 132 // Validate exported data: instance1 - user0 has NO data. 133 $this->setUser($this->user0); 134 writer::reset(); 135 $writer = writer::with_context($this->instancecontext1); 136 $this->assertFalse($writer->has_any_data()); 137 $this->export_context_data_for_user($this->user0->id, $this->instancecontext1, 'core_grading'); 138 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 139 $this->assertEmpty($data); 140 141 // Validate exported data: instance0 - user1 has NO data. 142 $this->setUser($this->user1); 143 writer::reset(); 144 $writer = writer::with_context($this->instancecontext0); 145 $this->assertFalse($writer->has_any_data()); 146 $this->export_context_data_for_user($this->user1->id, $this->instancecontext0, 'core_grading'); 147 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 148 $this->assertEmpty($data); 149 150 // Validate exported data: instance1 - user1 has data (user has created and modified it). 151 writer::reset(); 152 $writer = writer::with_context($this->instancecontext1); 153 $this->assertFalse($writer->has_any_data()); 154 $this->export_context_data_for_user($this->user1->id, $this->instancecontext1, 'core_grading'); 155 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 156 $this->assertCount(1, $data->definitions); 157 158 $firstkey = reset($data->definitions); 159 $this->assertNotEmpty($firstkey->name); 160 $this->assertEquals('test_method', $firstkey->method); 161 $this->assertEquals(transform::datetime($now), $firstkey->timecreated); 162 $this->assertEquals($this->user1->id, $firstkey->usercreated); 163 $this->assertEquals($defnameprefix.'1', $firstkey->name); 164 165 // Validate exported data: instance2 - user1 has data (user has created it). 166 writer::reset(); 167 $writer = writer::with_context($this->instancecontext2); 168 $this->assertFalse($writer->has_any_data()); 169 $this->export_context_data_for_user($this->user1->id, $this->instancecontext2, 'core_grading'); 170 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 171 $this->assertCount(1, $data->definitions); 172 173 $firstkey = reset($data->definitions); 174 $this->assertNotEmpty($firstkey->name); 175 $this->assertEquals('test_method', $firstkey->method); 176 $this->assertEquals(transform::datetime($now), $firstkey->timecreated); 177 $this->assertEquals($this->user1->id, $firstkey->usercreated); 178 $this->assertEquals($defnameprefix.'2', $firstkey->name); 179 180 // Validate exported data: instance1 - user2 has NO data. 181 $this->setUser($this->user2); 182 writer::reset(); 183 $writer = writer::with_context($this->instancecontext1); 184 $this->assertFalse($writer->has_any_data()); 185 $this->export_context_data_for_user($this->user2->id, $this->instancecontext1, 'core_grading'); 186 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 187 $this->assertEmpty($data); 188 189 // Validate exported data: instance2 - user2 has data (user has modified it). 190 $this->setUser($this->user2); 191 writer::reset(); 192 $writer = writer::with_context($this->instancecontext2); 193 $this->assertFalse($writer->has_any_data()); 194 $this->export_context_data_for_user($this->user2->id, $this->instancecontext2, 'core_grading'); 195 $data = $writer->get_data([get_string('gradingmethod', 'grading')]); 196 $this->assertCount(1, $data->definitions); 197 } 198 199 /** 200 * Test for provider::delete_data_for_all_users_in_context(). 201 */ 202 public function test_delete_data_for_all_users_in_context() { 203 global $DB; 204 205 $this->resetAfterTest(); 206 $this->grading_setup_test_scenario_data(); 207 208 // Before deletion, we should have 2 grading_definitions. 209 $this->assertCount(2, $DB->get_records('grading_definitions')); 210 211 // Delete data. 212 provider::delete_data_for_all_users_in_context($this->instancecontext0); 213 provider::delete_data_for_all_users_in_context($this->instancecontext1); 214 provider::delete_data_for_all_users_in_context($this->instancecontext2); 215 216 // Before deletion, we should have same grading_definitions (nothing was deleted). 217 $this->assertCount(2, $DB->get_records('grading_definitions')); 218 } 219 220 /** 221 * Test for provider::delete_data_for_user(). 222 */ 223 public function test_delete_data_for_user() { 224 global $DB; 225 226 $this->resetAfterTest(); 227 $this->grading_setup_test_scenario_data(); 228 229 // Before deletion, we should have 2 grading_definitions. 230 $this->assertCount(2, $DB->get_records('grading_definitions')); 231 232 // Delete data for $user0. 233 $contextlist = provider::get_contexts_for_userid($this->user0->id); 234 $approvedcontextlist = new approved_contextlist( 235 $this->user0, 236 'core_grading', 237 $contextlist->get_contextids() 238 ); 239 provider::delete_data_for_user($approvedcontextlist); 240 241 // Delete data for $user1. 242 $contextlist = provider::get_contexts_for_userid($this->user1->id); 243 $approvedcontextlist = new approved_contextlist( 244 $this->user1, 245 'core_grading', 246 $contextlist->get_contextids() 247 ); 248 provider::delete_data_for_user($approvedcontextlist); 249 250 // Delete data for $user2. 251 $contextlist = provider::get_contexts_for_userid($this->user2->id); 252 $approvedcontextlist = new approved_contextlist( 253 $this->user2, 254 'core_grading', 255 $contextlist->get_contextids() 256 ); 257 provider::delete_data_for_user($approvedcontextlist); 258 259 // Before deletion, we should have same grading_definitions (nothing was deleted). 260 $this->assertCount(2, $DB->get_records('grading_definitions')); 261 } 262 263 /** 264 * Test exporting user data relating to an item ID. 265 */ 266 public function test_export_item_data() { 267 global $DB; 268 $this->resetAfterTest(); 269 $course = $this->getDataGenerator()->create_course(); 270 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 271 $user = $this->getDataGenerator()->create_user(); 272 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 273 274 $this->setUser($user); 275 276 $modulecontext = \context_module::instance($module->cmid); 277 $controller = $guidegenerator->get_test_guide($modulecontext); 278 279 // In the situation of mod_assign this would be the id from assign_grades. 280 $itemid = 1; 281 $instance = $controller->create_instance($user->id, $itemid); 282 $data = $guidegenerator->get_test_form_data( 283 $controller, 284 $itemid, 285 5, 'This user made several mistakes.', 286 10, 'This user has two pictures.' 287 ); 288 289 $instance->update($data); 290 $instanceid = $instance->get_data('id'); 291 292 provider::export_item_data($modulecontext, $itemid, ['Test']); 293 $data = (array) writer::with_context($modulecontext)->get_data(['Test', 'Marking guide', $instance->get_data('id')]); 294 $this->assertCount(2, $data); 295 $this->assertEquals('This user made several mistakes.', $data['Spelling mistakes']->remark); 296 $this->assertEquals(5, $data['Spelling mistakes']->score); 297 $this->assertEquals('This user has two pictures.', $data['Pictures']->remark); 298 $this->assertEquals(10, $data['Pictures']->score); 299 } 300 301 /** 302 * Test deleting user data related to a context and item ID. 303 */ 304 public function test_delete_instance_data() { 305 global $DB; 306 $this->resetAfterTest(); 307 $course = $this->getDataGenerator()->create_course(); 308 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 309 $user = $this->getDataGenerator()->create_user(); 310 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 311 312 $this->setUser($user); 313 314 $modulecontext = \context_module::instance($module->cmid); 315 $controller = $guidegenerator->get_test_guide($modulecontext); 316 317 // In the situation of mod_assign this would be the id from assign_grades. 318 $itemid = 1; 319 $instance = $controller->create_instance($user->id, $itemid); 320 $data = $guidegenerator->get_test_form_data( 321 $controller, 322 $itemid, 323 5, 'This user made several mistakes.', 324 10, 'This user has two pictures.' 325 ); 326 $instance->update($data); 327 328 $itemid = 2; 329 $instance = $controller->create_instance($user->id, $itemid); 330 $data = $guidegenerator->get_test_form_data( 331 $controller, 332 $itemid, 333 25, 'This user made no mistakes.', 334 5, 'This user has one picture.' 335 ); 336 $instance->update($data); 337 338 // Check how many records we have in the fillings table. 339 $records = $DB->get_records('gradingform_guide_fillings'); 340 $this->assertCount(4, $records); 341 // Let's delete one of the instances (the last one would be the easiest). 342 provider::delete_instance_data($modulecontext, $itemid); 343 $records = $DB->get_records('gradingform_guide_fillings'); 344 $this->assertCount(2, $records); 345 foreach ($records as $record) { 346 $this->assertNotEquals($instance->get_id(), $record->instanceid); 347 } 348 // This will delete all the rest of the instances for this context. 349 provider::delete_instance_data($modulecontext); 350 $records = $DB->get_records('gradingform_guide_fillings'); 351 $this->assertEmpty($records); 352 } 353 354 /** 355 * Test the deletion of multiple instances at once. 356 */ 357 public function test_delete_data_for_instances() { 358 global $DB; 359 $this->resetAfterTest(); 360 $course = $this->getDataGenerator()->create_course(); 361 $module = $this->getDataGenerator()->create_module('assign', ['course' => $course]); 362 $user1 = $this->getDataGenerator()->create_user(); 363 $user2 = $this->getDataGenerator()->create_user(); 364 $user3 = $this->getDataGenerator()->create_user(); 365 $guidegenerator = \testing_util::get_data_generator()->get_plugin_generator('gradingform_guide'); 366 367 $this->setUser($user1); 368 369 $modulecontext = \context_module::instance($module->cmid); 370 $controller = $guidegenerator->get_test_guide($modulecontext); 371 372 // In the situation of mod_assign this would be the id from assign_grades. 373 $itemid1 = 1; 374 $instance1 = $controller->create_instance($user1->id, $itemid1); 375 $data = $guidegenerator->get_test_form_data( 376 $controller, 377 $itemid1, 378 5, 'This user made several mistakes.', 379 10, 'This user has two pictures.' 380 ); 381 $instance1->update($data); 382 383 $itemid2 = 2; 384 $instance2 = $controller->create_instance($user2->id, $itemid2); 385 $data = $guidegenerator->get_test_form_data( 386 $controller, 387 $itemid2, 388 15, 'This user made a couple of mistakes.', 389 10, 'This user has one picture.' 390 ); 391 $instance2->update($data); 392 393 $itemid3 = 3; 394 $instance3 = $controller->create_instance($user3->id, $itemid3); 395 $data = $guidegenerator->get_test_form_data( 396 $controller, 397 $itemid3, 398 20, 'This user made one mistakes.', 399 10, 'This user has one picture.' 400 ); 401 $instance3->update($data); 402 403 $records = $DB->get_records('gradingform_guide_fillings'); 404 $this->assertCount(6, $records); 405 406 // Delete all user data for items 1 and 3. 407 provider::delete_data_for_instances($modulecontext, [$itemid1, $itemid3]); 408 409 $records = $DB->get_records('gradingform_guide_fillings'); 410 $this->assertCount(2, $records); 411 $instanceid = $instance2->get_data('id'); 412 // The instance id should match for all remaining records. 413 foreach ($records as $record) { 414 $this->assertEquals($instanceid, $record->instanceid); 415 } 416 } 417 418 /** 419 * Helper function to setup the environment. 420 * 421 * course 422 * | 423 * +--instance0 (assignment) 424 * | | 425 * +--instance1 (assignment) 426 * | | 427 * | +--grading_definition1 (created and modified by user1) 428 * | | 429 * +--instance2 (assignment) 430 * | | 431 * | +--grading_definition2 (created by user1 and modified by user2) 432 * 433 * 434 * user0 hasn't any data. 435 * 436 * @param string $defnameprefix 437 * @param timestamp $now 438 */ 439 protected function grading_setup_test_scenario_data($defnameprefix = null, $now = null) { 440 global $DB; 441 442 $this->user0 = $this->getDataGenerator()->create_user(); 443 $this->user1 = $this->getDataGenerator()->create_user(); 444 $this->user2 = $this->getDataGenerator()->create_user(); 445 446 // Create a course. 447 $course = $this->getDataGenerator()->create_course(); 448 $coursecontext = \context_course::instance($course->id); 449 450 // Create some assignment instances. 451 $params = (object)array( 452 'course' => $course->id, 453 'name' => 'Testing instance' 454 ); 455 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 456 $instance0 = $generator->create_instance($params); 457 $cm0 = get_coursemodule_from_instance('assign', $instance0->id); 458 $this->instancecontext0 = \context_module::instance($cm0->id); 459 $instance1 = $generator->create_instance($params); 460 $cm1 = get_coursemodule_from_instance('assign', $instance1->id); 461 $this->instancecontext1 = \context_module::instance($cm1->id); 462 $instance2 = $generator->create_instance($params); 463 $cm2 = get_coursemodule_from_instance('assign', $instance2->id); 464 $this->instancecontext2 = \context_module::instance($cm2->id); 465 466 // Create fake grading areas. 467 $fakearea1 = (object)array( 468 'contextid' => $this->instancecontext1->id, 469 'component' => 'mod_assign', 470 'areaname' => 'submissions', 471 'activemethod' => 'test_method' 472 ); 473 $fakeareaid1 = $DB->insert_record('grading_areas', $fakearea1); 474 $fakearea2 = clone($fakearea1); 475 $fakearea2->contextid = $this->instancecontext2->id; 476 $fakeareaid2 = $DB->insert_record('grading_areas', $fakearea2); 477 478 // Create fake grading definitions. 479 if (empty($now)) { 480 $now = time(); 481 } 482 if (empty($defnameprefix)) { 483 $defnameprefix = 'fakename'; 484 } 485 $fakedefinition1 = (object)array( 486 'areaid' => $fakeareaid1, 487 'method' => 'test_method', 488 'name' => $defnameprefix.'1', 489 'status' => 0, 490 'timecreated' => $now, 491 'usercreated' => $this->user1->id, 492 'timemodified' => $now + 1, 493 'usermodified' => $this->user1->id, 494 ); 495 $fakedefid1 = $DB->insert_record('grading_definitions', $fakedefinition1); 496 $fakedefinition2 = clone($fakedefinition1); 497 $fakedefinition2->areaid = $fakeareaid2; 498 $fakedefinition2->name = $defnameprefix.'2'; 499 $fakedefinition2->usermodified = $this->user2->id; 500 $fakedefid2 = $DB->insert_record('grading_definitions', $fakedefinition2); 501 } 502 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body