Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
     */
11 efrain 44
    public function test_export_data(): void {
1 efrain 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
     */
11 efrain 69
    public function test_export_data_no_context_clash(): void {
1 efrain 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
     */
11 efrain 102
    public function test_get_data_with_children(): void {
1 efrain 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
     */
11 efrain 118
    public function test_export_metadata(): void {
1 efrain 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
     */
11 efrain 152
    public function test_export_metadata_no_context_clash(): void {
1 efrain 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
     */
11 efrain 195
    public function test_export_user_preference(): void {
1 efrain 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
     */
11 efrain 235
    public function test_export_user_preference_no_context_clash(): void {
1 efrain 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
     */
11 efrain 275
    public function test_get_metadata_with_children(): void {
1 efrain 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
     */
11 efrain 290
    public function test_export_file_special_folders(): void {
1 efrain 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
     */
11 efrain 312
    public function test_export_file_no_context_clash(): void {
1 efrain 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
     */
11 efrain 342
    public function test_get_file_with_children(): void {
1 efrain 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
     */
11 efrain 365
    public function test_export_related_data(): void {
1 efrain 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
     */
11 efrain 395
    public function test_export_related_data_no_context_clash(): void {
1 efrain 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
     */
11 efrain 421
    public function test_get_related_data_with_children(): void {
1 efrain 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
     */
11 efrain 436
    public function test_export_custom_file(): void {
1 efrain 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
     */
11 efrain 464
    public function test_export_custom_file_no_context_clash(): void {
1 efrain 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
     */
11 efrain 490
    public function test_get_custom_file_with_children(): void {
1 efrain 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
            ->onlyMethods([])
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
}