See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Unit Tests for the Content Writer used for unit testing. 19 * 20 * @package core_privacy 21 * @category test 22 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 30 use \core_privacy\local\request\writer; 31 use \core_privacy\tests\request\content_writer; 32 33 /** 34 * Unit Tests for the Content Writer used for unit testing. 35 * 36 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk> 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class tests_content_writer_test extends advanced_testcase { 40 41 /** 42 * It should be possible to store and retrieve data. 43 */ 44 public function test_export_data() { 45 $context = \context_system::instance(); 46 $writer = $this->get_writer_instance(); 47 48 $dataa = (object) [ 49 'example' => 'a', 50 ]; 51 $datab = (object) [ 52 'example' => 'b', 53 ]; 54 55 $writer->set_context($context) 56 ->export_data(['data'], $dataa) 57 ->export_data([], $datab); 58 59 $data = $writer->get_data([]); 60 $this->assertSame($datab, $data); 61 62 $data = $writer->get_data(['data']); 63 $this->assertSame($dataa, $data); 64 } 65 66 /** 67 * It should be possible to store and retrieve data at the same point in different contexts. 68 */ 69 public function test_export_data_no_context_clash() { 70 $writer = $this->get_writer_instance(); 71 72 $context = \context_system::instance(); 73 $dataa = (object) [ 74 'example' => 'a', 75 ]; 76 $writer->set_context($context) 77 ->export_data(['data'], $dataa); 78 79 $adminuser = \core_user::get_user_by_username('admin'); 80 $usercontext = \context_user::instance($adminuser->id); 81 $datab = (object) [ 82 'example' => 'b', 83 ]; 84 $writer->set_context($usercontext) 85 ->export_data(['data'], $datab); 86 87 $writer->set_context($context); 88 $data = $writer->get_data(['data']); 89 $this->assertSame($dataa, $data); 90 $this->assertTrue($writer->has_any_data()); 91 $this->assertTrue($writer->has_any_data(['data'])); 92 $this->assertFalse($writer->has_any_data(['somepath'])); 93 94 $writer->set_context($usercontext); 95 $data = $writer->get_data(['data']); 96 $this->assertSame($datab, $data); 97 } 98 99 /** 100 * Test export and recover with children. 101 */ 102 public function test_get_data_with_children() { 103 $writer = $this->get_writer_instance(); 104 $context = \context_system::instance(); 105 106 $writer->set_context($context) 107 ->export_data(['a'], (object) ['parent' => true]) 108 ->export_data(['a', 'b'], (object) ['parent' => false]); 109 110 $this->assertTrue($writer->get_data(['a'])->parent); 111 $this->assertFalse($writer->get_data(['a', 'b'])->parent); 112 $this->assertEquals([], $writer->get_data(['a', 'b', 'c'])); 113 } 114 115 /** 116 * It should be possible to store and retrieve metadata. 117 */ 118 public function test_export_metadata() { 119 $context = \context_system::instance(); 120 $writer = $this->get_writer_instance(); 121 122 $writer->set_context($context) 123 ->export_metadata(['metadata'], 'somekey', 'value1', 'description1') 124 ->export_metadata([], 'somekey', 'value2', 'description2'); 125 126 $allmetadata = $writer->get_all_metadata([]); 127 $this->assertCount(1, $allmetadata); 128 $this->assertArrayHasKey('somekey', $allmetadata); 129 $this->assertEquals('value2', $allmetadata['somekey']->value); 130 $this->assertEquals('description2', $allmetadata['somekey']->description); 131 132 $metadata = $writer->get_metadata([], 'somekey', false); 133 $this->assertEquals('value2', $metadata->value); 134 $this->assertEquals('description2', $metadata->description); 135 $this->assertEquals('value2', $writer->get_metadata([], 'somekey', true)); 136 137 $allmetadata = $writer->get_all_metadata(['metadata']); 138 $this->assertCount(1, $allmetadata); 139 $this->assertArrayHasKey('somekey', $allmetadata); 140 $this->assertEquals('value1', $allmetadata['somekey']->value); 141 $this->assertEquals('description1', $allmetadata['somekey']->description); 142 143 $metadata = $writer->get_metadata(['metadata'], 'somekey', false); 144 $this->assertEquals('value1', $metadata->value); 145 $this->assertEquals('description1', $metadata->description); 146 $this->assertEquals('value1', $writer->get_metadata(['metadata'], 'somekey', true)); 147 } 148 149 /** 150 * It should be possible to store and retrieve metadata at the same point in different contexts. 151 */ 152 public function test_export_metadata_no_context_clash() { 153 $writer = $this->get_writer_instance(); 154 155 $context = \context_system::instance(); 156 $writer->set_context($context) 157 ->export_metadata(['metadata'], 'somekey', 'value1', 'description1'); 158 159 $adminuser = \core_user::get_user_by_username('admin'); 160 $usercontext = \context_user::instance($adminuser->id); 161 $writer->set_context($usercontext) 162 ->export_metadata(['metadata'], 'somekey', 'value2', 'description2'); 163 164 $writer->set_context($context); 165 $allmetadata = $writer->get_all_metadata(['metadata']); 166 $this->assertCount(1, $allmetadata); 167 $this->assertArrayHasKey('somekey', $allmetadata); 168 $this->assertEquals('value1', $allmetadata['somekey']->value); 169 $this->assertEquals('description1', $allmetadata['somekey']->description); 170 171 $metadata = $writer->get_metadata(['metadata'], 'somekey', false); 172 $this->assertEquals('value1', $metadata->value); 173 $this->assertEquals('description1', $metadata->description); 174 $this->assertEquals('value1', $writer->get_metadata(['metadata'], 'somekey', true)); 175 176 $writer->set_context($usercontext); 177 $allmetadata = $writer->get_all_metadata(['metadata']); 178 $this->assertCount(1, $allmetadata); 179 $this->assertArrayHasKey('somekey', $allmetadata); 180 $this->assertEquals('value2', $allmetadata['somekey']->value); 181 $this->assertEquals('description2', $allmetadata['somekey']->description); 182 183 $metadata = $writer->get_metadata(['metadata'], 'somekey', false); 184 $this->assertEquals('value2', $metadata->value); 185 $this->assertEquals('description2', $metadata->description); 186 $this->assertEquals('value2', $writer->get_metadata(['metadata'], 'somekey', true)); 187 $this->assertTrue($writer->has_any_data()); 188 $this->assertTrue($writer->has_any_data(['metadata'])); 189 $this->assertFalse($writer->has_any_data(['somepath'])); 190 } 191 192 /** 193 * It should be possible to store and retrieve user preferences. 194 */ 195 public function test_export_user_preference() { 196 $context = \context_system::instance(); 197 $adminuser = \core_user::get_user_by_username('admin'); 198 $usercontext = \context_user::instance($adminuser->id); 199 $writer = $this->get_writer_instance(); 200 201 $writer->set_context($context) 202 ->export_user_preference('core_privacy', 'somekey', 'value0', 'description0'); 203 $writer->set_context($usercontext) 204 ->export_user_preference('core_tests', 'somekey', 'value1', 'description1') 205 ->export_user_preference('core_privacy', 'somekey', 'value2', 'description2') 206 ->export_user_preference('core_tests', 'someotherkey', 'value2', 'description2'); 207 208 $writer->set_context($usercontext); 209 210 $someprefs = $writer->get_user_preferences('core_privacy'); 211 $this->assertCount(1, (array) $someprefs); 212 $this->assertTrue(isset($someprefs->somekey)); 213 $this->assertEquals('value0', $someprefs->somekey->value); 214 $this->assertEquals('description0', $someprefs->somekey->description); 215 216 $someprefs = $writer->get_user_context_preferences('core_tests'); 217 $this->assertCount(2, (array) $someprefs); 218 $this->assertTrue(isset($someprefs->somekey)); 219 $this->assertEquals('value1', $someprefs->somekey->value); 220 $this->assertEquals('description1', $someprefs->somekey->description); 221 $this->assertTrue(isset($someprefs->someotherkey)); 222 $this->assertEquals('value2', $someprefs->someotherkey->value); 223 $this->assertEquals('description2', $someprefs->someotherkey->description); 224 225 $someprefs = $writer->get_user_context_preferences('core_privacy'); 226 $this->assertCount(1, (array) $someprefs); 227 $this->assertTrue(isset($someprefs->somekey)); 228 $this->assertEquals('value2', $someprefs->somekey->value); 229 $this->assertEquals('description2', $someprefs->somekey->description); 230 } 231 232 /** 233 * It should be possible to store and retrieve user preferences at the same point in different contexts. 234 */ 235 public function test_export_user_preference_no_context_clash() { 236 $writer = $this->get_writer_instance(); 237 $context = \context_system::instance(); 238 $coursecontext = \context_course::instance(SITEID); 239 $adminuser = \core_user::get_user_by_username('admin'); 240 $usercontext = \context_user::instance($adminuser->id); 241 242 $writer->set_context($context) 243 ->export_user_preference('core_tests', 'somekey', 'value0', 'description0'); 244 $writer->set_context($coursecontext) 245 ->export_user_preference('core_tests', 'somekey', 'value1', 'description1'); 246 $writer->set_context($usercontext) 247 ->export_user_preference('core_tests', 'somekey', 'value2', 'description2'); 248 249 // Set the course context and fetch with get_user_preferences to get the global preference. 250 $writer->set_context($coursecontext); 251 $someprefs = $writer->get_user_preferences('core_tests'); 252 $this->assertCount(1, (array) $someprefs); 253 $this->assertTrue(isset($someprefs->somekey)); 254 $this->assertEquals('value0', $someprefs->somekey->value); 255 $this->assertEquals('description0', $someprefs->somekey->description); 256 257 // Set the course context and fetch with get_user_context_preferences. 258 $someprefs = $writer->get_user_context_preferences('core_tests'); 259 $this->assertCount(1, (array) $someprefs); 260 $this->assertTrue(isset($someprefs->somekey)); 261 $this->assertEquals('value1', $someprefs->somekey->value); 262 $this->assertEquals('description1', $someprefs->somekey->description); 263 264 $writer->set_context($usercontext); 265 $someprefs = $writer->get_user_context_preferences('core_tests'); 266 $this->assertCount(1, (array) $someprefs); 267 $this->assertTrue(isset($someprefs->somekey)); 268 $this->assertEquals('value2', $someprefs->somekey->value); 269 $this->assertEquals('description2', $someprefs->somekey->description); 270 } 271 272 /** 273 * Test export and recover with children. 274 */ 275 public function test_get_metadata_with_children() { 276 $writer = $this->get_writer_instance(); 277 $context = \context_system::instance(); 278 279 $writer->set_context($context) 280 ->export_metadata(['a'], 'abc', 'ABC', 'A, B, C') 281 ->export_metadata(['a', 'b'], 'def', 'DEF', 'D, E, F'); 282 283 $this->assertEquals('ABC', $writer->get_metadata(['a'], 'abc')); 284 $this->assertEquals('DEF', $writer->get_metadata(['a', 'b'], 'def')); 285 } 286 287 /** 288 * It should be possible to export files in the files and children contexts. 289 */ 290 public function test_export_file_special_folders() { 291 $context = \context_system::instance(); 292 293 $filea = $this->get_stored_file('/', 'files'); 294 $fileb = $this->get_stored_file('/children/', 'foo.zip'); 295 296 $writer = $this->get_writer_instance() 297 ->set_context($context) 298 ->export_file([], $filea) 299 ->export_file([], $fileb); 300 301 $files = $writer->get_files([]); 302 303 $this->assertCount(2, $files); 304 $this->assertEquals($filea, $files['files']); 305 $this->assertEquals($fileb, $files['children/foo.zip']); 306 } 307 308 /** 309 * It should be possible to export mutliple files in the same subcontext/path space but different context and not 310 * have them clash. 311 */ 312 public function test_export_file_no_context_clash() { 313 $writer = $this->get_writer_instance(); 314 $context = \context_system::instance(); 315 $filea = $this->get_stored_file('/foo/', 'foo.txt'); 316 $writer = $this->get_writer_instance() 317 ->set_context($context) 318 ->export_file([], $filea); 319 320 $adminuser = \core_user::get_user_by_username('admin'); 321 $usercontext = \context_user::instance($adminuser->id); 322 $fileb = $this->get_stored_file('/foo/', 'foo.txt'); 323 $writer->set_context($usercontext) 324 ->export_file([], $fileb); 325 326 $writer->set_context($context); 327 $files = $writer->get_files([]); 328 $this->assertCount(1, $files); 329 $this->assertEquals($filea, $files['foo/foo.txt']); 330 331 $writer->set_context($usercontext); 332 $files = $writer->get_files([]); 333 $this->assertCount(1, $files); 334 $this->assertEquals($fileb, $files['foo/foo.txt']); 335 $this->assertTrue($writer->has_any_data()); 336 $this->assertFalse($writer->has_any_data(['somepath'])); 337 } 338 339 /** 340 * Test export and recover with children. 341 */ 342 public function test_get_file_with_children() { 343 $writer = $this->get_writer_instance(); 344 $context = \context_system::instance(); 345 346 $filea = $this->get_stored_file('/foo/', 'foo.txt'); 347 $fileb = $this->get_stored_file('/foo/', 'foo.txt'); 348 349 $writer->set_context($context) 350 ->export_file(['a'], $filea) 351 ->export_file(['a', 'b'], $fileb); 352 353 $files = $writer->get_files(['a']); 354 $this->assertCount(1, $files); 355 $this->assertEquals($filea, $files['foo/foo.txt']); 356 357 $files = $writer->get_files(['a', 'b']); 358 $this->assertCount(1, $files); 359 $this->assertEquals($fileb, $files['foo/foo.txt']); 360 } 361 362 /** 363 * It should be possible to export related data in the files and children contexts. 364 */ 365 public function test_export_related_data() { 366 $context = \context_system::instance(); 367 368 $writer = $this->get_writer_instance() 369 ->set_context($context) 370 ->export_related_data(['file', 'data'], 'file', 'data1') 371 ->export_related_data([], 'file', 'data2'); 372 373 $data = $writer->get_related_data([]); 374 $this->assertCount(1, $data); 375 $this->assertEquals('data2', $data['file']); 376 377 $data = $writer->get_related_data([], 'file'); 378 $this->assertEquals('data2', $data); 379 380 $data = $writer->get_related_data(['file', 'data']); 381 $this->assertCount(1, $data); 382 $this->assertEquals('data1', $data['file']); 383 384 $data = $writer->get_related_data(['file', 'data'], 'file'); 385 $this->assertEquals('data1', $data); 386 $this->assertTrue($writer->has_any_data()); 387 $this->assertTrue($writer->has_any_data(['file'])); 388 $this->assertTrue($writer->has_any_data(['file', 'data'])); 389 $this->assertFalse($writer->has_any_data(['somepath'])); 390 } 391 392 /** 393 * It should be possible to export related data in the same location,but in a different context. 394 */ 395 public function test_export_related_data_no_context_clash() { 396 $writer = $this->get_writer_instance(); 397 398 $context = \context_system::instance(); 399 $writer->set_context($context) 400 ->export_related_data(['file', 'data'], 'file', 'data1'); 401 402 $adminuser = \core_user::get_user_by_username('admin'); 403 $usercontext = \context_user::instance($adminuser->id); 404 $writer->set_context($usercontext) 405 ->export_related_data(['file', 'data'], 'file', 'data2'); 406 407 $writer->set_context($context); 408 $data = $writer->get_related_data(['file', 'data']); 409 $this->assertCount(1, $data); 410 $this->assertEquals('data1', $data['file']); 411 412 $writer->set_context($usercontext); 413 $data = $writer->get_related_data(['file', 'data']); 414 $this->assertCount(1, $data); 415 $this->assertEquals('data2', $data['file']); 416 } 417 418 /** 419 * Test export and recover with children. 420 */ 421 public function test_get_related_data_with_children() { 422 $writer = $this->get_writer_instance(); 423 $context = \context_system::instance(); 424 425 $writer->set_context($context) 426 ->export_related_data(['a'], 'abc', 'ABC') 427 ->export_related_data(['a', 'b'], 'def', 'DEF'); 428 429 $this->assertEquals('ABC', $writer->get_related_data(['a'], 'abc')); 430 $this->assertEquals('DEF', $writer->get_related_data(['a', 'b'], 'def')); 431 } 432 433 /** 434 * It should be possible to export related files in the files and children contexts. 435 */ 436 public function test_export_custom_file() { 437 $context = \context_system::instance(); 438 439 $writer = $this->get_writer_instance() 440 ->set_context($context) 441 ->export_custom_file(['file.txt'], 'file.txt', 'Content 1') 442 ->export_custom_file([], 'file.txt', 'Content 2'); 443 444 $files = $writer->get_custom_file([]); 445 $this->assertCount(1, $files); 446 $this->assertEquals('Content 2', $files['file.txt']); 447 $file = $writer->get_custom_file([], 'file.txt'); 448 $this->assertEquals('Content 2', $file); 449 450 $files = $writer->get_custom_file(['file.txt']); 451 $this->assertCount(1, $files); 452 $this->assertEquals('Content 1', $files['file.txt']); 453 $file = $writer->get_custom_file(['file.txt'], 'file.txt'); 454 $this->assertEquals('Content 1', $file); 455 $this->assertTrue($writer->has_any_data()); 456 $this->assertTrue($writer->has_any_data(['file.txt'])); 457 $this->assertFalse($writer->has_any_data(['somepath'])); 458 } 459 460 /** 461 * It should be possible to export related files in the same location 462 * in different contexts. 463 */ 464 public function test_export_custom_file_no_context_clash() { 465 $writer = $this->get_writer_instance(); 466 $context = \context_system::instance(); 467 468 $writer->set_context($context) 469 ->export_custom_file(['file.txt'], 'file.txt', 'Content 1'); 470 471 $adminuser = \core_user::get_user_by_username('admin'); 472 $usercontext = \context_user::instance($adminuser->id); 473 $writer->set_context($usercontext) 474 ->export_custom_file(['file.txt'], 'file.txt', 'Content 2'); 475 476 $writer->set_context($context); 477 $files = $writer->get_custom_file(['file.txt']); 478 $this->assertCount(1, $files); 479 $this->assertEquals('Content 1', $files['file.txt']); 480 481 $writer->set_context($usercontext); 482 $files = $writer->get_custom_file(['file.txt']); 483 $this->assertCount(1, $files); 484 $this->assertEquals('Content 2', $files['file.txt']); 485 } 486 487 /** 488 * Test export and recover with children. 489 */ 490 public function test_get_custom_file_with_children() { 491 $writer = $this->get_writer_instance(); 492 $context = \context_system::instance(); 493 494 $writer->set_context($context) 495 ->export_custom_file(['a'], 'file.txt', 'ABC') 496 ->export_custom_file(['a', 'b'], 'file.txt', 'DEF'); 497 498 $this->assertEquals('ABC', $writer->get_custom_file(['a'], 'file.txt')); 499 $this->assertEquals('DEF', $writer->get_custom_file(['a', 'b'], 'file.txt')); 500 } 501 502 /** 503 * Get a fresh content writer. 504 * 505 * @return moodle_content_writer 506 */ 507 public function get_writer_instance() { 508 $factory = $this->createMock(writer::class); 509 return new content_writer($factory); 510 } 511 512 /** 513 * Helper to create a stored file objectw with the given supplied content. 514 * 515 * @param string $filepath The file path to use in the stored_file 516 * @param string $filename The file name to use in the stored_file 517 * @return stored_file 518 */ 519 protected function get_stored_file($filepath, $filename) { 520 static $counter = 0; 521 $counter++; 522 $filecontent = "Example content {$counter}"; 523 $contenthash = file_storage::hash_from_string($filecontent); 524 525 $file = $this->getMockBuilder(stored_file::class) 526 ->setMethods(null) 527 ->setConstructorArgs([ 528 get_file_storage(), 529 (object) [ 530 'contenthash' => $contenthash, 531 'filesize' => strlen($filecontent), 532 'filepath' => $filepath, 533 'filename' => $filename, 534 ] 535 ]) 536 ->getMock(); 537 538 return $file; 539 } 540 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body