mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
81407f18ec
The current ->setMethods() has been silently (won't emit any warning) in PHPUnit 9. And will stop working (current plans) in PHPUnit 10. Basically the now deprecated method has been split into: - onlyMethods(): To point to existing methods in the mocked artifact. - addMethods(): To point to non existing (yet) methods in the mocked artifact. In practice that means that all our current setMethods() calls can be converted to onlyMethods() (existing) and done. The addMethods() is mostly useful on development phases, not final testing. Finally note that <null> isn't accepted anymore as parameter to double all the methods. Instead empty array [] must be used. Link: https://github.com/sebastianbergmann/phpunit/issues/3770
541 lines
21 KiB
PHP
541 lines
21 KiB
PHP
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* Unit Tests for the Content Writer used for unit testing.
|
|
*
|
|
* @package core_privacy
|
|
* @category test
|
|
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
global $CFG;
|
|
|
|
use \core_privacy\local\request\writer;
|
|
use \core_privacy\tests\request\content_writer;
|
|
|
|
/**
|
|
* Unit Tests for the Content Writer used for unit testing.
|
|
*
|
|
* @copyright 2018 Andrew Nicols <andrew@nicols.co.uk>
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
class tests_content_writer_test extends advanced_testcase {
|
|
|
|
/**
|
|
* It should be possible to store and retrieve data.
|
|
*/
|
|
public function test_export_data() {
|
|
$context = \context_system::instance();
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$dataa = (object) [
|
|
'example' => 'a',
|
|
];
|
|
$datab = (object) [
|
|
'example' => 'b',
|
|
];
|
|
|
|
$writer->set_context($context)
|
|
->export_data(['data'], $dataa)
|
|
->export_data([], $datab);
|
|
|
|
$data = $writer->get_data([]);
|
|
$this->assertSame($datab, $data);
|
|
|
|
$data = $writer->get_data(['data']);
|
|
$this->assertSame($dataa, $data);
|
|
}
|
|
|
|
/**
|
|
* It should be possible to store and retrieve data at the same point in different contexts.
|
|
*/
|
|
public function test_export_data_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$context = \context_system::instance();
|
|
$dataa = (object) [
|
|
'example' => 'a',
|
|
];
|
|
$writer->set_context($context)
|
|
->export_data(['data'], $dataa);
|
|
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$datab = (object) [
|
|
'example' => 'b',
|
|
];
|
|
$writer->set_context($usercontext)
|
|
->export_data(['data'], $datab);
|
|
|
|
$writer->set_context($context);
|
|
$data = $writer->get_data(['data']);
|
|
$this->assertSame($dataa, $data);
|
|
$this->assertTrue($writer->has_any_data());
|
|
$this->assertTrue($writer->has_any_data(['data']));
|
|
$this->assertFalse($writer->has_any_data(['somepath']));
|
|
|
|
$writer->set_context($usercontext);
|
|
$data = $writer->get_data(['data']);
|
|
$this->assertSame($datab, $data);
|
|
}
|
|
|
|
/**
|
|
* Test export and recover with children.
|
|
*/
|
|
public function test_get_data_with_children() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_data(['a'], (object) ['parent' => true])
|
|
->export_data(['a', 'b'], (object) ['parent' => false]);
|
|
|
|
$this->assertTrue($writer->get_data(['a'])->parent);
|
|
$this->assertFalse($writer->get_data(['a', 'b'])->parent);
|
|
$this->assertEquals([], $writer->get_data(['a', 'b', 'c']));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to store and retrieve metadata.
|
|
*/
|
|
public function test_export_metadata() {
|
|
$context = \context_system::instance();
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_metadata(['metadata'], 'somekey', 'value1', 'description1')
|
|
->export_metadata([], 'somekey', 'value2', 'description2');
|
|
|
|
$allmetadata = $writer->get_all_metadata([]);
|
|
$this->assertCount(1, $allmetadata);
|
|
$this->assertArrayHasKey('somekey', $allmetadata);
|
|
$this->assertEquals('value2', $allmetadata['somekey']->value);
|
|
$this->assertEquals('description2', $allmetadata['somekey']->description);
|
|
|
|
$metadata = $writer->get_metadata([], 'somekey', false);
|
|
$this->assertEquals('value2', $metadata->value);
|
|
$this->assertEquals('description2', $metadata->description);
|
|
$this->assertEquals('value2', $writer->get_metadata([], 'somekey', true));
|
|
|
|
$allmetadata = $writer->get_all_metadata(['metadata']);
|
|
$this->assertCount(1, $allmetadata);
|
|
$this->assertArrayHasKey('somekey', $allmetadata);
|
|
$this->assertEquals('value1', $allmetadata['somekey']->value);
|
|
$this->assertEquals('description1', $allmetadata['somekey']->description);
|
|
|
|
$metadata = $writer->get_metadata(['metadata'], 'somekey', false);
|
|
$this->assertEquals('value1', $metadata->value);
|
|
$this->assertEquals('description1', $metadata->description);
|
|
$this->assertEquals('value1', $writer->get_metadata(['metadata'], 'somekey', true));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to store and retrieve metadata at the same point in different contexts.
|
|
*/
|
|
public function test_export_metadata_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$context = \context_system::instance();
|
|
$writer->set_context($context)
|
|
->export_metadata(['metadata'], 'somekey', 'value1', 'description1');
|
|
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$writer->set_context($usercontext)
|
|
->export_metadata(['metadata'], 'somekey', 'value2', 'description2');
|
|
|
|
$writer->set_context($context);
|
|
$allmetadata = $writer->get_all_metadata(['metadata']);
|
|
$this->assertCount(1, $allmetadata);
|
|
$this->assertArrayHasKey('somekey', $allmetadata);
|
|
$this->assertEquals('value1', $allmetadata['somekey']->value);
|
|
$this->assertEquals('description1', $allmetadata['somekey']->description);
|
|
|
|
$metadata = $writer->get_metadata(['metadata'], 'somekey', false);
|
|
$this->assertEquals('value1', $metadata->value);
|
|
$this->assertEquals('description1', $metadata->description);
|
|
$this->assertEquals('value1', $writer->get_metadata(['metadata'], 'somekey', true));
|
|
|
|
$writer->set_context($usercontext);
|
|
$allmetadata = $writer->get_all_metadata(['metadata']);
|
|
$this->assertCount(1, $allmetadata);
|
|
$this->assertArrayHasKey('somekey', $allmetadata);
|
|
$this->assertEquals('value2', $allmetadata['somekey']->value);
|
|
$this->assertEquals('description2', $allmetadata['somekey']->description);
|
|
|
|
$metadata = $writer->get_metadata(['metadata'], 'somekey', false);
|
|
$this->assertEquals('value2', $metadata->value);
|
|
$this->assertEquals('description2', $metadata->description);
|
|
$this->assertEquals('value2', $writer->get_metadata(['metadata'], 'somekey', true));
|
|
$this->assertTrue($writer->has_any_data());
|
|
$this->assertTrue($writer->has_any_data(['metadata']));
|
|
$this->assertFalse($writer->has_any_data(['somepath']));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to store and retrieve user preferences.
|
|
*/
|
|
public function test_export_user_preference() {
|
|
$context = \context_system::instance();
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_user_preference('core_privacy', 'somekey', 'value0', 'description0');
|
|
$writer->set_context($usercontext)
|
|
->export_user_preference('core_tests', 'somekey', 'value1', 'description1')
|
|
->export_user_preference('core_privacy', 'somekey', 'value2', 'description2')
|
|
->export_user_preference('core_tests', 'someotherkey', 'value2', 'description2');
|
|
|
|
$writer->set_context($usercontext);
|
|
|
|
$someprefs = $writer->get_user_preferences('core_privacy');
|
|
$this->assertCount(1, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value0', $someprefs->somekey->value);
|
|
$this->assertEquals('description0', $someprefs->somekey->description);
|
|
|
|
$someprefs = $writer->get_user_context_preferences('core_tests');
|
|
$this->assertCount(2, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value1', $someprefs->somekey->value);
|
|
$this->assertEquals('description1', $someprefs->somekey->description);
|
|
$this->assertTrue(isset($someprefs->someotherkey));
|
|
$this->assertEquals('value2', $someprefs->someotherkey->value);
|
|
$this->assertEquals('description2', $someprefs->someotherkey->description);
|
|
|
|
$someprefs = $writer->get_user_context_preferences('core_privacy');
|
|
$this->assertCount(1, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value2', $someprefs->somekey->value);
|
|
$this->assertEquals('description2', $someprefs->somekey->description);
|
|
}
|
|
|
|
/**
|
|
* It should be possible to store and retrieve user preferences at the same point in different contexts.
|
|
*/
|
|
public function test_export_user_preference_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
$coursecontext = \context_course::instance(SITEID);
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
|
|
$writer->set_context($context)
|
|
->export_user_preference('core_tests', 'somekey', 'value0', 'description0');
|
|
$writer->set_context($coursecontext)
|
|
->export_user_preference('core_tests', 'somekey', 'value1', 'description1');
|
|
$writer->set_context($usercontext)
|
|
->export_user_preference('core_tests', 'somekey', 'value2', 'description2');
|
|
|
|
// Set the course context and fetch with get_user_preferences to get the global preference.
|
|
$writer->set_context($coursecontext);
|
|
$someprefs = $writer->get_user_preferences('core_tests');
|
|
$this->assertCount(1, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value0', $someprefs->somekey->value);
|
|
$this->assertEquals('description0', $someprefs->somekey->description);
|
|
|
|
// Set the course context and fetch with get_user_context_preferences.
|
|
$someprefs = $writer->get_user_context_preferences('core_tests');
|
|
$this->assertCount(1, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value1', $someprefs->somekey->value);
|
|
$this->assertEquals('description1', $someprefs->somekey->description);
|
|
|
|
$writer->set_context($usercontext);
|
|
$someprefs = $writer->get_user_context_preferences('core_tests');
|
|
$this->assertCount(1, (array) $someprefs);
|
|
$this->assertTrue(isset($someprefs->somekey));
|
|
$this->assertEquals('value2', $someprefs->somekey->value);
|
|
$this->assertEquals('description2', $someprefs->somekey->description);
|
|
}
|
|
|
|
/**
|
|
* Test export and recover with children.
|
|
*/
|
|
public function test_get_metadata_with_children() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_metadata(['a'], 'abc', 'ABC', 'A, B, C')
|
|
->export_metadata(['a', 'b'], 'def', 'DEF', 'D, E, F');
|
|
|
|
$this->assertEquals('ABC', $writer->get_metadata(['a'], 'abc'));
|
|
$this->assertEquals('DEF', $writer->get_metadata(['a', 'b'], 'def'));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export files in the files and children contexts.
|
|
*/
|
|
public function test_export_file_special_folders() {
|
|
$context = \context_system::instance();
|
|
|
|
$filea = $this->get_stored_file('/', 'files');
|
|
$fileb = $this->get_stored_file('/children/', 'foo.zip');
|
|
|
|
$writer = $this->get_writer_instance()
|
|
->set_context($context)
|
|
->export_file([], $filea)
|
|
->export_file([], $fileb);
|
|
|
|
$files = $writer->get_files([]);
|
|
|
|
$this->assertCount(2, $files);
|
|
$this->assertEquals($filea, $files['files']);
|
|
$this->assertEquals($fileb, $files['children/foo.zip']);
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export mutliple files in the same subcontext/path space but different context and not
|
|
* have them clash.
|
|
*/
|
|
public function test_export_file_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
$filea = $this->get_stored_file('/foo/', 'foo.txt');
|
|
$writer = $this->get_writer_instance()
|
|
->set_context($context)
|
|
->export_file([], $filea);
|
|
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$fileb = $this->get_stored_file('/foo/', 'foo.txt');
|
|
$writer->set_context($usercontext)
|
|
->export_file([], $fileb);
|
|
|
|
$writer->set_context($context);
|
|
$files = $writer->get_files([]);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals($filea, $files['foo/foo.txt']);
|
|
|
|
$writer->set_context($usercontext);
|
|
$files = $writer->get_files([]);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals($fileb, $files['foo/foo.txt']);
|
|
$this->assertTrue($writer->has_any_data());
|
|
$this->assertFalse($writer->has_any_data(['somepath']));
|
|
}
|
|
|
|
/**
|
|
* Test export and recover with children.
|
|
*/
|
|
public function test_get_file_with_children() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$filea = $this->get_stored_file('/foo/', 'foo.txt');
|
|
$fileb = $this->get_stored_file('/foo/', 'foo.txt');
|
|
|
|
$writer->set_context($context)
|
|
->export_file(['a'], $filea)
|
|
->export_file(['a', 'b'], $fileb);
|
|
|
|
$files = $writer->get_files(['a']);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals($filea, $files['foo/foo.txt']);
|
|
|
|
$files = $writer->get_files(['a', 'b']);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals($fileb, $files['foo/foo.txt']);
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export related data in the files and children contexts.
|
|
*/
|
|
public function test_export_related_data() {
|
|
$context = \context_system::instance();
|
|
|
|
$writer = $this->get_writer_instance()
|
|
->set_context($context)
|
|
->export_related_data(['file', 'data'], 'file', 'data1')
|
|
->export_related_data([], 'file', 'data2');
|
|
|
|
$data = $writer->get_related_data([]);
|
|
$this->assertCount(1, $data);
|
|
$this->assertEquals('data2', $data['file']);
|
|
|
|
$data = $writer->get_related_data([], 'file');
|
|
$this->assertEquals('data2', $data);
|
|
|
|
$data = $writer->get_related_data(['file', 'data']);
|
|
$this->assertCount(1, $data);
|
|
$this->assertEquals('data1', $data['file']);
|
|
|
|
$data = $writer->get_related_data(['file', 'data'], 'file');
|
|
$this->assertEquals('data1', $data);
|
|
$this->assertTrue($writer->has_any_data());
|
|
$this->assertTrue($writer->has_any_data(['file']));
|
|
$this->assertTrue($writer->has_any_data(['file', 'data']));
|
|
$this->assertFalse($writer->has_any_data(['somepath']));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export related data in the same location,but in a different context.
|
|
*/
|
|
public function test_export_related_data_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
|
|
$context = \context_system::instance();
|
|
$writer->set_context($context)
|
|
->export_related_data(['file', 'data'], 'file', 'data1');
|
|
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$writer->set_context($usercontext)
|
|
->export_related_data(['file', 'data'], 'file', 'data2');
|
|
|
|
$writer->set_context($context);
|
|
$data = $writer->get_related_data(['file', 'data']);
|
|
$this->assertCount(1, $data);
|
|
$this->assertEquals('data1', $data['file']);
|
|
|
|
$writer->set_context($usercontext);
|
|
$data = $writer->get_related_data(['file', 'data']);
|
|
$this->assertCount(1, $data);
|
|
$this->assertEquals('data2', $data['file']);
|
|
}
|
|
|
|
/**
|
|
* Test export and recover with children.
|
|
*/
|
|
public function test_get_related_data_with_children() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_related_data(['a'], 'abc', 'ABC')
|
|
->export_related_data(['a', 'b'], 'def', 'DEF');
|
|
|
|
$this->assertEquals('ABC', $writer->get_related_data(['a'], 'abc'));
|
|
$this->assertEquals('DEF', $writer->get_related_data(['a', 'b'], 'def'));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export related files in the files and children contexts.
|
|
*/
|
|
public function test_export_custom_file() {
|
|
$context = \context_system::instance();
|
|
|
|
$writer = $this->get_writer_instance()
|
|
->set_context($context)
|
|
->export_custom_file(['file.txt'], 'file.txt', 'Content 1')
|
|
->export_custom_file([], 'file.txt', 'Content 2');
|
|
|
|
$files = $writer->get_custom_file([]);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals('Content 2', $files['file.txt']);
|
|
$file = $writer->get_custom_file([], 'file.txt');
|
|
$this->assertEquals('Content 2', $file);
|
|
|
|
$files = $writer->get_custom_file(['file.txt']);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals('Content 1', $files['file.txt']);
|
|
$file = $writer->get_custom_file(['file.txt'], 'file.txt');
|
|
$this->assertEquals('Content 1', $file);
|
|
$this->assertTrue($writer->has_any_data());
|
|
$this->assertTrue($writer->has_any_data(['file.txt']));
|
|
$this->assertFalse($writer->has_any_data(['somepath']));
|
|
}
|
|
|
|
/**
|
|
* It should be possible to export related files in the same location
|
|
* in different contexts.
|
|
*/
|
|
public function test_export_custom_file_no_context_clash() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_custom_file(['file.txt'], 'file.txt', 'Content 1');
|
|
|
|
$adminuser = \core_user::get_user_by_username('admin');
|
|
$usercontext = \context_user::instance($adminuser->id);
|
|
$writer->set_context($usercontext)
|
|
->export_custom_file(['file.txt'], 'file.txt', 'Content 2');
|
|
|
|
$writer->set_context($context);
|
|
$files = $writer->get_custom_file(['file.txt']);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals('Content 1', $files['file.txt']);
|
|
|
|
$writer->set_context($usercontext);
|
|
$files = $writer->get_custom_file(['file.txt']);
|
|
$this->assertCount(1, $files);
|
|
$this->assertEquals('Content 2', $files['file.txt']);
|
|
}
|
|
|
|
/**
|
|
* Test export and recover with children.
|
|
*/
|
|
public function test_get_custom_file_with_children() {
|
|
$writer = $this->get_writer_instance();
|
|
$context = \context_system::instance();
|
|
|
|
$writer->set_context($context)
|
|
->export_custom_file(['a'], 'file.txt', 'ABC')
|
|
->export_custom_file(['a', 'b'], 'file.txt', 'DEF');
|
|
|
|
$this->assertEquals('ABC', $writer->get_custom_file(['a'], 'file.txt'));
|
|
$this->assertEquals('DEF', $writer->get_custom_file(['a', 'b'], 'file.txt'));
|
|
}
|
|
|
|
/**
|
|
* Get a fresh content writer.
|
|
*
|
|
* @return moodle_content_writer
|
|
*/
|
|
public function get_writer_instance() {
|
|
$factory = $this->createMock(writer::class);
|
|
return new content_writer($factory);
|
|
}
|
|
|
|
/**
|
|
* Helper to create a stored file objectw with the given supplied content.
|
|
*
|
|
* @param string $filepath The file path to use in the stored_file
|
|
* @param string $filename The file name to use in the stored_file
|
|
* @return stored_file
|
|
*/
|
|
protected function get_stored_file($filepath, $filename) {
|
|
static $counter = 0;
|
|
$counter++;
|
|
$filecontent = "Example content {$counter}";
|
|
$contenthash = file_storage::hash_from_string($filecontent);
|
|
|
|
$file = $this->getMockBuilder(stored_file::class)
|
|
->onlyMethods([])
|
|
->setConstructorArgs([
|
|
get_file_storage(),
|
|
(object) [
|
|
'contenthash' => $contenthash,
|
|
'filesize' => strlen($filecontent),
|
|
'filepath' => $filepath,
|
|
'filename' => $filename,
|
|
]
|
|
])
|
|
->getMock();
|
|
|
|
return $file;
|
|
}
|
|
}
|