See Release Notes
Long Term Support Release
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 * Privacy tests for core_comment. 18 * 19 * @package core_comment 20 * @category test 21 * @copyright 2018 Adrian Greeve <adrian@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die(); 26 global $CFG; 27 28 require_once($CFG->dirroot . '/comment/locallib.php'); 29 require_once($CFG->dirroot . '/comment/lib.php'); 30 31 use \core_privacy\tests\provider_testcase; 32 33 /** 34 * Unit tests for comment/classes/privacy/policy 35 * 36 * @copyright 2018 Adrian Greeve <adrian@moodle.com> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class core_comment_privacy_testcase extends provider_testcase { 40 41 protected function setUp() { 42 $this->resetAfterTest(); 43 } 44 45 /** 46 * Check the exporting of comments for a user id in a context. 47 */ 48 public function test_export_comments() { 49 $course = $this->getDataGenerator()->create_course(); 50 $context = context_course::instance($course->id); 51 52 $comment = $this->get_comment_object($context, $course); 53 54 $user1 = $this->getDataGenerator()->create_user(); 55 $user2 = $this->getDataGenerator()->create_user(); 56 57 // Add comments. 58 $comments = []; 59 $firstcomment = 'This is the first comment'; 60 $this->setUser($user1); 61 $comment->add($firstcomment); 62 $comments[$user1->id] = $firstcomment; 63 64 $secondcomment = 'From the second user'; 65 $this->setUser($user2); 66 $comment->add($secondcomment); 67 $comments[$user2->id] = $secondcomment; 68 69 // Retrieve comments only for user1. 70 $this->setUser($user1); 71 $writer = \core_privacy\local\request\writer::with_context($context); 72 \core_comment\privacy\provider::export_comments($context, 'block_comments', 'page_comments', 0, []); 73 74 $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]); 75 $exportedcomments = $data->comments; 76 77 // There is only one comment made by this user. 78 $this->assertCount(1, $exportedcomments); 79 $comment = reset($exportedcomments); 80 $this->assertEquals($comments[$user1->id], format_string($comment->content, FORMAT_PLAIN)); 81 82 // Retrieve comments from any user. 83 \core_comment\privacy\provider::export_comments($context, 'block_comments', 'page_comments', 0, [], false); 84 85 $data = $writer->get_data([get_string('commentsubcontext', 'core_comment')]); 86 $exportedcomments = $data->comments; 87 88 // The whole conversation is two comments. 89 $this->assertCount(2, $exportedcomments); 90 foreach ($exportedcomments as $comment) { 91 $this->assertEquals($comments[$comment->userid], format_string($comment->content, FORMAT_PLAIN)); 92 } 93 } 94 95 /** 96 * Tests the deletion of all comments in a context. 97 */ 98 public function test_delete_comments_for_all_users() { 99 global $DB; 100 101 $course1 = $this->getDataGenerator()->create_course(); 102 $course2 = $this->getDataGenerator()->create_course(); 103 104 $coursecontext1 = context_course::instance($course1->id); 105 $coursecontext2 = context_course::instance($course2->id); 106 107 $user1 = $this->getDataGenerator()->create_user(); 108 $user2 = $this->getDataGenerator()->create_user(); 109 110 $comment1 = $this->get_comment_object($coursecontext1, $course1); 111 $comment2 = $this->get_comment_object($coursecontext2, $course2); 112 113 $this->setUser($user1); 114 $comment1->add('First comment for user 1 on comment 1'); 115 $comment2->add('First comment for user 1 on comment 2'); 116 $this->setUser($user2); 117 $comment1->add('First comment for user 2 on comment 1'); 118 $comment2->add('First comment for user 2 on comment 2'); 119 120 // Because of the way things are set up with validation, creating an entry with the same context in a different component 121 // or comment area is a huge pain. We're just going to jam entries into the table instead. 122 $record = (object) [ 123 'contextid' => $coursecontext1->id, 124 'component' => 'block_comments', 125 'commentarea' => 'other_comments', 126 'itemid' => 2, 127 'content' => 'Comment user 1 different comment area', 128 'format' => 0, 129 'userid' => $user1->id, 130 'timecreated' => time() 131 ]; 132 $DB->insert_record('comments', $record); 133 $record = (object) [ 134 'contextid' => $coursecontext1->id, 135 'component' => 'tool_dataprivacy', 136 'commentarea' => 'page_comments', 137 'itemid' => 2, 138 'content' => 'Comment user 1 different component', 139 'format' => 0, 140 'userid' => $user1->id, 141 'timecreated' => time() 142 ]; 143 $DB->insert_record('comments', $record); 144 145 // Delete only for the first context. All records in the comments table for this context should be removed. 146 \core_comment\privacy\provider::delete_comments_for_all_users($coursecontext1, 'block_comments', 'page_comments', 0); 147 // No records left here. 148 $this->assertCount(0, $comment1->get_comments()); 149 // All of the records are left intact here. 150 $this->assertCount(2, $comment2->get_comments()); 151 // Check the other comment area. 152 $result = $DB->get_records('comments', ['commentarea' => 'other_comments']); 153 $this->assertCount(1, $result); 154 $data = array_shift($result); 155 $this->assertEquals('other_comments', $data->commentarea); 156 // Check the different component, same commentarea. 157 $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']); 158 $this->assertCount(1, $result); 159 $data = array_shift($result); 160 $this->assertEquals('tool_dataprivacy', $data->component); 161 } 162 163 /** 164 * Tests the deletion of all comments in a context. 165 */ 166 public function test_delete_comments_for_all_users_select() { 167 global $DB; 168 169 $course1 = $this->getDataGenerator()->create_course(); 170 $course2 = $this->getDataGenerator()->create_course(); 171 172 $coursecontext1 = context_course::instance($course1->id); 173 $coursecontext2 = context_course::instance($course2->id); 174 175 $user1 = $this->getDataGenerator()->create_user(); 176 $user2 = $this->getDataGenerator()->create_user(); 177 178 $comment1 = $this->get_comment_object($coursecontext1, $course1); 179 $comment2 = $this->get_comment_object($coursecontext2, $course2); 180 181 $this->setUser($user1); 182 $comment1->add('First comment for user 1 on comment 1'); 183 $comment2->add('First comment for user 1 on comment 2'); 184 $this->setUser($user2); 185 $comment1->add('First comment for user 2 on comment 1'); 186 $comment2->add('First comment for user 2 on comment 2'); 187 188 // Because of the way things are set up with validation, creating an entry with the same context in a different component 189 // or comment area is a huge pain. We're just going to jam entries into the table instead. 190 $record = (object) [ 191 'contextid' => $coursecontext1->id, 192 'component' => 'block_comments', 193 'commentarea' => 'other_comments', 194 'itemid' => 2, 195 'content' => 'Comment user 1 different comment area', 196 'format' => 0, 197 'userid' => $user1->id, 198 'timecreated' => time() 199 ]; 200 $DB->insert_record('comments', $record); 201 $record = (object) [ 202 'contextid' => $coursecontext1->id, 203 'component' => 'tool_dataprivacy', 204 'commentarea' => 'page_comments', 205 'itemid' => 2, 206 'content' => 'Comment user 1 different component', 207 'format' => 0, 208 'userid' => $user1->id, 209 'timecreated' => time() 210 ]; 211 $DB->insert_record('comments', $record); 212 213 // Delete only for the first context. All records in the comments table for this context should be removed. 214 list($sql, $params) = $DB->get_in_or_equal([0, 1, 2, 3], SQL_PARAMS_NAMED); 215 \core_comment\privacy\provider::delete_comments_for_all_users_select($coursecontext1, 216 'block_comments', 'page_comments', $sql, $params); 217 // No records left here. 218 $this->assertCount(0, $comment1->get_comments()); 219 // All of the records are left intact here. 220 $this->assertCount(2, $comment2->get_comments()); 221 // Check the other comment area. 222 $result = $DB->get_records('comments', ['commentarea' => 'other_comments']); 223 $this->assertCount(1, $result); 224 $data = array_shift($result); 225 $this->assertEquals('other_comments', $data->commentarea); 226 // Check the different component, same commentarea. 227 $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']); 228 $this->assertCount(1, $result); 229 $data = array_shift($result); 230 $this->assertEquals('tool_dataprivacy', $data->component); 231 } 232 233 /** 234 * Tests deletion of comments for a specified user and contexts. 235 */ 236 public function test_delete_comments_for_user() { 237 global $DB; 238 239 $course1 = $this->getDataGenerator()->create_course(); 240 $course2 = $this->getDataGenerator()->create_course(); 241 $course3 = $this->getDataGenerator()->create_course(); 242 243 $coursecontext1 = context_course::instance($course1->id); 244 $coursecontext2 = context_course::instance($course2->id); 245 $coursecontext3 = context_course::instance($course3->id); 246 247 $user1 = $this->getDataGenerator()->create_user(); 248 $user2 = $this->getDataGenerator()->create_user(); 249 250 $comment1 = $this->get_comment_object($coursecontext1, $course1); 251 $comment2 = $this->get_comment_object($coursecontext2, $course2); 252 $comment3 = $this->get_comment_object($coursecontext3, $course3); 253 254 $this->setUser($user1); 255 $comment1->add('First comment for user 1'); 256 $comment2->add('User 1 comment in second comment'); 257 258 $this->setUser($user2); 259 $comment2->add('User two replied in comment two'); 260 $comment3->add('Comment three for user 2.'); 261 262 // Because of the way things are set up with validation, creating an entry with the same context in a different component 263 // or comment area is a huge pain. We're just going to jam entries into the table instead. 264 $record = (object) [ 265 'contextid' => $coursecontext1->id, 266 'component' => 'block_comments', 267 'commentarea' => 'other_comments', 268 'itemid' => 2, 269 'content' => 'Comment user 1 different comment area', 270 'format' => 0, 271 'userid' => $user1->id, 272 'timecreated' => time() 273 ]; 274 $DB->insert_record('comments', $record); 275 $record = (object) [ 276 'contextid' => $coursecontext1->id, 277 'component' => 'tool_dataprivacy', 278 'commentarea' => 'page_comments', 279 'itemid' => 2, 280 'content' => 'Comment user 1 different component', 281 'format' => 0, 282 'userid' => $user1->id, 283 'timecreated' => time() 284 ]; 285 $DB->insert_record('comments', $record); 286 287 // Delete the comments for user 1. 288 $approvedcontextlist = new core_privacy\tests\request\approved_contextlist($user1, 'block_comments', 289 [$coursecontext1->id, $coursecontext2->id]); 290 \core_comment\privacy\provider::delete_comments_for_user($approvedcontextlist, 'block_comments', 'page_comments', 0); 291 292 // No comments left in comments 1 as only user 1 commented there. 293 $this->assertCount(0, $comment1->get_comments()); 294 // Only user 2 comments left in comments 2. 295 $comment2comments = $comment2->get_comments(); 296 $this->assertCount(1, $comment2comments); 297 $data = array_shift($comment2comments); 298 $this->assertEquals($user2->id, $data->userid); 299 // Nothing changed here as user 1 did not leave a comment. 300 $comment3comments = $comment3->get_comments(); 301 $this->assertCount(1, $comment3comments); 302 $data = array_shift($comment3comments); 303 $this->assertEquals($user2->id, $data->userid); 304 // Check the other comment area. 305 $result = $DB->get_records('comments', ['commentarea' => 'other_comments']); 306 $this->assertCount(1, $result); 307 $data = array_shift($result); 308 $this->assertEquals('other_comments', $data->commentarea); 309 // Check the different component, same commentarea. 310 $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']); 311 $this->assertCount(1, $result); 312 $data = array_shift($result); 313 $this->assertEquals('tool_dataprivacy', $data->component); 314 } 315 316 /** 317 * Tests deletion of comments for a specified userlist and context. 318 */ 319 public function test_delete_comments_for_users() { 320 global $DB; 321 322 $course1 = $this->getDataGenerator()->create_course(); 323 $course2 = $this->getDataGenerator()->create_course(); 324 $course3 = $this->getDataGenerator()->create_course(); 325 326 $coursecontext1 = context_course::instance($course1->id); 327 $coursecontext2 = context_course::instance($course2->id); 328 $coursecontext3 = context_course::instance($course3->id); 329 330 $user1 = $this->getDataGenerator()->create_user(); 331 $user2 = $this->getDataGenerator()->create_user(); 332 $user3 = $this->getDataGenerator()->create_user(); 333 334 $comment1 = $this->get_comment_object($coursecontext1, $course1); 335 $comment2 = $this->get_comment_object($coursecontext2, $course2); 336 $comment3 = $this->get_comment_object($coursecontext3, $course3); 337 338 $this->setUser($user1); 339 $comment1->add('First comment for user 1'); 340 $comment2->add('User 1 comment in second comment'); 341 342 $this->setUser($user2); 343 $comment2->add('User two replied in comment two'); 344 345 $this->setUser($user3); 346 $comment2->add('User 3 also writing on comment 2, but will not be deleted'); 347 $comment3->add('Only user 3 commenting in comment 3.'); 348 349 // Because of the way things are set up with validation, creating an entry with the same context in a different component 350 // or comment area is a huge pain. We're just going to jam entries into the table instead. 351 $record = (object) [ 352 'contextid' => $coursecontext1->id, 353 'component' => 'block_comments', 354 'commentarea' => 'other_comments', 355 'itemid' => 2, 356 'content' => 'Comment user 1 different comment area', 357 'format' => 0, 358 'userid' => $user1->id, 359 'timecreated' => time() 360 ]; 361 $DB->insert_record('comments', $record); 362 $record = (object) [ 363 'contextid' => $coursecontext1->id, 364 'component' => 'tool_dataprivacy', 365 'commentarea' => 'page_comments', 366 'itemid' => 2, 367 'content' => 'Comment user 1 different component', 368 'format' => 0, 369 'userid' => $user1->id, 370 'timecreated' => time() 371 ]; 372 $DB->insert_record('comments', $record); 373 374 // Delete the comments for users 1 and 2 in all 3 contexts. 375 $approvedusers = [$user1->id, $user2->id]; 376 377 $approveduserlist = new core_privacy\local\request\approved_userlist($coursecontext1, 'block_comments', $approvedusers); 378 \core_comment\privacy\provider::delete_comments_for_users($approveduserlist, 'block_comments', 'page_comments'); 379 380 $approveduserlist = new core_privacy\local\request\approved_userlist($coursecontext2, 'block_comments', $approvedusers); 381 \core_comment\privacy\provider::delete_comments_for_users($approveduserlist, 'block_comments', 'page_comments'); 382 383 $approveduserlist = new core_privacy\local\request\approved_userlist($coursecontext3, 'block_comments', $approvedusers); 384 \core_comment\privacy\provider::delete_comments_for_users($approveduserlist, 'block_comments', 'page_comments'); 385 386 // No comments left in comments 1 as only user 1 commented there. 387 $this->assertCount(0, $comment1->get_comments()); 388 389 // Only user 3's comment left in comments 2 as user 1 and 2 were approved for deletion. 390 $comment2comments = $comment2->get_comments(); 391 $this->assertCount(1, $comment2comments); 392 $comment2comment = array_shift($comment2comments); 393 $this->assertEquals($user3->id, $comment2comment->userid); 394 395 // Nothing changed here as user 1 and 2 did not leave a comment. 396 $comment3comments = $comment3->get_comments(); 397 $this->assertCount(1, $comment3comments); 398 $data = array_shift($comment3comments); 399 $this->assertEquals($user3->id, $data->userid); 400 401 // Check the other comment area. 402 $result = $DB->get_records('comments', ['commentarea' => 'other_comments']); 403 $this->assertCount(1, $result); 404 $data = array_shift($result); 405 $this->assertEquals('other_comments', $data->commentarea); 406 407 // Check the different component, same commentarea. 408 $result = $DB->get_records('comments', ['component' => 'tool_dataprivacy']); 409 $this->assertCount(1, $result); 410 $data = array_shift($result); 411 $this->assertEquals('tool_dataprivacy', $data->component); 412 } 413 414 /** 415 * Creates a comment object 416 * 417 * @param context $context A context object. 418 * @param stdClass $course A course object. 419 * @return comment The comment object. 420 */ 421 protected function get_comment_object($context, $course) { 422 // Comment on course page. 423 $args = new stdClass; 424 $args->context = $context; 425 $args->course = $course; 426 $args->area = 'page_comments'; 427 $args->itemid = 0; 428 $args->component = 'block_comments'; 429 $comment = new comment($args); 430 $comment->set_post_permission(true); 431 return $comment; 432 } 433 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body