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 * Privacy provider tests. 19 * 20 * @package mod_glossary 21 * @copyright 2018 Simey Lameze <simey@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 use core_privacy\local\metadata\collection; 26 use core_privacy\local\request\deletion_criteria; 27 use mod_glossary\privacy\provider; 28 29 defined('MOODLE_INTERNAL') || die(); 30 31 global $CFG; 32 require_once($CFG->dirroot . '/comment/lib.php'); 33 require_once($CFG->dirroot . '/rating/lib.php'); 34 35 /** 36 * Privacy provider tests class. 37 * 38 * @package mod_glossary 39 * @copyright 2018 Simey Lameze <simey@moodle.com> 40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 41 */ 42 class mod_glossary_privacy_provider_testcase extends \core_privacy\tests\provider_testcase { 43 /** @var stdClass The student object. */ 44 protected $student; 45 46 /** @var stdClass The teacher object. */ 47 protected $teacher; 48 49 /** @var stdClass The glossary object. */ 50 protected $glossary; 51 52 /** @var stdClass The course object. */ 53 protected $course; 54 55 /** @var stdClass The plugin generator object. */ 56 protected $plugingenerator; 57 58 /** 59 * {@inheritdoc} 60 */ 61 protected function setUp(): void { 62 $this->resetAfterTest(); 63 64 global $DB; 65 $generator = $this->getDataGenerator(); 66 $course = $generator->create_course(); 67 $this->course = $course; 68 69 $this->plugingenerator = $generator->get_plugin_generator('mod_glossary'); 70 71 // The glossary activity the user will answer. 72 $glossary = $this->plugingenerator->create_instance(['course' => $course->id]); 73 $this->glossary = $glossary; 74 75 $cm = get_coursemodule_from_instance('glossary', $glossary->id); 76 $context = context_module::instance($cm->id); 77 78 // Create a student which will add an entry to a glossary. 79 $student = $generator->create_user(); 80 $generator->enrol_user($student->id, $course->id, 'student'); 81 $this->student = $student; 82 83 $teacher = $generator->create_user(); 84 $generator->enrol_user($teacher->id, $course->id, 'editingteacher'); 85 $this->teacher = $teacher; 86 87 $this->setUser($student->id); 88 $ge1 = $this->plugingenerator->create_content($glossary, ['concept' => 'first', 'approved' => 1], ['one']); 89 90 // Student create a comment on a glossary entry. 91 $this->setUser($student); 92 $comment = $this->get_comment_object($context, $ge1->id); 93 $comment->add('Hello, it\'s me!'); 94 95 // Attach tags. 96 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context, ['Beer', 'Golf']); 97 } 98 99 /** 100 * Test for provider::get_metadata(). 101 */ 102 public function test_get_metadata() { 103 $collection = new collection('mod_glossary'); 104 $newcollection = provider::get_metadata($collection); 105 $itemcollection = $newcollection->get_collection(); 106 $this->assertCount(5, $itemcollection); 107 108 $table = reset($itemcollection); 109 $this->assertEquals('glossary_entries', $table->get_name()); 110 111 $privacyfields = $table->get_privacy_fields(); 112 $this->assertArrayHasKey('glossaryid', $privacyfields); 113 $this->assertArrayHasKey('concept', $privacyfields); 114 $this->assertArrayHasKey('definition', $privacyfields); 115 $this->assertArrayHasKey('attachment', $privacyfields); 116 $this->assertArrayHasKey('userid', $privacyfields); 117 $this->assertArrayHasKey('timemodified', $privacyfields); 118 119 $this->assertEquals('privacy:metadata:glossary_entries', $table->get_summary()); 120 } 121 122 /** 123 * Test for provider::get_contexts_for_userid(). 124 */ 125 public function test_get_contexts_for_userid() { 126 $cm = get_coursemodule_from_instance('glossary', $this->glossary->id); 127 128 $contextlist = provider::get_contexts_for_userid($this->student->id); 129 $this->assertCount(1, $contextlist); 130 $contextforuser = $contextlist->current(); 131 $cmcontext = context_module::instance($cm->id); 132 $this->assertEquals($cmcontext->id, $contextforuser->id); 133 } 134 135 /** 136 * Test for provider::get_users_in_context(). 137 */ 138 public function test_get_users_in_context() { 139 $component = 'mod_glossary'; 140 $cm = get_coursemodule_from_instance('glossary', $this->glossary->id); 141 $cmcontext = context_module::instance($cm->id); 142 143 $userlist = new \core_privacy\local\request\userlist($cmcontext, $component); 144 provider::get_users_in_context($userlist); 145 146 $this->assertCount(1, $userlist); 147 148 $expected = [$this->student->id]; 149 $actual = $userlist->get_userids(); 150 sort($expected); 151 sort($actual); 152 153 $this->assertEquals($expected, $actual); 154 } 155 156 /** 157 * Test for provider::export_user_data(). 158 */ 159 public function test_export_for_context() { 160 $cm = get_coursemodule_from_instance('glossary', $this->glossary->id); 161 $cmcontext = context_module::instance($cm->id); 162 163 // Export all of the data for the context. 164 $writer = \core_privacy\local\request\writer::with_context($cmcontext); 165 $contextlist = new \core_privacy\local\request\approved_contextlist($this->student, 'mod_glossary' , [$cmcontext->id]); 166 167 \mod_glossary\privacy\provider::export_user_data($contextlist); 168 $this->assertTrue($writer->has_any_data()); 169 $data = $writer->get_data([]); 170 171 $this->assertEquals('Glossary 1', $data->name); 172 $this->assertEquals('first', $data->entries[0]['concept']); 173 } 174 175 /** 176 * Test for provider::delete_data_for_all_users_in_context(). 177 */ 178 public function test_delete_data_for_all_users_in_context() { 179 global $DB; 180 181 $generator = $this->getDataGenerator(); 182 $cm = get_coursemodule_from_instance('glossary', $this->glossary->id); 183 $context = context_module::instance($cm->id); 184 // Create another student who will add an entry the glossary activity. 185 $student2 = $generator->create_user(); 186 $generator->enrol_user($student2->id, $this->course->id, 'student'); 187 188 $this->setUser($student2); 189 $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first', 'approved' => 1], ['three']); 190 $comment = $this->get_comment_object($context, $ge3->id); 191 $comment->add('User 2 comment'); 192 193 $this->plugingenerator->create_category($this->glossary, ['cat1'], [$ge3]); 194 $count = $DB->count_records('glossary_entries_categories', ['entryid' => $ge3->id]); 195 $this->assertEquals(1, $count); 196 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context, ['Pizza', 'Noodles']); 197 198 // As a teacher, rate student 2 entry. 199 $this->setUser($this->teacher); 200 $rating = $this->get_rating_object($context, $ge3->id); 201 $rating->update_rating(2); 202 203 // Before deletion, we should have 2 entries. 204 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]); 205 $this->assertEquals(2, $count); 206 $aliascount = $DB->count_records('glossary_alias'); 207 $this->assertEquals(2, $aliascount); 208 // Delete data based on context. 209 provider::delete_data_for_all_users_in_context($context); 210 211 // After deletion, the glossary entries and aliases for that glossary activity should have been deleted. 212 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]); 213 $this->assertEquals(0, $count); 214 $this->assertEquals(0, $DB->count_records('glossary_alias')); 215 $count = $DB->count_records('glossary_entries_categories', ['entryid' => $ge3->id]); 216 $this->assertEquals(0, $count); 217 $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries', 218 'itemid' => $ge3->id]); 219 $this->assertEquals(0, $tagcount); 220 221 $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry', 222 'itemid' => $ge3->id, 'userid' => $student2->id]); 223 $this->assertEquals(0, $commentcount); 224 225 $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry', 226 'itemid' => $ge3->id]); 227 $this->assertEquals(0, $ratingcount); 228 } 229 230 /** 231 * Test for provider::delete_data_for_user(). 232 */ 233 public function test_delete_data_for_user() { 234 global $DB; 235 $generator = $this->getDataGenerator(); 236 237 // Create another student who will add an entry to the first glossary. 238 $student2 = $generator->create_user(); 239 $generator->enrol_user($student2->id, $this->course->id, 'student'); 240 241 $cm1 = get_coursemodule_from_instance('glossary', $this->glossary->id); 242 $glossary2 = $this->plugingenerator->create_instance(['course' => $this->course->id]); 243 $cm2 = get_coursemodule_from_instance('glossary', $glossary2->id); 244 245 $ge1 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first user glossary entry', 'approved' => 1]); 246 $this->plugingenerator->create_content($glossary2, ['concept' => 'first user second glossary entry', 'approved' => 1]); 247 248 $context1 = context_module::instance($cm1->id); 249 $context2 = context_module::instance($cm2->id); 250 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context1, ['Parmi', 'Sushi']); 251 252 $this->setUser($student2); 253 $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'second user glossary entry', 254 'approved' => 1], ['three']); 255 256 $comment = $this->get_comment_object($context1, $ge3->id); 257 $comment->add('User 2 comment'); 258 259 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context1, ['Pizza', 'Noodles']); 260 261 // As a teacher, rate student 2's entry. 262 $this->setUser($this->teacher); 263 $rating = $this->get_rating_object($context1, $ge3->id); 264 $rating->update_rating(2); 265 266 // Before deletion, we should have 3 entries, one rating and 2 tag instances. 267 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]); 268 $this->assertEquals(3, $count); 269 $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries', 270 'itemid' => $ge3->id]); 271 $this->assertEquals(2, $tagcount); 272 $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge3->id]); 273 $this->assertEquals(1, $aliascount); 274 $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry', 275 'itemid' => $ge3->id]); 276 $this->assertEquals(1, $ratingcount); 277 278 $contextlist = new \core_privacy\local\request\approved_contextlist($student2, 'glossary', 279 [$context1->id, $context2->id]); 280 provider::delete_data_for_user($contextlist); 281 282 // After deletion, the glossary entry and tags for the second student should have been deleted. 283 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id, 'userid' => $student2->id]); 284 $this->assertEquals(0, $count); 285 286 $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries', 287 'itemid' => $ge3->id]); 288 $this->assertEquals(0, $tagcount); 289 290 $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry', 291 'itemid' => $ge3->id, 'userid' => $student2->id]); 292 $this->assertEquals(0, $commentcount); 293 $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge3->id]); 294 $this->assertEquals(0, $aliascount); 295 296 // Student's 1 entries, comments and tags should not be removed. 297 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id, 298 'userid' => $this->student->id]); 299 $this->assertEquals(2, $count); 300 301 $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries', 302 'itemid' => $ge1->id]); 303 $this->assertEquals(2, $tagcount); 304 305 $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry', 306 'userid' => $this->student->id]); 307 $this->assertEquals(1, $commentcount); 308 309 $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry', 310 'itemid' => $ge3->id]); 311 $this->assertEquals(0, $ratingcount); 312 } 313 314 /** 315 * Test for provider::delete_data_for_users(). 316 */ 317 public function test_delete_data_for_users() { 318 global $DB; 319 $generator = $this->getDataGenerator(); 320 321 $student2 = $generator->create_user(); 322 $generator->enrol_user($student2->id, $this->course->id, 'student'); 323 324 $cm1 = get_coursemodule_from_instance('glossary', $this->glossary->id); 325 $glossary2 = $this->plugingenerator->create_instance(['course' => $this->course->id]); 326 $cm2 = get_coursemodule_from_instance('glossary', $glossary2->id); 327 328 $ge1 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'first user glossary entry', 'approved' => 1]); 329 $ge2 = $this->plugingenerator->create_content($glossary2, ['concept' => 'first user second glossary entry', 330 'approved' => 1], ['two']); 331 332 $context1 = context_module::instance($cm1->id); 333 $context2 = context_module::instance($cm2->id); 334 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge1->id, $context1, ['Parmi', 'Sushi']); 335 336 $this->setUser($student2); 337 $ge3 = $this->plugingenerator->create_content($this->glossary, ['concept' => 'second user glossary entry', 338 'approved' => 1], ['three']); 339 340 $comment = $this->get_comment_object($context1, $ge3->id); 341 $comment->add('User 2 comment 1'); 342 $comment = $this->get_comment_object($context2, $ge2->id); 343 $comment->add('User 2 comment 2'); 344 345 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge3->id, $context1, ['Pizza', 'Noodles']); 346 core_tag_tag::set_item_tags('mod_glossary', 'glossary_entries', $ge2->id, $context2, ['Potato', 'Kumara']); 347 348 // As a teacher, rate student 2's entry. 349 $this->setUser($this->teacher); 350 $rating = $this->get_rating_object($context1, $ge3->id); 351 $rating->update_rating(2); 352 353 // Check correct glossary 1 record counts before deletion. 354 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]); 355 // Note: There is an additional student entry from setUp(). 356 $this->assertEquals(3, $count); 357 358 list($context1itemsql, $context1itemparams) = $DB->get_in_or_equal([$ge1->id, $ge3->id], SQL_PARAMS_NAMED); 359 $geparams = [ 360 'component' => 'mod_glossary', 361 'itemtype' => 'glossary_entries', 362 ]; 363 $geparams += $context1itemparams; 364 $wheresql = "component = :component AND itemtype = :itemtype AND itemid {$context1itemsql}"; 365 366 $tagcount = $DB->count_records_select('tag_instance', $wheresql, $geparams); 367 $this->assertEquals(4, $tagcount); 368 369 $aliascount = $DB->count_records_select('glossary_alias', "entryid {$context1itemsql}", $context1itemparams); 370 $this->assertEquals(1, $aliascount); 371 372 $commentparams = [ 373 'component' => 'mod_glossary', 374 'commentarea' => 'glossary_entry', 375 ]; 376 $commentparams += $context1itemparams; 377 $commentwhere = "component = :component AND commentarea = :commentarea AND itemid {$context1itemsql}"; 378 379 $commentcount = $DB->count_records_select('comments', $commentwhere, $commentparams); 380 $this->assertEquals(1, $commentcount); 381 382 $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry', 383 'itemid' => $ge3->id]); 384 $this->assertEquals(1, $ratingcount); 385 386 // Perform deletion within context 1 for both students. 387 $approveduserlist = new core_privacy\local\request\approved_userlist($context1, 'mod_glossary', 388 [$this->student->id, $student2->id]); 389 provider::delete_data_for_users($approveduserlist); 390 391 // After deletion, all context 1 entries, tags and comment should be deleted. 392 $count = $DB->count_records('glossary_entries', ['glossaryid' => $this->glossary->id]); 393 $this->assertEquals(0, $count); 394 395 $tagcount = $DB->count_records_select('tag_instance', $wheresql, $geparams); 396 $this->assertEquals(0, $tagcount); 397 398 $aliascount = $DB->count_records_select('glossary_alias', "entryid {$context1itemsql}", $context1itemparams); 399 $this->assertEquals(0, $aliascount); 400 401 $commentcount = $DB->count_records_select('comments', $commentwhere, $commentparams); 402 $this->assertEquals(0, $commentcount); 403 404 // Context 2 entries should remain intact. 405 $count = $DB->count_records('glossary_entries', ['glossaryid' => $glossary2->id]); 406 $this->assertEquals(1, $count); 407 408 $tagcount = $DB->count_records('tag_instance', ['component' => 'mod_glossary', 'itemtype' => 'glossary_entries', 409 'itemid' => $ge2->id]); 410 $this->assertEquals(2, $tagcount); 411 412 $aliascount = $DB->count_records('glossary_alias', ['entryid' => $ge2->id]); 413 $this->assertEquals(1, $aliascount); 414 415 $commentcount = $DB->count_records('comments', ['component' => 'mod_glossary', 'commentarea' => 'glossary_entry', 416 'itemid' => $ge2->id]); 417 $this->assertEquals(1, $commentcount); 418 419 $ratingcount = $DB->count_records('rating', ['component' => 'mod_glossary', 'ratingarea' => 'entry', 420 'itemid' => $ge3->id]); 421 $this->assertEquals(0, $ratingcount); 422 } 423 424 /** 425 * Get the comment area for glossary module. 426 * 427 * @param context $context The context. 428 * @param int $itemid The item ID. 429 * @return comment 430 */ 431 protected function get_comment_object(context $context, $itemid) { 432 $args = new stdClass(); 433 434 $args->context = $context; 435 $args->course = get_course(SITEID); 436 $args->area = 'glossary_entry'; 437 $args->itemid = $itemid; 438 $args->component = 'mod_glossary'; 439 $comment = new comment($args); 440 $comment->set_post_permission(true); 441 442 return $comment; 443 } 444 445 /** 446 * Get the rating area for glossary module. 447 * 448 * @param context $context The context. 449 * @param int $itemid The item ID. 450 * @return rating object 451 */ 452 protected function get_rating_object(context $context, $itemid) { 453 global $USER; 454 455 $ratingoptions = new stdClass; 456 $ratingoptions->context = $context; 457 $ratingoptions->ratingarea = 'entry'; 458 $ratingoptions->component = 'mod_glossary'; 459 $ratingoptions->itemid = $itemid; 460 $ratingoptions->scaleid = 2; 461 $ratingoptions->userid = $USER->id; 462 return new rating($ratingoptions); 463 } 464 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body