2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
19 * PHPUnit tests for conversion API.
22 * @copyright 2017 Andrew nicols <andrew@nicols.co.uk>
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') ||
die();
29 use core_files\conversion
;
32 * PHPUnit tests for conversion persistent.
35 * @copyright 2017 Andrew nicols <andrew@nicols.co.uk>
36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38 class core_files_conversion_testcase
extends advanced_testcase
{
41 * Helper to create a stored file object with the given supplied content.
43 * @param string $filecontent The content of the mocked file
44 * @param string $filename The file name to use in the stored_file
45 * @param string $filerecord Any overrides to the filerecord
48 protected function create_stored_file($filecontent = 'content', $filename = 'testfile.txt', $filerecord = []) {
49 $filerecord = array_merge([
50 'contextid' => context_system
::instance()->id
,
51 'component' => 'core',
52 'filearea' => 'unittest',
55 'filename' => $filename,
58 $fs = get_file_storage();
59 $file = $fs->create_file_from_string($filerecord, $filecontent);
65 * Ensure that get_conversions_for_file returns an existing conversion
66 * record with matching sourcefileid and targetformat.
68 public function test_get_conversions_for_file_existing_conversion_incomplete() {
69 $this->resetAfterTest();
71 $sourcefile = $this->create_stored_file();
73 $existing = new conversion(0, (object) [
74 'sourcefileid' => $sourcefile->get_id(),
75 'targetformat' => 'pdf',
79 $conversions = conversion
::get_conversions_for_file($sourcefile, 'pdf');
81 $this->assertCount(1, $conversions);
83 $conversion = array_shift($conversions);
84 $conversionfile = $conversion->get_sourcefile();
86 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id());
87 $this->assertFalse($conversion->get_destfile());
91 * Ensure that get_conversions_for_file returns an existing conversion
92 * record with matching sourcefileid and targetformat when a second
93 * conversion to a different format exists.
95 public function test_get_conversions_for_file_existing_conversion_multiple_formats_incomplete() {
96 $this->resetAfterTest();
98 $sourcefile = $this->create_stored_file();
100 $existing = new conversion(0, (object) [
101 'sourcefileid' => $sourcefile->get_id(),
102 'targetformat' => 'pdf',
106 $second = new conversion(0, (object) [
107 'sourcefileid' => $sourcefile->get_id(),
108 'targetformat' => 'doc',
112 $conversions = conversion
::get_conversions_for_file($sourcefile, 'pdf');
114 $this->assertCount(1, $conversions);
116 $conversion = array_shift($conversions);
117 $conversionfile = $conversion->get_sourcefile();
119 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id());
120 $this->assertFalse($conversion->get_destfile());
124 * Ensure that get_conversions_for_file returns an existing conversion
125 * record with matching sourcefileid and targetformat.
127 public function test_get_conversions_for_file_existing_conversion_complete() {
128 $this->resetAfterTest();
130 $sourcefile = $this->create_stored_file();
131 $destfile = $this->create_stored_file(
133 $sourcefile->get_contenthash(),
135 'component' => 'core',
136 'filearea' => 'documentconversion',
137 'filepath' => '/pdf/',
140 $existing = new conversion(0, (object) [
141 'sourcefileid' => $sourcefile->get_id(),
142 'targetformat' => 'pdf',
143 'destfileid' => $destfile->get_id(),
147 $conversions = conversion
::get_conversions_for_file($sourcefile, 'pdf');
149 // Only one file should be returned.
150 $this->assertCount(1, $conversions);
152 $conversion = array_shift($conversions);
154 $this->assertEquals($sourcefile->get_id(), $conversion->get_sourcefile()->get_id());
155 $this->assertEquals($destfile->get_id(), $conversion->get_destfile()->get_id());
159 * Ensure that get_conversions_for_file returns an existing conversion
160 * record with matching sourcefileid and targetformat.
162 public function test_get_conversions_for_file_existing_conversion_multiple_formats_complete() {
163 $this->resetAfterTest();
165 $sourcefile = $this->create_stored_file();
166 $destfile = $this->create_stored_file(
168 $sourcefile->get_contenthash(),
170 'component' => 'core',
171 'filearea' => 'documentconversion',
172 'filepath' => '/pdf/',
175 $existing = new conversion(0, (object) [
176 'sourcefileid' => $sourcefile->get_id(),
177 'targetformat' => 'pdf',
178 'destfileid' => $destfile->get_id(),
182 $second = new conversion(0, (object) [
183 'sourcefileid' => $sourcefile->get_id(),
184 'targetformat' => 'doc',
188 $conversions = conversion
::get_conversions_for_file($sourcefile, 'pdf');
190 // Only one file should be returned.
191 $this->assertCount(1, $conversions);
193 $conversion = array_shift($conversions);
195 $this->assertEquals($sourcefile->get_id(), $conversion->get_sourcefile()->get_id());
196 $this->assertEquals($destfile->get_id(), $conversion->get_destfile()->get_id());
200 * Ensure that get_conversions_for_file returns an existing conversion
201 * record does not exist, but the file has previously been converted.
203 public function test_get_conversions_for_file_existing_target() {
204 $this->resetAfterTest();
206 $sourcefile = $this->create_stored_file();
207 $destfile = $this->create_stored_file(
209 $sourcefile->get_contenthash(),
211 'component' => 'core',
212 'filearea' => 'documentconversion',
213 'filepath' => '/pdf/',
216 $conversions = conversion
::get_conversions_for_file($sourcefile, 'pdf');
218 $this->assertCount(1, $conversions);
220 $conversion = array_shift($conversions);
221 $conversionsource = $conversion->get_sourcefile();
222 $this->assertEquals($sourcefile->get_id(), $conversionsource->get_id());
223 $conversiondest = $conversion->get_destfile();
224 $this->assertEquals($destfile->get_id(), $conversiondest->get_id());
228 * Ensure that set_sourcefile sets the correct fileid.
230 public function test_set_sourcefile() {
231 $this->resetAfterTest();
233 $sourcefile = $this->create_stored_file();
234 $conversion = new conversion(0, (object) []);
236 $conversion->set_sourcefile($sourcefile);
238 $this->assertEquals($sourcefile->get_id(), $conversion->get('sourcefileid'));
239 $this->assertNull($conversion->get('destfileid'));
243 * Ensure that store_destfile_from_path stores the file as expected.
245 public function test_store_destfile_from_path() {
246 $this->resetAfterTest();
248 $sourcefile = $this->create_stored_file();
249 $conversion = new conversion(0, (object) [
250 'sourcefileid' => $sourcefile->get_id(),
251 'targetformat' => 'pdf',
255 $conversion->store_destfile_from_path($fixture);
257 $destfile = $conversion->get_destfile();
258 $this->assertEquals(file_get_contents($fixture), $destfile->get_content());
262 * Ensure that store_destfile_from_path stores the file as expected.
264 public function test_store_destfile_from_path_delete_existing() {
265 $this->resetAfterTest();
267 $sourcefile = $this->create_stored_file();
268 $conversion = new conversion(0, (object) [
269 'sourcefileid' => $sourcefile->get_id(),
270 'targetformat' => 'pdf',
274 'contextid' => \context_system
::instance()->id
,
275 'component' => 'core',
276 'filearea' => 'documentconversion',
278 'filepath' => '/pdf/',
280 $existingfile = $this->create_stored_file('foo', $sourcefile->get_contenthash(), $record);
283 $conversion->store_destfile_from_path($fixture);
285 $destfile = $conversion->get_destfile();
286 $this->assertEquals(file_get_contents($fixture), $destfile->get_content());
290 * Ensure that store_destfile_from_path stores the file as expected.
292 public function test_store_destfile_from_string() {
293 $this->resetAfterTest();
295 $sourcefile = $this->create_stored_file();
296 $conversion = new conversion(0, (object) [
297 'sourcefileid' => $sourcefile->get_id(),
298 'targetformat' => 'pdf',
301 $fixture = 'Example content';
302 $conversion->store_destfile_from_string($fixture);
304 $destfile = $conversion->get_destfile();
305 $this->assertEquals($fixture, $destfile->get_content());
309 * Ensure that store_destfile_from_string stores the file as expected when
310 * an existing destfile is found.
312 public function test_store_destfile_from_string_delete_existing() {
313 $this->resetAfterTest();
315 $sourcefile = $this->create_stored_file();
316 $conversion = new conversion(0, (object) [
317 'sourcefileid' => $sourcefile->get_id(),
318 'targetformat' => 'pdf',
322 'contextid' => \context_system
::instance()->id
,
323 'component' => 'core',
324 'filearea' => 'documentconversion',
326 'filepath' => '/pdf/',
328 $existingfile = $this->create_stored_file('foo', $sourcefile->get_contenthash(), $record);
330 $fixture = 'Example content';
331 $conversion->store_destfile_from_string($fixture);
333 $destfile = $conversion->get_destfile();
334 $this->assertEquals($fixture, $destfile->get_content());
338 * Ensure that the get_status functions cast the status to integer correctly.
340 public function test_get_status() {
341 $conversion = new conversion(0, (object) [
342 'status' => (string) 1,
345 $this->assertIsInt($conversion->get('status'));
349 * Ensure that get_converter_instance returns false when no converter is set.
351 public function test_get_converter_instance_none_set() {
352 $conversion = new conversion(0, (object) []);
353 $this->assertFalse($conversion->get_converter_instance());
357 * Ensure that get_converter_instance returns false when no valid converter is set.
359 public function test_get_converter_instance_invalid_set() {
360 $conversion = new conversion(0, (object) [
361 'converter' => '\\fileconverter_not_a_valid_converter\\converter',
363 $this->assertFalse($conversion->get_converter_instance());
367 * Ensure that get_converter_instance returns an instance when a valid converter is set.
369 public function test_get_converter_instance_valid_set() {
370 $conversion = new conversion(0, (object) [
371 'converter' => \fileconverter_unoconv\converter
::class,
373 $this->assertInstanceOf(\fileconverter_unoconv\converter
::class, $conversion->get_converter_instance());
377 * Test that all old conversion records are removed periodically.
379 public function test_remove_old_conversion_records_old() {
380 $this->resetAfterTest();
383 $sourcefile = $this->create_stored_file();
384 $conversion = new conversion(0, (object) [
385 'sourcefileid' => $sourcefile->get_id(),
386 'targetformat' => 'pdf',
388 $conversion->create();
389 $DB->set_field(conversion
::TABLE
, 'timemodified', time() - YEARSECS
);
391 conversion
::remove_old_conversion_records();
393 $this->assertEquals(0, $DB->count_records(conversion
::TABLE
));
397 * Test that all old conversion records are removed periodically.
399 public function test_remove_old_conversion_records_young() {
400 $this->resetAfterTest();
403 $sourcefile = $this->create_stored_file();
404 $conversion = new conversion(0, (object) [
405 'sourcefileid' => $sourcefile->get_id(),
406 'targetformat' => 'pdf',
408 $conversion->create();
409 $DB->set_field(conversion
::TABLE
, 'timemodified', time() - DAYSECS
);
411 conversion
::remove_old_conversion_records();
413 $this->assertEquals(1, $DB->count_records(conversion
::TABLE
));
417 * Test orphan records are removed.
419 public function test_remove_orphan_records() {
421 $this->resetAfterTest();
423 $sf1 = $this->create_stored_file('1', '1');
424 $sf2 = $this->create_stored_file('2', '2');
425 $sf3 = $this->create_stored_file('3', '3');
426 $c1 = new conversion(0, (object) ['sourcefileid' => $sf1->get_id(), 'targetformat' => 'pdf']);
428 $c2 = new conversion(0, (object) ['sourcefileid' => $sf2->get_id(), 'targetformat' => 'pdf']);
430 $c3 = new conversion(0, (object) ['sourcefileid' => $sf3->get_id(), 'targetformat' => 'pdf']);
433 $this->assertTrue(conversion
::record_exists($c1->get('id')));
434 $this->assertTrue(conversion
::record_exists($c2->get('id')));
435 $this->assertTrue(conversion
::record_exists($c3->get('id')));
437 // Nothing should happen here.
438 conversion
::remove_orphan_records();
439 $this->assertTrue(conversion
::record_exists($c1->get('id')));
440 $this->assertTrue(conversion
::record_exists($c2->get('id')));
441 $this->assertTrue(conversion
::record_exists($c3->get('id')));
445 conversion
::remove_orphan_records();
446 $this->assertTrue(conversion
::record_exists($c1->get('id')));
447 $this->assertFalse(conversion
::record_exists($c2->get('id')));
448 $this->assertTrue(conversion
::record_exists($c3->get('id')));
450 // Delete file #1, #3.
453 conversion
::remove_orphan_records();
454 $this->assertFalse(conversion
::record_exists($c1->get('id')));
455 $this->assertFalse(conversion
::record_exists($c2->get('id')));
456 $this->assertFalse(conversion
::record_exists($c3->get('id')));