Automatically generated installer lang files
[moodle.git] / privacy / tests / tests_content_writer_test.php
blobf3a869849952b30cf3e612621945778e4a3f0eab
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.
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/>.
17 /**
18 * Unit Tests for the Content Writer used for unit testing.
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
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 use \core_privacy\local\request\writer;
31 use \core_privacy\tests\request\content_writer;
33 /**
34 * Unit Tests for the Content Writer used for unit testing.
36 * @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 class tests_content_writer_test extends advanced_testcase {
41 /**
42 * It should be possible to store and retrieve data.
44 public function test_export_data() {
45 $context = \context_system::instance();
46 $writer = $this->get_writer_instance();
48 $dataa = (object) [
49 'example' => 'a',
51 $datab = (object) [
52 'example' => 'b',
55 $writer->set_context($context)
56 ->export_data(['data'], $dataa)
57 ->export_data([], $datab);
59 $data = $writer->get_data([]);
60 $this->assertSame($datab, $data);
62 $data = $writer->get_data(['data']);
63 $this->assertSame($dataa, $data);
66 /**
67 * It should be possible to store and retrieve data at the same point in different contexts.
69 public function test_export_data_no_context_clash() {
70 $writer = $this->get_writer_instance();
72 $context = \context_system::instance();
73 $dataa = (object) [
74 'example' => 'a',
76 $writer->set_context($context)
77 ->export_data(['data'], $dataa);
79 $adminuser = \core_user::get_user_by_username('admin');
80 $usercontext = \context_user::instance($adminuser->id);
81 $datab = (object) [
82 'example' => 'b',
84 $writer->set_context($usercontext)
85 ->export_data(['data'], $datab);
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']));
94 $writer->set_context($usercontext);
95 $data = $writer->get_data(['data']);
96 $this->assertSame($datab, $data);
99 /**
100 * Test export and recover with children.
102 public function test_get_data_with_children() {
103 $writer = $this->get_writer_instance();
104 $context = \context_system::instance();
106 $writer->set_context($context)
107 ->export_data(['a'], (object) ['parent' => true])
108 ->export_data(['a', 'b'], (object) ['parent' => false]);
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']));
116 * It should be possible to store and retrieve metadata.
118 public function test_export_metadata() {
119 $context = \context_system::instance();
120 $writer = $this->get_writer_instance();
122 $writer->set_context($context)
123 ->export_metadata(['metadata'], 'somekey', 'value1', 'description1')
124 ->export_metadata([], 'somekey', 'value2', 'description2');
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);
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));
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);
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));
150 * It should be possible to store and retrieve metadata at the same point in different contexts.
152 public function test_export_metadata_no_context_clash() {
153 $writer = $this->get_writer_instance();
155 $context = \context_system::instance();
156 $writer->set_context($context)
157 ->export_metadata(['metadata'], 'somekey', 'value1', 'description1');
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');
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);
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));
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);
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']));
193 * It should be possible to store and retrieve user preferences.
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();
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');
208 $writer->set_context($usercontext);
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);
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);
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);
233 * It should be possible to store and retrieve user preferences at the same point in different contexts.
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);
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');
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);
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);
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);
273 * Test export and recover with children.
275 public function test_get_metadata_with_children() {
276 $writer = $this->get_writer_instance();
277 $context = \context_system::instance();
279 $writer->set_context($context)
280 ->export_metadata(['a'], 'abc', 'ABC', 'A, B, C')
281 ->export_metadata(['a', 'b'], 'def', 'DEF', 'D, E, F');
283 $this->assertEquals('ABC', $writer->get_metadata(['a'], 'abc'));
284 $this->assertEquals('DEF', $writer->get_metadata(['a', 'b'], 'def'));
288 * It should be possible to export files in the files and children contexts.
290 public function test_export_file_special_folders() {
291 $context = \context_system::instance();
293 $filea = $this->get_stored_file('/', 'files');
294 $fileb = $this->get_stored_file('/children/', 'foo.zip');
296 $writer = $this->get_writer_instance()
297 ->set_context($context)
298 ->export_file([], $filea)
299 ->export_file([], $fileb);
301 $files = $writer->get_files([]);
303 $this->assertCount(2, $files);
304 $this->assertEquals($filea, $files['files']);
305 $this->assertEquals($fileb, $files['children/foo.zip']);
309 * It should be possible to export mutliple files in the same subcontext/path space but different context and not
310 * have them clash.
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);
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);
326 $writer->set_context($context);
327 $files = $writer->get_files([]);
328 $this->assertCount(1, $files);
329 $this->assertEquals($filea, $files['foo/foo.txt']);
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']));
340 * Test export and recover with children.
342 public function test_get_file_with_children() {
343 $writer = $this->get_writer_instance();
344 $context = \context_system::instance();
346 $filea = $this->get_stored_file('/foo/', 'foo.txt');
347 $fileb = $this->get_stored_file('/foo/', 'foo.txt');
349 $writer->set_context($context)
350 ->export_file(['a'], $filea)
351 ->export_file(['a', 'b'], $fileb);
353 $files = $writer->get_files(['a']);
354 $this->assertCount(1, $files);
355 $this->assertEquals($filea, $files['foo/foo.txt']);
357 $files = $writer->get_files(['a', 'b']);
358 $this->assertCount(1, $files);
359 $this->assertEquals($fileb, $files['foo/foo.txt']);
363 * It should be possible to export related data in the files and children contexts.
365 public function test_export_related_data() {
366 $context = \context_system::instance();
368 $writer = $this->get_writer_instance()
369 ->set_context($context)
370 ->export_related_data(['file', 'data'], 'file', 'data1')
371 ->export_related_data([], 'file', 'data2');
373 $data = $writer->get_related_data([]);
374 $this->assertCount(1, $data);
375 $this->assertEquals('data2', $data['file']);
377 $data = $writer->get_related_data([], 'file');
378 $this->assertEquals('data2', $data);
380 $data = $writer->get_related_data(['file', 'data']);
381 $this->assertCount(1, $data);
382 $this->assertEquals('data1', $data['file']);
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']));
393 * It should be possible to export related data in the same location,but in a different context.
395 public function test_export_related_data_no_context_clash() {
396 $writer = $this->get_writer_instance();
398 $context = \context_system::instance();
399 $writer->set_context($context)
400 ->export_related_data(['file', 'data'], 'file', 'data1');
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');
407 $writer->set_context($context);
408 $data = $writer->get_related_data(['file', 'data']);
409 $this->assertCount(1, $data);
410 $this->assertEquals('data1', $data['file']);
412 $writer->set_context($usercontext);
413 $data = $writer->get_related_data(['file', 'data']);
414 $this->assertCount(1, $data);
415 $this->assertEquals('data2', $data['file']);
419 * Test export and recover with children.
421 public function test_get_related_data_with_children() {
422 $writer = $this->get_writer_instance();
423 $context = \context_system::instance();
425 $writer->set_context($context)
426 ->export_related_data(['a'], 'abc', 'ABC')
427 ->export_related_data(['a', 'b'], 'def', 'DEF');
429 $this->assertEquals('ABC', $writer->get_related_data(['a'], 'abc'));
430 $this->assertEquals('DEF', $writer->get_related_data(['a', 'b'], 'def'));
434 * It should be possible to export related files in the files and children contexts.
436 public function test_export_custom_file() {
437 $context = \context_system::instance();
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');
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);
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']));
461 * It should be possible to export related files in the same location
462 * in different contexts.
464 public function test_export_custom_file_no_context_clash() {
465 $writer = $this->get_writer_instance();
466 $context = \context_system::instance();
468 $writer->set_context($context)
469 ->export_custom_file(['file.txt'], 'file.txt', 'Content 1');
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');
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']);
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']);
488 * Test export and recover with children.
490 public function test_get_custom_file_with_children() {
491 $writer = $this->get_writer_instance();
492 $context = \context_system::instance();
494 $writer->set_context($context)
495 ->export_custom_file(['a'], 'file.txt', 'ABC')
496 ->export_custom_file(['a', 'b'], 'file.txt', 'DEF');
498 $this->assertEquals('ABC', $writer->get_custom_file(['a'], 'file.txt'));
499 $this->assertEquals('DEF', $writer->get_custom_file(['a', 'b'], 'file.txt'));
503 * Get a fresh content writer.
505 * @return moodle_content_writer
507 public function get_writer_instance() {
508 $factory = $this->createMock(writer::class);
509 return new content_writer($factory);
513 * Helper to create a stored file objectw with the given supplied content.
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
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);
525 $file = $this->getMockBuilder(stored_file::class)
526 ->onlyMethods([])
527 ->setConstructorArgs([
528 get_file_storage(),
529 (object) [
530 'contenthash' => $contenthash,
531 'filesize' => strlen($filecontent),
532 'filepath' => $filepath,
533 'filename' => $filename,
536 ->getMock();
538 return $file;