Differences Between: [Versions 39 and 310]
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 * Data provider tests. 19 * 20 * @package core_grades 21 * @category test 22 * @copyright 2018 Frédéric Massart 23 * @author Frédéric Massart <fred@branchup.tech> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 global $CFG; 29 30 use core_privacy\tests\provider_testcase; 31 use core_privacy\local\request\approved_contextlist; 32 use core_privacy\local\request\transform; 33 use core_privacy\local\request\writer; 34 use core_grades\privacy\provider; 35 36 require_once($CFG->libdir . '/gradelib.php'); 37 38 /** 39 * Data provider testcase class. 40 * 41 * @package core_grades 42 * @category test 43 * @copyright 2018 Frédéric Massart 44 * @author Frédéric Massart <fred@branchup.tech> 45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 46 */ 47 class core_grades_privacy_testcase extends provider_testcase { 48 49 public function setUp(): void { 50 global $PAGE; 51 $this->resetAfterTest(); 52 $PAGE->get_renderer('core'); 53 } 54 55 public function test_get_contexts_for_userid_gradebook_edits() { 56 $dg = $this->getDataGenerator(); 57 58 $c1 = $dg->create_course(); 59 $c2 = $dg->create_course(); 60 61 $u1 = $dg->create_user(); 62 $u2 = $dg->create_user(); 63 $u3 = $dg->create_user(); 64 $u4 = $dg->create_user(); 65 $u5 = $dg->create_user(); 66 $u6 = $dg->create_user(); 67 $u7 = $dg->create_user(); 68 $u8 = $dg->create_user(); 69 $u9 = $dg->create_user(); 70 $u10 = $dg->create_user(); 71 $u11 = $dg->create_user(); 72 73 $sysctx = context_system::instance(); 74 $c1ctx = context_course::instance($c1->id); 75 $c2ctx = context_course::instance($c2->id); 76 77 // Create some stuff. 78 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 79 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 80 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 81 $gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 82 $gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 83 $gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false); 84 $go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2', 85 'fullname' => 'go2']), false); 86 87 // Nothing as of now. 88 foreach ([$u1, $u2, $u3, $u4, $u5, $u6, $u7, $u8, $u9, $u10, $u11] as $u) { 89 $contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids()); 90 $this->assertEmpty($contexts); 91 } 92 93 $go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]); 94 $go0->insert(); 95 $go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]); 96 $go1->insert(); 97 98 // Create scales. 99 $s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']); 100 $s1->insert(); 101 $s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']); 102 $s2->insert(); 103 104 // User 2 creates history. 105 $this->setUser($u2); 106 $go0->shortname .= ' edited'; 107 $go0->update(); 108 $gc1a->fullname .= ' edited'; 109 $gc1a->update(); 110 111 // User 3 creates history. 112 $this->setUser($u3); 113 $go1->shortname .= ' edited'; 114 $go1->update(); 115 $gc2a->fullname .= ' a'; 116 $gc2a->update(); 117 118 // User 4 updates an outcome in course (creates history). 119 $this->setUser($u4); 120 $go2->shortname .= ' edited'; 121 $go2->update(); 122 123 // User 5 updates an item. 124 $this->setUser($u5); 125 $gi1a->itemname .= ' edited'; 126 $gi1a->update(); 127 128 // User 6 creates history. 129 $this->setUser($u6); 130 $gi2a->delete(); 131 132 // User 9 creates history. 133 $this->setUser($u9); 134 $s1->name .= ' edited'; 135 $s1->update(); 136 137 // Assert contexts. 138 $contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids()); 139 $this->assertCount(1, $contexts); 140 $this->assertArrayHasKey($sysctx->id, $contexts); 141 $contexts = array_flip(provider::get_contexts_for_userid($u11->id)->get_contextids()); 142 $this->assertCount(1, $contexts); 143 $this->assertArrayHasKey($c1ctx->id, $contexts); 144 $contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids()); 145 $this->assertCount(2, $contexts); 146 $this->assertArrayHasKey($sysctx->id, $contexts); 147 $this->assertArrayHasKey($c1ctx->id, $contexts); 148 $contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids()); 149 $this->assertCount(2, $contexts); 150 $this->assertArrayHasKey($c1ctx->id, $contexts); 151 $this->assertArrayHasKey($c2ctx->id, $contexts); 152 $contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids()); 153 $this->assertCount(1, $contexts); 154 $this->assertArrayHasKey($c2ctx->id, $contexts); 155 $contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids()); 156 $this->assertCount(1, $contexts); 157 $this->assertArrayHasKey($c1ctx->id, $contexts); 158 $contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids()); 159 $this->assertCount(1, $contexts); 160 $this->assertArrayHasKey($c2ctx->id, $contexts); 161 $contexts = array_flip(provider::get_contexts_for_userid($u7->id)->get_contextids()); 162 $this->assertCount(1, $contexts); 163 $this->assertArrayHasKey($sysctx->id, $contexts); 164 $contexts = array_flip(provider::get_contexts_for_userid($u8->id)->get_contextids()); 165 $this->assertCount(1, $contexts); 166 $this->assertArrayHasKey($c1ctx->id, $contexts); 167 $contexts = array_flip(provider::get_contexts_for_userid($u9->id)->get_contextids()); 168 $this->assertCount(1, $contexts); 169 $this->assertArrayHasKey($sysctx->id, $contexts); 170 171 // User 10 creates history. 172 $this->setUser($u10); 173 $s2->delete(); 174 175 $contexts = array_flip(provider::get_contexts_for_userid($u10->id)->get_contextids()); 176 $this->assertCount(1, $contexts); 177 $this->assertArrayHasKey($c1ctx->id, $contexts); 178 } 179 180 public function test_get_contexts_for_userid_grades_and_history() { 181 $dg = $this->getDataGenerator(); 182 183 $c1 = $dg->create_course(); 184 $c2 = $dg->create_course(); 185 186 $u1 = $dg->create_user(); 187 $u2 = $dg->create_user(); 188 $u3 = $dg->create_user(); 189 $u4 = $dg->create_user(); 190 $u5 = $dg->create_user(); 191 $u6 = $dg->create_user(); 192 193 $sysctx = context_system::instance(); 194 $c1ctx = context_course::instance($c1->id); 195 $c2ctx = context_course::instance($c2->id); 196 197 // Create some stuff. 198 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 199 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 200 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 201 $gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 202 203 // Nothing as of now. 204 foreach ([$u1, $u2, $u3, $u4, $u5, $u6] as $u) { 205 $contexts = array_flip(provider::get_contexts_for_userid($u->id)->get_contextids()); 206 $this->assertEmpty($contexts); 207 } 208 209 // User 1 is graded in course 1. 210 $gi1a->update_final_grade($u1->id, 1, 'test'); 211 212 // User 2 is graded in course 2. 213 $gi2a->update_final_grade($u2->id, 10, 'test'); 214 215 // User 3 is set as modifier. 216 $gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id); 217 218 // User 4 is set as modifier, and creates history.. 219 $this->setUser($u4); 220 $gi1a->update_final_grade($u2->id, 1, 'test'); 221 222 // User 5 creates history, user 6 is the known modifier, and we delete the item. 223 $this->setUser($u5); 224 $gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id); 225 $gi2b->delete(); 226 227 // Assert contexts. 228 $contexts = array_flip(provider::get_contexts_for_userid($u1->id)->get_contextids()); 229 $this->assertCount(1, $contexts); 230 $this->assertArrayHasKey($c1ctx->id, $contexts); 231 $contexts = array_flip(provider::get_contexts_for_userid($u2->id)->get_contextids()); 232 $this->assertCount(3, $contexts); 233 $this->assertArrayHasKey($c1ctx->id, $contexts); 234 $this->assertArrayHasKey($c2ctx->id, $contexts); 235 $this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts); 236 $contexts = array_flip(provider::get_contexts_for_userid($u3->id)->get_contextids()); 237 $this->assertCount(1, $contexts); 238 $this->assertArrayHasKey($c1ctx->id, $contexts); 239 $contexts = array_flip(provider::get_contexts_for_userid($u4->id)->get_contextids()); 240 $this->assertCount(1, $contexts); 241 $this->assertArrayHasKey($c1ctx->id, $contexts); 242 $contexts = array_flip(provider::get_contexts_for_userid($u5->id)->get_contextids()); 243 $this->assertCount(2, $contexts); 244 $this->assertArrayHasKey($c2ctx->id, $contexts); 245 $this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts); 246 $contexts = array_flip(provider::get_contexts_for_userid($u6->id)->get_contextids()); 247 $this->assertCount(1, $contexts); 248 $this->assertArrayHasKey(context_user::instance($u2->id)->id, $contexts); 249 } 250 251 /** 252 * Test that the appropriate user IDs are returned for a given context. 253 */ 254 public function test_get_users_in_context_gradebook_edits() { 255 $dg = $this->getDataGenerator(); 256 257 $c1 = $dg->create_course(); 258 $c2 = $dg->create_course(); 259 260 $u1 = $dg->create_user(); 261 $u2 = $dg->create_user(); 262 $u3 = $dg->create_user(); 263 $u4 = $dg->create_user(); 264 $u5 = $dg->create_user(); 265 $u6 = $dg->create_user(); 266 $u7 = $dg->create_user(); 267 $u8 = $dg->create_user(); 268 $u9 = $dg->create_user(); 269 $u10 = $dg->create_user(); 270 $u11 = $dg->create_user(); 271 272 $sysctx = context_system::instance(); 273 $c1ctx = context_course::instance($c1->id); 274 $c2ctx = context_course::instance($c2->id); 275 276 // Create some stuff. 277 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 278 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 279 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 280 $gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 281 $gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 282 $gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false); 283 $go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2', 284 'fullname' => 'go2']), false); 285 286 $go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]); 287 $go0->insert(); 288 $go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u11->id]); 289 $go1->insert(); 290 291 // Create scales. 292 $s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']); 293 $s1->insert(); 294 $s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']); 295 $s2->insert(); 296 297 // User 2 creates history. 298 $this->setUser($u2); 299 $go0->shortname .= ' edited'; 300 $go0->update(); 301 $gc1a->fullname .= ' edited'; 302 $gc1a->update(); 303 304 // User 3 creates history. 305 $this->setUser($u3); 306 $go1->shortname .= ' edited'; 307 $go1->update(); 308 $gc2a->fullname .= ' a'; 309 $gc2a->update(); 310 311 // User 4 updates an outcome in course (creates history). 312 $this->setUser($u4); 313 $go2->shortname .= ' edited'; 314 $go2->update(); 315 316 // User 5 updates an item. 317 $this->setUser($u5); 318 $gi1a->itemname .= ' edited'; 319 $gi1a->update(); 320 321 // User 6 creates history. 322 $this->setUser($u6); 323 $gi2a->delete(); 324 325 // User 9 creates history. 326 $this->setUser($u9); 327 $s1->name .= ' edited'; 328 $s1->update(); 329 330 $userlist = new \core_privacy\local\request\userlist($sysctx, 'core_grades'); 331 provider::get_users_in_context($userlist); 332 $systemcontextuserids = [$u1->id, $u2->id, $u7->id, $u9->id]; 333 $this->assertEquals($systemcontextuserids, $userlist->get_userids()); 334 335 $userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades'); 336 provider::get_users_in_context($userlist); 337 $course1userids = [$u11->id, $u3->id, $u8->id, $u5->id, $u2->id]; 338 $this->assertEquals($course1userids, $userlist->get_userids()); 339 340 $userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades'); 341 provider::get_users_in_context($userlist); 342 $course2userids = [$u4->id, $u6->id, $u3->id]; 343 $this->assertEquals($course2userids, $userlist->get_userids()); 344 } 345 346 /** 347 * Test that the appropriate user IDs are returned for a given context. 348 */ 349 public function test_get_users_in_context_grades_and_history() { 350 $dg = $this->getDataGenerator(); 351 352 $c1 = $dg->create_course(); 353 $c2 = $dg->create_course(); 354 355 $u1 = $dg->create_user(); 356 $u2 = $dg->create_user(); 357 $u3 = $dg->create_user(); 358 $u4 = $dg->create_user(); 359 $u5 = $dg->create_user(); 360 $u6 = $dg->create_user(); 361 362 $c1ctx = context_course::instance($c1->id); 363 $c2ctx = context_course::instance($c2->id); 364 $u2ctx = context_user::instance($u2->id); 365 366 // Create some stuff. 367 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 368 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 369 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 370 $gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 371 372 // User 1 is graded in course 1. 373 $gi1a->update_final_grade($u1->id, 1, 'test'); 374 375 // User 2 is graded in course 2. 376 $gi2a->update_final_grade($u2->id, 10, 'test'); 377 378 // User 3 is set as modifier. 379 $gi1a->update_final_grade($u1->id, 1, 'test', '', FORMAT_MOODLE, $u3->id); 380 381 // User 4 is set as modifier, and creates history.. 382 $this->setUser($u4); 383 $gi1a->update_final_grade($u2->id, 1, 'test'); 384 385 // User 5 creates history, user 6 is the known modifier, and we delete the item. 386 $this->setUser($u5); 387 $gi2b->update_final_grade($u2->id, 1, 'test', '', FORMAT_PLAIN, $u6->id); 388 $gi2b->delete(); 389 390 $userlist = new \core_privacy\local\request\userlist($c1ctx, 'core_grades'); 391 provider::get_users_in_context($userlist); 392 $course1userids = [$u1->id, $u2->id, $u3->id, $u4->id]; 393 $this->assertEqualsCanonicalizing($course1userids, $userlist->get_userids()); 394 395 $userlist = new \core_privacy\local\request\userlist($c2ctx, 'core_grades'); 396 provider::get_users_in_context($userlist); 397 $course2userids = [$u5->id, $u2->id]; 398 $this->assertEqualsCanonicalizing($course2userids, $userlist->get_userids()); 399 400 $userlist = new \core_privacy\local\request\userlist($u2ctx, 'core_grades'); 401 provider::get_users_in_context($userlist); 402 $this->assertEquals([$u2->id], $userlist->get_userids()); 403 } 404 405 public function test_delete_data_for_all_users_in_context() { 406 global $DB; 407 408 $fs = new file_storage(); 409 410 $dg = $this->getDataGenerator(); 411 412 $c1 = $dg->create_course(); 413 $c2 = $dg->create_course(); 414 $u1 = $dg->create_user(); 415 $u2 = $dg->create_user(); 416 $u1ctx = context_user::instance($u1->id); 417 $c1ctx = context_course::instance($c1->id); 418 $c2ctx = context_course::instance($c2->id); 419 420 $a1 = $dg->create_module('assign', ['course' => $c1->id]); 421 $a2 = $dg->create_module('assign', ['course' => $c1->id]); 422 $a3 = $dg->create_module('assign', ['course' => $c2->id]); 423 $a4 = $dg->create_module('assign', ['course' => $c2->id]); 424 425 $a1context = context_module::instance($a1->cmid); 426 $a2context = context_module::instance($a2->cmid); 427 $a3context = context_module::instance($a3->cmid); 428 $a4context = context_module::instance($a4->cmid); 429 430 // Create some stuff. 431 $gi1a = new grade_item($dg->create_grade_item( 432 [ 433 'courseid' => $c1->id, 434 'itemtype' => 'mod', 435 'itemmodule' => 'assign', 436 'iteminstance' => $a1->id 437 ] 438 ), false); 439 $gi1b = new grade_item($dg->create_grade_item( 440 [ 441 'courseid' => $c1->id, 442 'itemtype' => 'mod', 443 'itemmodule' => 'assign', 444 'iteminstance' => $a2->id 445 ] 446 ), false); 447 $gi2a = new grade_item($dg->create_grade_item( 448 [ 449 'courseid' => $c2->id, 450 'itemtype' => 'mod', 451 'itemmodule' => 'assign', 452 'iteminstance' => $a3->id 453 ] 454 ), false); 455 $gi2b = new grade_item($dg->create_grade_item( 456 [ 457 'courseid' => $c2->id, 458 'itemtype' => 'mod', 459 'itemmodule' => 'assign', 460 'iteminstance' => $a4->id 461 ] 462 ), false); 463 464 $this->add_feedback_file_to_copy(); 465 466 $grades['feedback'] = 'Nice feedback!'; 467 $grades['feedbackformat'] = FORMAT_MOODLE; 468 $grades['feedbackfiles'] = [ 469 'contextid' => 1, 470 'component' => 'test', 471 'filearea' => 'testarea', 472 'itemid' => 1 473 ]; 474 475 $grades['userid'] = $u1->id; 476 grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance, 477 $gi1a->itemnumber, $grades); 478 479 $grades['userid'] = $u2->id; 480 grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance, 481 $gi1a->itemnumber, $grades); 482 483 $grades['userid'] = $u1->id; 484 grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance, 485 $gi1b->itemnumber, $grades); 486 487 $grades['userid'] = $u1->id; 488 grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance, 489 $gi2a->itemnumber, $grades); 490 491 $grades['userid'] = $u2->id; 492 grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance, 493 $gi2a->itemnumber, $grades); 494 495 $grades['userid'] = $u1->id; 496 grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance, 497 $gi2b->itemnumber, $grades); 498 499 $grades['userid'] = $u2->id; 500 grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance, 501 $gi2b->itemnumber, $grades); 502 $gi2b->delete(); 503 504 // Feedback file area. 505 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 506 $this->assertEquals(4, count($files)); 507 508 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 509 $this->assertEquals(2, count($files)); 510 511 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 512 $this->assertEquals(4, count($files)); 513 514 // Grade item 2 was deleted, so the associated files were as well. 515 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 516 $this->assertEquals(0, count($files)); 517 518 // History file area. 519 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 520 $this->assertEquals(4, count($files)); 521 522 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 523 $this->assertEquals(2, count($files)); 524 525 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 526 $this->assertEquals(4, count($files)); 527 528 // Grade item 2 was deleted, so the associated files were as well. 529 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 530 $this->assertEquals(0, count($files)); 531 532 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 533 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 534 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 535 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 536 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 537 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 538 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 539 540 provider::delete_data_for_all_users_in_context($c1ctx); 541 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 542 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 543 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 544 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 545 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 546 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 547 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 548 549 // Feedback file area. 550 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 551 $this->assertEquals(0, count($files)); 552 553 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 554 $this->assertEquals(0, count($files)); 555 556 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 557 $this->assertEquals(4, count($files)); 558 559 // Grade item 2 was deleted, so the associated files were as well. 560 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 561 $this->assertEquals(0, count($files)); 562 563 // History file area. 564 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 565 $this->assertEquals(0, count($files)); 566 567 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 568 $this->assertEquals(0, count($files)); 569 570 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 571 $this->assertEquals(4, count($files)); 572 573 // Grade item 2 was deleted, so the associated files were as well. 574 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 575 $this->assertEquals(0, count($files)); 576 577 provider::delete_data_for_all_users_in_context($u1ctx); 578 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 579 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 580 $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 581 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 582 583 // Feedback file area. 584 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 585 $this->assertEquals(0, count($files)); 586 587 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 588 $this->assertEquals(0, count($files)); 589 590 // The user context is only reported when there are orphan historical grades, so we only delete those files. 591 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 592 $this->assertEquals(4, count($files)); 593 594 // Grade item 2 was deleted, so the associated files were as well. 595 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 596 $this->assertEquals(0, count($files)); 597 598 // History file area. 599 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 600 $this->assertEquals(0, count($files)); 601 602 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 603 $this->assertEquals(0, count($files)); 604 605 // User 2 still has historical files. 606 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 607 $this->assertEquals(2, count($files)); 608 609 // Grade item 2 was deleted, so the associated files were as well. 610 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 611 $this->assertEquals(0, count($files)); 612 613 provider::delete_data_for_all_users_in_context($c2ctx); 614 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 615 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 616 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 617 618 // Feedback file area. 619 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 620 $this->assertEquals(0, count($files)); 621 622 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 623 $this->assertEquals(0, count($files)); 624 625 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 626 $this->assertEquals(0, count($files)); 627 628 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 629 $this->assertEquals(0, count($files)); 630 631 // History file area. 632 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 633 $this->assertEquals(0, count($files)); 634 635 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 636 $this->assertEquals(0, count($files)); 637 638 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 639 $this->assertEquals(0, count($files)); 640 641 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 642 $this->assertEquals(0, count($files)); 643 } 644 645 public function test_delete_data_for_user() { 646 global $DB; 647 648 $fs = new file_storage(); 649 650 $dg = $this->getDataGenerator(); 651 652 $c1 = $dg->create_course(); 653 $c2 = $dg->create_course(); 654 $u1 = $dg->create_user(); 655 $u2 = $dg->create_user(); 656 $u1ctx = context_user::instance($u1->id); 657 $u2ctx = context_user::instance($u2->id); 658 $c1ctx = context_course::instance($c1->id); 659 $c2ctx = context_course::instance($c2->id); 660 661 $a1 = $dg->create_module('assign', ['course' => $c1->id]); 662 $a2 = $dg->create_module('assign', ['course' => $c1->id]); 663 $a3 = $dg->create_module('assign', ['course' => $c2->id]); 664 $a4 = $dg->create_module('assign', ['course' => $c2->id]); 665 666 $a1context = context_module::instance($a1->cmid); 667 $a2context = context_module::instance($a2->cmid); 668 $a3context = context_module::instance($a3->cmid); 669 $a4context = context_module::instance($a4->cmid); 670 671 // Create some stuff. 672 $gi1a = new grade_item($dg->create_grade_item( 673 [ 674 'courseid' => $c1->id, 675 'itemtype' => 'mod', 676 'itemmodule' => 'assign', 677 'iteminstance' => $a1->id 678 ] 679 ), false); 680 $gi1b = new grade_item($dg->create_grade_item( 681 [ 682 'courseid' => $c1->id, 683 'itemtype' => 'mod', 684 'itemmodule' => 'assign', 685 'iteminstance' => $a2->id 686 ] 687 ), false); 688 $gi2a = new grade_item($dg->create_grade_item( 689 [ 690 'courseid' => $c2->id, 691 'itemtype' => 'mod', 692 'itemmodule' => 'assign', 693 'iteminstance' => $a3->id 694 ] 695 ), false); 696 $gi2b = new grade_item($dg->create_grade_item( 697 [ 698 'courseid' => $c2->id, 699 'itemtype' => 'mod', 700 'itemmodule' => 'assign', 701 'iteminstance' => $a4->id 702 ] 703 ), false); 704 705 $this->add_feedback_file_to_copy(); 706 707 $grades['feedback'] = 'Nice feedback!'; 708 $grades['feedbackfiles'] = [ 709 'contextid' => 1, 710 'component' => 'test', 711 'filearea' => 'testarea', 712 'itemid' => 1 713 ]; 714 715 $grades['userid'] = $u1->id; 716 grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance, 717 $gi1a->itemnumber, $grades); 718 719 $grades['userid'] = $u2->id; 720 grade_update('mod/assign', $gi1a->courseid, $gi1a->itemtype, $gi1a->itemmodule, $gi1a->iteminstance, 721 $gi1a->itemnumber, $grades); 722 723 $grades['userid'] = $u1->id; 724 grade_update('mod/assign', $gi1b->courseid, $gi1b->itemtype, $gi1b->itemmodule, $gi1b->iteminstance, 725 $gi1b->itemnumber, $grades); 726 727 $grades['userid'] = $u1->id; 728 grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance, 729 $gi2a->itemnumber, $grades); 730 731 $grades['userid'] = $u2->id; 732 grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance, 733 $gi2a->itemnumber, $grades); 734 735 $grades['userid'] = $u1->id; 736 grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance, 737 $gi2b->itemnumber, $grades); 738 739 $grades['userid'] = $u2->id; 740 grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance, 741 $gi2b->itemnumber, $grades); 742 743 $gi2b->delete(); 744 745 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 746 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 747 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 748 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 749 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 750 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 751 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 752 753 // Feedback file area. 754 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 755 $this->assertEquals(4, count($files)); 756 757 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 758 $this->assertEquals(2, count($files)); 759 760 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 761 $this->assertEquals(4, count($files)); 762 763 // Grade item 2 was deleted, so the associated files were as well. 764 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 765 $this->assertEquals(0, count($files)); 766 767 // History file area. 768 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 769 $this->assertEquals(4, count($files)); 770 771 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 772 $this->assertEquals(2, count($files)); 773 774 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 775 $this->assertEquals(4, count($files)); 776 777 // Grade item 2 was deleted, so the associated files were as well. 778 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 779 $this->assertEquals(0, count($files)); 780 781 provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$c1ctx->id])); 782 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 783 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 784 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 785 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 786 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 787 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 788 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 789 790 // Feedback file area. 791 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 792 $this->assertEquals(2, count($files)); 793 794 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 795 $this->assertEquals(0, count($files)); 796 797 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 798 $this->assertEquals(4, count($files)); 799 800 // Grade item 2 was deleted, so the associated files were as well. 801 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 802 $this->assertEquals(0, count($files)); 803 804 // History file area. 805 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 806 $this->assertEquals(2, count($files)); 807 808 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 809 $this->assertEquals(0, count($files)); 810 811 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 812 $this->assertEquals(4, count($files)); 813 814 // Grade item 2 was deleted, so the associated files were as well. 815 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 816 $this->assertEquals(0, count($files)); 817 818 provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u1ctx->id])); 819 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 820 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 821 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 822 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 823 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 824 $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 825 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 826 827 // Feedback file area. 828 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 829 $this->assertEquals(2, count($files)); 830 831 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 832 $this->assertEquals(0, count($files)); 833 834 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 835 $this->assertEquals(4, count($files)); 836 837 // Grade item 2 was deleted, so the associated files were as well. 838 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 839 $this->assertEquals(0, count($files)); 840 841 // History file area. 842 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 843 $this->assertEquals(2, count($files)); 844 845 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 846 $this->assertEquals(0, count($files)); 847 848 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 849 $this->assertEquals(2, count($files)); 850 851 // Grade item 2 was deleted, so the associated files were as well. 852 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 853 $this->assertEquals(0, count($files)); 854 855 provider::delete_data_for_user(new approved_contextlist($u1, 'core_grades', [$u2ctx->id, $c2ctx->id])); 856 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 857 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 858 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 859 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 860 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 861 $this->assertFalse($DB->record_exists('grade_grades_history', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 862 $this->assertTrue($DB->record_exists('grade_grades_history', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 863 864 // Feedback file area. 865 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 866 $this->assertEquals(2, count($files)); 867 868 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 869 $this->assertEquals(0, count($files)); 870 871 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 872 $this->assertEquals(2, count($files)); 873 874 // Grade item 2 was deleted, so the associated files were as well. 875 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_FEEDBACK_FILEAREA); 876 $this->assertEquals(0, count($files)); 877 878 // History file area. 879 $files = $fs->get_area_files($a1context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 880 $this->assertEquals(2, count($files)); 881 882 $files = $fs->get_area_files($a2context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 883 $this->assertEquals(0, count($files)); 884 885 $files = $fs->get_area_files($a3context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 886 $this->assertEquals(2, count($files)); 887 888 // Grade item 2 was deleted, so the associated files were as well. 889 $files = $fs->get_area_files($a4context->id, GRADE_FILE_COMPONENT, GRADE_HISTORY_FEEDBACK_FILEAREA); 890 $this->assertEquals(0, count($files)); 891 } 892 893 /** 894 * Test deleting multiple users for a context works. 895 */ 896 public function test_delete_data_for_users() { 897 global $DB; 898 $dg = $this->getDataGenerator(); 899 900 $c1 = $dg->create_course(); 901 $c2 = $dg->create_course(); 902 $u1 = $dg->create_user(); 903 $u2 = $dg->create_user(); 904 $u3 = $dg->create_user(); 905 $u4 = $dg->create_user(); 906 $u1ctx = context_user::instance($u1->id); 907 $u2ctx = context_user::instance($u2->id); 908 $c1ctx = context_course::instance($c1->id); 909 $c2ctx = context_course::instance($c2->id); 910 911 // Create some stuff. 912 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 913 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 914 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 915 $gi2b = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 916 917 $gi1a->update_final_grade($u1->id, 1, 'test'); 918 $gi1a->update_final_grade($u2->id, 1, 'test'); 919 $gi1a->update_final_grade($u3->id, 1, 'test'); 920 $gi1b->update_final_grade($u1->id, 1, 'test'); 921 $gi1b->update_final_grade($u4->id, 1, 'test'); 922 $gi2a->update_final_grade($u1->id, 1, 'test'); 923 $gi2a->update_final_grade($u2->id, 1, 'test'); 924 $gi2a->update_final_grade($u4->id, 1, 'test'); 925 $gi2b->update_final_grade($u1->id, 1, 'test'); 926 $gi2b->update_final_grade($u2->id, 1, 'test'); 927 $gi2b->update_final_grade($u3->id, 1, 'test'); 928 $gi2b->delete(); 929 930 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 931 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 932 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id])); 933 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 934 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id])); 935 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 936 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 937 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id])); 938 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2b->id])); 939 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2b->id])); 940 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi2b->id])); 941 942 $userlist = new \core_privacy\local\request\approved_userlist($c1ctx, 'core_grades', [$u1->id, $u2->id]); 943 provider::delete_data_for_users($userlist); 944 945 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 946 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 947 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id])); 948 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 949 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id])); 950 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 951 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 952 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id])); 953 954 $userlist = new \core_privacy\local\request\approved_userlist($c2ctx, 'core_grades', [$u2->id, $u4->id]); 955 provider::delete_data_for_users($userlist); 956 957 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1a->id])); 958 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi1a->id])); 959 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u3->id, 'itemid' => $gi1a->id])); 960 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi1b->id])); 961 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi1b->id])); 962 $this->assertTrue($DB->record_exists('grade_grades', ['userid' => $u1->id, 'itemid' => $gi2a->id])); 963 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u2->id, 'itemid' => $gi2a->id])); 964 $this->assertFalse($DB->record_exists('grade_grades', ['userid' => $u4->id, 'itemid' => $gi2a->id])); 965 } 966 967 public function test_export_data_for_user_about_grades_and_history() { 968 $dg = $this->getDataGenerator(); 969 970 $c1 = $dg->create_course(); 971 $c2 = $dg->create_course(); 972 973 // Users being graded. 974 $ug1 = $dg->create_user(); 975 $ug2 = $dg->create_user(); 976 $ug3 = $dg->create_user(); 977 // Users performing actions. 978 $ua1 = $dg->create_user(); 979 $ua2 = $dg->create_user(); 980 $ua3 = $dg->create_user(); 981 982 $ug1ctx = context_user::instance($ug1->id); 983 $ug2ctx = context_user::instance($ug2->id); 984 $c1ctx = context_course::instance($c1->id); 985 $c2ctx = context_course::instance($c2->id); 986 987 $rootpath = [get_string('grades', 'core_grades')]; 988 $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]); 989 990 // Create the course minimal stuff. 991 grade_category::fetch_course_category($c1->id); 992 $ci1 = grade_item::fetch_course_item($c1->id); 993 grade_category::fetch_course_category($c2->id); 994 $ci2 = grade_item::fetch_course_item($c2->id); 995 996 $this->add_feedback_file_to_copy(); 997 998 $grades['feedbackfiles'] = [ 999 'contextid' => 1, 1000 'component' => 'test', 1001 'filearea' => 'testarea', 1002 'itemid' => 1 1003 ]; 1004 1005 $a1 = $dg->create_module('assign', ['course' => $c1->id]); 1006 1007 // Create data that will sit in the user context because we will delete the grate item. 1008 $gi1 = new grade_item($dg->create_grade_item( 1009 [ 1010 'courseid' => $c1->id, 1011 'itemtype' => 'mod', 1012 'itemmodule' => 'assign', 1013 'iteminstance' => $a1->id, 1014 'aggregationcoef2' => 1 1015 ] 1016 ), false); 1017 1018 $grades['feedback'] = 'Well done!'; 1019 $grades['feedbackformat'] = FORMAT_PLAIN; 1020 $grades['userid'] = $ug1->id; 1021 $grades['usermodified'] = $ua2->id; 1022 $grades['rawgrade'] = 100; 1023 grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance, 1024 $gi1->itemnumber, $grades); 1025 1026 $grades['feedback'] = 'Hi'; 1027 $grades['userid'] = $ug1->id; 1028 $grades['usermodified'] = $ua2->id; 1029 $grades['rawgrade'] = 1; 1030 grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance, 1031 $gi1->itemnumber, $grades); 1032 1033 $grades['feedback'] = 'Hello'; 1034 $grades['userid'] = $ug3->id; 1035 $grades['usermodified'] = $ua2->id; 1036 $grades['rawgrade'] = 12; 1037 grade_update('mod/assign', $gi1->courseid, $gi1->itemtype, $gi1->itemmodule, $gi1->iteminstance, 1038 $gi1->itemnumber, $grades); 1039 1040 // Create another set for another user. 1041 $a2 = $dg->create_module('assign', ['course' => $c2->id]); 1042 $a3 = $dg->create_module('assign', ['course' => $c2->id]); 1043 $gi2a = new grade_item($dg->create_grade_item( 1044 [ 1045 'courseid' => $c2->id, 1046 'itemtype' => 'mod', 1047 'itemmodule' => 'assign', 1048 'iteminstance' => $a2->id 1049 ] 1050 ), false); 1051 $gi2b = new grade_item($dg->create_grade_item( 1052 [ 1053 'courseid' => $c2->id, 1054 'itemtype' => 'mod', 1055 'itemmodule' => 'assign', 1056 'iteminstance' => $a3->id 1057 ] 1058 ), false); 1059 1060 $grades['feedback'] = ''; 1061 $grades['userid'] = $ug1->id; 1062 $grades['usermodified'] = $ua2->id; 1063 $grades['rawgrade'] = 15; 1064 grade_update('mod/assign', $gi2a->courseid, $gi2a->itemtype, $gi2a->itemmodule, $gi2a->iteminstance, 1065 $gi2a->itemnumber, $grades); 1066 1067 $grades['feedback'] = 'Well played!'; 1068 $grades['userid'] = $ug1->id; 1069 $grades['usermodified'] = $ua2->id; 1070 $grades['rawgrade'] = 30; 1071 grade_update('mod/assign', $gi2b->courseid, $gi2b->itemtype, $gi2b->itemmodule, $gi2b->iteminstance, 1072 $gi2b->itemnumber, $grades); 1073 1074 // Export action user 1 everywhere. 1075 provider::export_user_data(new approved_contextlist($ua1, 'core_grades', [$ug1ctx->id, $ug2ctx->id, 1076 $c1ctx->id, $c2ctx->id])); 1077 $this->assert_context_has_no_data($ug1ctx); 1078 $this->assert_context_has_no_data($ug2ctx); 1079 $this->assert_context_has_no_data($c1ctx); 1080 $this->assert_context_has_no_data($c2ctx); 1081 1082 // Export action user 2 in course 1. 1083 writer::reset(); 1084 provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$c1ctx->id])); 1085 $this->assert_context_has_no_data($ug1ctx); 1086 $this->assert_context_has_no_data($ug2ctx); 1087 $this->assert_context_has_no_data($c2ctx); 1088 $data = writer::with_context($c1ctx)->get_data($rootpath); 1089 $this->assertEmpty($data); 1090 1091 // Here we are testing the export of grades that we've changed. 1092 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades'); 1093 $this->assertCount(2, $data->grades); 1094 $this->assertEquals($gi1->get_name(), $data->grades[0]['item']); 1095 $this->assertEquals(1, $data->grades[0]['grade']); 1096 $this->assertEquals('Hi', $data->grades[0]['feedback']); 1097 $this->assertEquals(transform::yesno(true), $data->grades[0]['created_or_modified_by_you']); 1098 $this->assertEquals($gi1->get_name(), $data->grades[1]['item']); 1099 $this->assertEquals(12, $data->grades[1]['grade']); 1100 $this->assertEquals('Hello', $data->grades[1]['feedback']); 1101 $this->assertEquals(transform::yesno(true), $data->grades[1]['created_or_modified_by_you']); 1102 1103 $pathtofiles = [ 1104 get_string('grades', 'core_grades'), 1105 get_string('feedbackfiles', 'core_grades') 1106 ]; 1107 $file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt']; 1108 1109 $this->assertInstanceOf('stored_file', $file); 1110 $this->assertEquals('feedback1.txt', $file->get_filename()); 1111 1112 $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]); 1113 1114 // Here we are testing the export of history of grades that we've changed. 1115 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history'); 1116 $this->assertCount(3, $data->modified_records); 1117 $grade = $data->modified_records[0]; 1118 $this->assertEquals($ug1->id, $grade['userid']); 1119 $this->assertEquals($gi1->get_name(), $grade['item']); 1120 $this->assertEquals(100, $grade['grade']); 1121 $this->assertEquals('Well done!', $grade['feedback']); 1122 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1123 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1124 $grade = $data->modified_records[1]; 1125 $this->assertEquals($ug1->id, $grade['userid']); 1126 $this->assertEquals($gi1->get_name(), $grade['item']); 1127 $this->assertEquals(1, $grade['grade']); 1128 $this->assertEquals('Hi', $grade['feedback']); 1129 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1130 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1131 $grade = $data->modified_records[2]; 1132 $this->assertEquals($ug3->id, $grade['userid']); 1133 $this->assertEquals($gi1->get_name(), $grade['item']); 1134 $this->assertEquals(12, $grade['grade']); 1135 $this->assertEquals('Hello', $grade['feedback']); 1136 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1137 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1138 1139 $pathtofiles = [ 1140 get_string('grades', 'core_grades'), 1141 get_string('feedbackhistoryfiles', 'core_grades') 1142 ]; 1143 $file = writer::with_context($gi1->get_context())->get_files($pathtofiles)['feedback1.txt']; 1144 1145 $this->assertInstanceOf('stored_file', $file); 1146 $this->assertEquals('feedback1.txt', $file->get_filename()); 1147 1148 // Create a history record with logged user. 1149 $this->setUser($ua3); 1150 $gi1->update_final_grade($ug3->id, 50, 'test', '...', FORMAT_PLAIN, $ua2->id); 1151 writer::reset(); 1152 provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$c1ctx->id])); 1153 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'grades_history'); 1154 $this->assertCount(1, $data->modified_records); 1155 $grade = $data->modified_records[0]; 1156 $this->assertEquals($ug3->id, $grade['userid']); 1157 $this->assertEquals($gi1->get_name(), $grade['item']); 1158 $this->assertEquals(50, $grade['grade']); 1159 $this->assertEquals('...', $grade['feedback']); 1160 $this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']); 1161 $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']); 1162 1163 // Test that we export our own grades. 1164 writer::reset(); 1165 provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$c1ctx->id])); 1166 $data = writer::with_context($c1ctx)->get_data($rootpath); 1167 $this->assert_context_has_no_data($c2ctx); 1168 $this->assertCount(3, $data->grades); 1169 $grade = $data->grades[0]; 1170 $this->assertEquals($ci1->get_name(), $grade['item']); 1171 $this->assertEquals(1, $grade['grade']); 1172 $grade = $data->grades[2]; 1173 $this->assertEquals($gi1->get_name(), $grade['item']); 1174 $this->assertEquals(1, $grade['grade']); 1175 $this->assertEquals('Hi', $grade['feedback']); 1176 1177 // Test that we export our own grades in two courses. 1178 writer::reset(); 1179 provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id])); 1180 $this->assert_context_has_no_data($ug1ctx); 1181 $data = writer::with_context($c1ctx)->get_data($rootpath); 1182 $this->assertCount(3, $data->grades); 1183 $grade = $data->grades[0]; 1184 $this->assertEquals($ci1->get_name(), $grade['item']); 1185 $this->assertEquals(1, $grade['grade']); 1186 $grade = $data->grades[2]; 1187 $this->assertEquals($gi1->get_name(), $grade['item']); 1188 $this->assertEquals(1, $grade['grade']); 1189 $this->assertEquals('Hi', $grade['feedback']); 1190 1191 $data = writer::with_context($c2ctx)->get_data($rootpath); 1192 $this->assertCount(5, $data->grades); 1193 $grade = $data->grades[0]; 1194 $this->assertEquals($ci2->get_name(), $grade['item']); 1195 $grade = $data->grades[3]; 1196 $this->assertEquals($gi2a->get_name(), $grade['item']); 1197 $this->assertEquals(15, $grade['grade']); 1198 $this->assertEquals('', $grade['feedback']); 1199 $grade = $data->grades[4]; 1200 $this->assertEquals($gi2b->get_name(), $grade['item']); 1201 $this->assertEquals(30, $grade['grade']); 1202 $this->assertEquals('Well played!', $grade['feedback']); 1203 1204 // Delete a grade item. 1205 $this->setUser($ua3); 1206 $gi1->delete(); 1207 1208 // Now, we should find history of grades in our own context. 1209 writer::reset(); 1210 provider::export_user_data(new approved_contextlist($ug1, 'core_grades', [$ug1ctx->id, $c1ctx->id, $c2ctx->id])); 1211 $data = writer::with_context($c1ctx)->get_data($rootpath); 1212 $this->assertCount(2, $data->grades); 1213 $this->assertEquals($ci1->get_name(), $data->grades[0]['item']); 1214 $data = writer::with_context($c2ctx)->get_data($rootpath); 1215 $this->assertCount(5, $data->grades); 1216 $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history'); 1217 $this->assertCount(3, $data->grades); 1218 $grade = $data->grades[0]; 1219 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1220 $this->assertEquals(100, $grade['grade']); 1221 $this->assertEquals('Well done!', $grade['feedback']); 1222 $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']); 1223 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1224 $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']); 1225 $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']); 1226 $grade = $data->grades[1]; 1227 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1228 $this->assertEquals(1, $grade['grade']); 1229 $this->assertEquals('Hi', $grade['feedback']); 1230 $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']); 1231 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1232 $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']); 1233 $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']); 1234 $grade = $data->grades[2]; 1235 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1236 $this->assertEquals(1, $grade['grade']); 1237 $this->assertEquals('Hi', $grade['feedback']); 1238 $this->assertEquals(transform::yesno(true), $grade['graded_user_was_you']); 1239 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1240 $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']); 1241 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']); 1242 1243 // The action user 3 should have a record of the deletion in the user's context. 1244 writer::reset(); 1245 provider::export_user_data(new approved_contextlist($ua3, 'core_grades', [$ug1ctx->id])); 1246 $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history'); 1247 $this->assertCount(1, $data->grades); 1248 $grade = $data->grades[0]; 1249 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1250 $this->assertEquals(1, $grade['grade']); 1251 $this->assertEquals('Hi', $grade['feedback']); 1252 $this->assertEquals(transform::yesno(true), $grade['logged_in_user_was_you']); 1253 $this->assertEquals(transform::yesno(false), $grade['author_of_change_was_you']); 1254 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']); 1255 1256 // The action user 2 should have a record of their edits in the user's context. 1257 writer::reset(); 1258 provider::export_user_data(new approved_contextlist($ua2, 'core_grades', [$ug1ctx->id])); 1259 $data = writer::with_context($ug1ctx)->get_related_data($rootpath, 'history'); 1260 $this->assertCount(3, $data->grades); 1261 $grade = $data->grades[0]; 1262 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1263 $this->assertEquals(100, $grade['grade']); 1264 $this->assertEquals('Well done!', $grade['feedback']); 1265 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1266 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1267 $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), $grade['action']); 1268 $grade = $data->grades[1]; 1269 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1270 $this->assertEquals(1, $grade['grade']); 1271 $this->assertEquals('Hi', $grade['feedback']); 1272 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1273 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1274 $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), $grade['action']); 1275 $grade = $data->grades[2]; 1276 $this->assertEquals(get_string('privacy:request:unknowndeletedgradeitem', 'core_grades'), $grade['name']); 1277 $this->assertEquals(1, $grade['grade']); 1278 $this->assertEquals('Hi', $grade['feedback']); 1279 $this->assertEquals(transform::yesno(false), $grade['logged_in_user_was_you']); 1280 $this->assertEquals(transform::yesno(true), $grade['author_of_change_was_you']); 1281 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), $grade['action']); 1282 } 1283 1284 public function test_export_data_for_user_with_scale() { 1285 global $DB; 1286 $dg = $this->getDataGenerator(); 1287 $c1 = $dg->create_course(); 1288 $scale = $dg->create_scale(['scale' => 'Awesome,OK,Reasonable,Bad']); 1289 $u1 = $dg->create_user(); 1290 $u2 = $dg->create_user(); 1291 1292 $u1ctx = context_user::instance($u1->id); 1293 $c1ctx = context_course::instance($c1->id); 1294 1295 $rootpath = [get_string('grades', 'core_grades')]; 1296 1297 // Create another set for another user. 1298 $gi1 = new grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false); 1299 $gi1->update_final_grade($u1->id, 1, 'test', '', FORMAT_PLAIN, $u2->id); 1300 $gi2 = new grade_item($dg->create_grade_item(['courseid' => $c1->id, 'scaleid' => $scale->id]), false); 1301 $gi2->update_final_grade($u1->id, 3, 'test', '', FORMAT_PLAIN, $u2->id); 1302 1303 // Export user's data. 1304 writer::reset(); 1305 provider::export_user_data(new approved_contextlist($u1, 'core_grades', [$c1ctx->id])); 1306 $data = writer::with_context($c1ctx)->get_data($rootpath); 1307 $this->assertCount(3, $data->grades); 1308 $this->assertEquals(grade_item::fetch_course_item($c1->id)->get_name(), $data->grades[0]['item']); 1309 $this->assertEquals($gi1->get_name(), $data->grades[1]['item']); 1310 $this->assertEquals(1, $data->grades[1]['grade']); 1311 $this->assertEquals('Awesome', $data->grades[1]['grade_formatted']); 1312 $this->assertEquals($gi2->get_name(), $data->grades[2]['item']); 1313 $this->assertEquals(3, $data->grades[2]['grade']); 1314 $this->assertEquals('Reasonable', $data->grades[2]['grade_formatted']); 1315 } 1316 1317 public function test_export_data_for_user_about_gradebook_edits() { 1318 global $DB; 1319 $dg = $this->getDataGenerator(); 1320 $c1 = $dg->create_course(); 1321 $c2 = $dg->create_course(); 1322 $u1 = $dg->create_user(); 1323 $u2 = $dg->create_user(); 1324 $u3 = $dg->create_user(); 1325 $u4 = $dg->create_user(); 1326 $u5 = $dg->create_user(); 1327 $u6 = $dg->create_user(); 1328 $u7 = $dg->create_user(); 1329 $u8 = $dg->create_user(); 1330 $u9 = $dg->create_user(); 1331 $u10 = $dg->create_user(); 1332 1333 $sysctx = context_system::instance(); 1334 $u1ctx = context_user::instance($u1->id); 1335 $u2ctx = context_user::instance($u2->id); 1336 $u3ctx = context_user::instance($u3->id); 1337 $u4ctx = context_user::instance($u4->id); 1338 $u5ctx = context_user::instance($u5->id); 1339 $u6ctx = context_user::instance($u6->id); 1340 $c1ctx = context_course::instance($c1->id); 1341 $c2ctx = context_course::instance($c2->id); 1342 1343 $rootpath = [get_string('grades', 'core_grades')]; 1344 $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]); 1345 $allcontexts = [$sysctx->id, $c1ctx->id, $c2ctx->id, $u1ctx->id, $u2ctx->id, $u3ctx->id, $u4ctx->id, 1346 $u5ctx->id, $u6ctx->id]; 1347 $updateactionstr = get_string('privacy:request:historyactionupdate', 'core_grades'); 1348 1349 // Create some stuff. 1350 $gi1a = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 1351 $gi1b = new grade_item($dg->create_grade_item(['courseid' => $c1->id]), false); 1352 $gi2a = new grade_item($dg->create_grade_item(['courseid' => $c2->id]), false); 1353 $gc1a = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 1354 $gc1b = new grade_category($dg->create_grade_category(['courseid' => $c1->id]), false); 1355 $gc2a = new grade_category($dg->create_grade_category(['courseid' => $c2->id]), false); 1356 $go2 = new grade_outcome($dg->create_grade_outcome(['courseid' => $c2->id, 'shortname' => 'go2', 1357 'fullname' => 'go2']), false); 1358 1359 $go0 = new grade_outcome(['shortname' => 'go0', 'fullname' => 'go0', 'usermodified' => $u1->id]); 1360 $go0->insert(); 1361 $go1 = new grade_outcome(['shortname' => 'go1', 'fullname' => 'go1', 'courseid' => $c1->id, 'usermodified' => $u1->id]); 1362 $go1->insert(); 1363 1364 // Create scales. 1365 $s1 = new grade_scale(['name' => 's1', 'scale' => 'a,b', 'userid' => $u7->id, 'courseid' => 0, 'description' => '']); 1366 $s1->insert(); 1367 $s2 = new grade_scale(['name' => 's2', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c1->id, 'description' => '']); 1368 $s2->insert(); 1369 $s3 = new grade_scale(['name' => 's3', 'scale' => 'a,b', 'userid' => $u8->id, 'courseid' => $c2->id, 'description' => '']); 1370 $s3->insert(); 1371 1372 // User 2 creates history. 1373 $this->setUser($u2); 1374 $go0->shortname .= ' edited'; 1375 $go0->update(); 1376 $gc1a->fullname .= ' edited'; 1377 $gc1a->update(); 1378 1379 // User 3 creates history. 1380 $this->setUser($u3); 1381 $go1->shortname .= ' edited'; 1382 $go1->update(); 1383 $gc2a->fullname .= ' a'; 1384 $gc2a->update(); 1385 1386 // User 4 updates an outcome in course (creates history). 1387 $this->setUser($u4); 1388 $go2->shortname .= ' edited'; 1389 $go2->update(); 1390 1391 // User 5 updates an item. 1392 $this->setUser($u5); 1393 $gi1a->itemname .= ' edited'; 1394 $gi1a->update(); 1395 1396 // User 6 creates history. 1397 $this->setUser($u6); 1398 $gi2a->delete(); 1399 1400 // User 9 creates history. 1401 $this->setUser($u9); 1402 $s1->name .= ' edited'; 1403 $s1->update(); 1404 1405 // User 10 creates history. 1406 $this->setUser($u10); 1407 $s3->delete(); 1408 1409 $this->setAdminUser(); 1410 1411 // Export data for u1. 1412 writer::reset(); 1413 provider::export_user_data(new approved_contextlist($u1, 'core_grades', $allcontexts)); 1414 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes'); 1415 $this->assertCount(1, $data->outcomes); 1416 $this->assertEquals($go0->shortname, $data->outcomes[0]['shortname']); 1417 $this->assertEquals($go0->fullname, $data->outcomes[0]['fullname']); 1418 $this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']); 1419 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes'); 1420 $this->assertCount(1, $data->outcomes); 1421 $this->assertEquals($go1->shortname, $data->outcomes[0]['shortname']); 1422 $this->assertEquals($go1->fullname, $data->outcomes[0]['fullname']); 1423 $this->assertEquals(transform::yesno(true), $data->outcomes[0]['created_or_modified_by_you']); 1424 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history'); 1425 $this->assertEmpty($data); 1426 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history'); 1427 $this->assertEmpty($data); 1428 1429 // Export data for u2. 1430 writer::reset(); 1431 provider::export_user_data(new approved_contextlist($u2, 'core_grades', $allcontexts)); 1432 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes'); 1433 $this->assertEmpty($data); 1434 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes'); 1435 $this->assertEmpty($data); 1436 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'outcomes_history'); 1437 $this->assertCount(1, $data->modified_records); 1438 $this->assertEquals($go0->shortname, $data->modified_records[0]['shortname']); 1439 $this->assertEquals($go0->fullname, $data->modified_records[0]['fullname']); 1440 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1441 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1442 1443 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'categories_history'); 1444 $this->assertCount(1, $data->modified_records); 1445 $this->assertEquals($gc1a->fullname, $data->modified_records[0]['name']); 1446 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1447 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1448 1449 // Export data for u3. 1450 writer::reset(); 1451 provider::export_user_data(new approved_contextlist($u3, 'core_grades', $allcontexts)); 1452 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'outcomes_history'); 1453 $this->assertCount(1, $data->modified_records); 1454 $this->assertEquals($go1->shortname, $data->modified_records[0]['shortname']); 1455 $this->assertEquals($go1->fullname, $data->modified_records[0]['fullname']); 1456 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1457 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1458 1459 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'categories_history'); 1460 $this->assertCount(1, $data->modified_records); 1461 $this->assertEquals($gc2a->fullname, $data->modified_records[0]['name']); 1462 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1463 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1464 1465 // Export data for u4. 1466 writer::reset(); 1467 provider::export_user_data(new approved_contextlist($u4, 'core_grades', $allcontexts)); 1468 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'outcomes_history'); 1469 $this->assertCount(1, $data->modified_records); 1470 $this->assertEquals($go2->shortname, $data->modified_records[0]['shortname']); 1471 $this->assertEquals($go2->fullname, $data->modified_records[0]['fullname']); 1472 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1473 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1474 1475 // Export data for u5. 1476 writer::reset(); 1477 provider::export_user_data(new approved_contextlist($u5, 'core_grades', $allcontexts)); 1478 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history'); 1479 $this->assertCount(1, $data->modified_records); 1480 $this->assertEquals($gi1a->itemname, $data->modified_records[0]['name']); 1481 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1482 $this->assertEquals($updateactionstr, $data->modified_records[0]['action']); 1483 1484 // Export data for u6. 1485 writer::reset(); 1486 provider::export_user_data(new approved_contextlist($u6, 'core_grades', $allcontexts)); 1487 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'items_history'); 1488 $this->assertEmpty($data); 1489 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'items_history'); 1490 $this->assertCount(1, $data->modified_records); 1491 $this->assertEquals($gi2a->itemname, $data->modified_records[0]['name']); 1492 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['logged_in_user_was_you']); 1493 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), 1494 $data->modified_records[0]['action']); 1495 1496 // Export data for u7. 1497 writer::reset(); 1498 provider::export_user_data(new approved_contextlist($u7, 'core_grades', $allcontexts)); 1499 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales'); 1500 $this->assertEmpty($data); 1501 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales'); 1502 $this->assertCount(1, $data->scales); 1503 $this->assertEquals($s1->name, $data->scales[0]['name']); 1504 $this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']); 1505 1506 // Export data for u8. 1507 writer::reset(); 1508 provider::export_user_data(new approved_contextlist($u8, 'core_grades', $allcontexts)); 1509 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales'); 1510 $this->assertEmpty($data); 1511 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales'); 1512 $this->assertCount(1, $data->scales); 1513 $this->assertEquals($s2->name, $data->scales[0]['name']); 1514 $this->assertEquals(transform::yesno(true), $data->scales[0]['created_or_modified_by_you']); 1515 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history'); 1516 $this->assertCount(2, $data->modified_records); 1517 $this->assertEquals($s3->name, $data->modified_records[0]['name']); 1518 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_change_was_you']); 1519 $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_action_was_you']); 1520 $this->assertEquals(get_string('privacy:request:historyactioninsert', 'core_grades'), 1521 $data->modified_records[0]['action']); 1522 $this->assertEquals($s3->name, $data->modified_records[1]['name']); 1523 $this->assertEquals(transform::yesno(true), $data->modified_records[1]['author_of_change_was_you']); 1524 $this->assertEquals(transform::yesno(false), $data->modified_records[1]['author_of_action_was_you']); 1525 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), 1526 $data->modified_records[1]['action']); 1527 1528 // Export data for u9. 1529 writer::reset(); 1530 provider::export_user_data(new approved_contextlist($u9, 'core_grades', $allcontexts)); 1531 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales'); 1532 $this->assertEmpty($data); 1533 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales'); 1534 $this->assertEmpty($data); 1535 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history'); 1536 $this->assertCount(1, $data->modified_records); 1537 $this->assertEquals($s1->name, $data->modified_records[0]['name']); 1538 $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']); 1539 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']); 1540 $this->assertEquals(get_string('privacy:request:historyactionupdate', 'core_grades'), 1541 $data->modified_records[0]['action']); 1542 1543 // Export data for u10. 1544 writer::reset(); 1545 provider::export_user_data(new approved_contextlist($u10, 'core_grades', $allcontexts)); 1546 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales'); 1547 $this->assertEmpty($data); 1548 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales'); 1549 $this->assertEmpty($data); 1550 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales'); 1551 $this->assertEmpty($data); 1552 $data = writer::with_context($c1ctx)->get_related_data($relatedtomepath, 'scales_history'); 1553 $this->assertEmpty($data); 1554 $data = writer::with_context($sysctx)->get_related_data($relatedtomepath, 'scales_history'); 1555 $this->assertEmpty($data); 1556 $data = writer::with_context($c2ctx)->get_related_data($relatedtomepath, 'scales_history'); 1557 $this->assertCount(1, $data->modified_records); 1558 $this->assertEquals($s3->name, $data->modified_records[0]['name']); 1559 $this->assertEquals(transform::yesno(false), $data->modified_records[0]['author_of_change_was_you']); 1560 $this->assertEquals(transform::yesno(true), $data->modified_records[0]['author_of_action_was_you']); 1561 $this->assertEquals(get_string('privacy:request:historyactiondelete', 'core_grades'), 1562 $data->modified_records[0]['action']); 1563 } 1564 1565 /** 1566 * Assert there is no grade data in the context. 1567 * 1568 * @param context $context The context. 1569 * @return void 1570 */ 1571 protected function assert_context_has_no_data(context $context) { 1572 $rootpath = [get_string('grades', 'core_grades')]; 1573 $relatedtomepath = array_merge($rootpath, [get_string('privacy:path:relatedtome', 'core_grades')]); 1574 1575 $data = writer::with_context($context)->get_data($rootpath); 1576 $this->assertEmpty($data); 1577 1578 $data = writer::with_context($context)->get_related_data($rootpath, 'history'); 1579 $this->assertEmpty($data); 1580 1581 $files = ['categories_history', 'items_history', 'outcomes', 'outcomes_history', 'grades', 'grades_history', 'history']; 1582 foreach ($files as $file) { 1583 $data = writer::with_context($context)->get_related_data($relatedtomepath, $file); 1584 $this->assertEmpty($data); 1585 } 1586 } 1587 1588 /** 1589 * Creates a feedback file to copy to the gradebook area. 1590 */ 1591 private function add_feedback_file_to_copy() { 1592 $dummy = array( 1593 'contextid' => 1, 1594 'component' => 'test', 1595 'filearea' => 'testarea', 1596 'itemid' => 1, 1597 'filepath' => '/', 1598 'filename' => 'feedback1.txt' 1599 ); 1600 1601 $fs = get_file_storage(); 1602 $fs->create_file_from_string($dummy, ''); 1603 } 1604 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body