See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401] [Versions 401 and 402] [Versions 401 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 namespace core_files; 18 19 /** 20 * PHPUnit tests for conversion persistent. 21 * 22 * @package core_files 23 * @copyright 2017 Andrew nicols <andrew@nicols.co.uk> 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 class conversion_test extends \advanced_testcase { 27 28 /** 29 * Helper to create a stored file object with the given supplied content. 30 * 31 * @param string $filecontent The content of the mocked file 32 * @param string $filename The file name to use in the stored_file 33 * @param string $filerecord Any overrides to the filerecord 34 * @return stored_file 35 */ 36 protected function create_stored_file($filecontent = 'content', $filename = 'testfile.txt', $filerecord = []) { 37 $filerecord = array_merge([ 38 'contextid' => \context_system::instance()->id, 39 'component' => 'core', 40 'filearea' => 'unittest', 41 'itemid' => 0, 42 'filepath' => '/', 43 'filename' => $filename, 44 ], $filerecord); 45 46 $fs = get_file_storage(); 47 $file = $fs->create_file_from_string($filerecord, $filecontent); 48 49 return $file; 50 } 51 52 /** 53 * Ensure that get_conversions_for_file returns an existing conversion 54 * record with matching sourcefileid and targetformat. 55 */ 56 public function test_get_conversions_for_file_existing_conversion_incomplete() { 57 $this->resetAfterTest(); 58 59 $sourcefile = $this->create_stored_file(); 60 61 $existing = new conversion(0, (object) [ 62 'sourcefileid' => $sourcefile->get_id(), 63 'targetformat' => 'pdf', 64 ]); 65 $existing->create(); 66 67 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 68 69 $this->assertCount(1, $conversions); 70 71 $conversion = array_shift($conversions); 72 $conversionfile = $conversion->get_sourcefile(); 73 74 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id()); 75 $this->assertFalse($conversion->get_destfile()); 76 } 77 78 /** 79 * Ensure that get_conversions_for_file returns an existing conversion 80 * record with matching sourcefileid and targetformat when a file with the same 81 * contenthash is uploaded several times. 82 * 83 * @covers \core_files\conversion::get_conversions_for_file 84 */ 85 public function test_get_conversions_for_multiple_files_existing_conversion_incomplete() { 86 $this->resetAfterTest(); 87 88 // Create a bunch of files with the same content. 89 for ($i = 0; $i < 5; $i++) { 90 $sourcefiles[] = $this->create_stored_file('test content', 'testfile' . $i . '.txt'); 91 } 92 93 // Use only one file for the conversion. 94 // Pick some file in the middle. 95 $sourcefile = $sourcefiles[count($sourcefiles) - 2]; 96 97 $existing = new conversion(0, (object) [ 98 'sourcefileid' => $sourcefile->get_id(), 99 'targetformat' => 'pdf', 100 ]); 101 $existing->create(); 102 103 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 104 $this->assertCount(1, $conversions); 105 106 $conversion = array_shift($conversions); 107 $conversionfile = $conversion->get_sourcefile(); 108 109 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id()); 110 $this->assertFalse($conversion->get_destfile()); 111 112 // Check that getting the conversion for a different file record with the same contenthash 113 // returns the same conversion as above. 114 $conversions = conversion::get_conversions_for_file($sourcefiles[count($sourcefiles) - 1], 'pdf'); 115 $this->assertCount(1, $conversions); 116 117 $conversion = array_shift($conversions); 118 $conversionfile = $conversion->get_sourcefile(); 119 120 $this->assertEquals($existing->get('id'), $conversion->get('id')); 121 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id()); 122 $this->assertFalse($conversion->get_destfile()); 123 } 124 125 /** 126 * Ensure that get_conversions_for_file returns an existing conversion 127 * record with matching sourcefileid and targetformat when a second 128 * conversion to a different format exists. 129 */ 130 public function test_get_conversions_for_file_existing_conversion_multiple_formats_incomplete() { 131 $this->resetAfterTest(); 132 133 $sourcefile = $this->create_stored_file(); 134 135 $existing = new conversion(0, (object) [ 136 'sourcefileid' => $sourcefile->get_id(), 137 'targetformat' => 'pdf', 138 ]); 139 $existing->create(); 140 141 $second = new conversion(0, (object) [ 142 'sourcefileid' => $sourcefile->get_id(), 143 'targetformat' => 'doc', 144 ]); 145 $second->create(); 146 147 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 148 149 $this->assertCount(1, $conversions); 150 151 $conversion = array_shift($conversions); 152 $conversionfile = $conversion->get_sourcefile(); 153 154 $this->assertEquals($sourcefile->get_id(), $conversionfile->get_id()); 155 $this->assertFalse($conversion->get_destfile()); 156 } 157 158 /** 159 * Ensure that get_conversions_for_file returns an existing conversion 160 * record with matching sourcefileid and targetformat. 161 */ 162 public function test_get_conversions_for_file_existing_conversion_complete() { 163 $this->resetAfterTest(); 164 165 $sourcefile = $this->create_stored_file(); 166 $destfile = $this->create_stored_file( 167 'example content', 168 $sourcefile->get_contenthash(), 169 [ 170 'component' => 'core', 171 'filearea' => 'documentconversion', 172 'filepath' => '/pdf/', 173 ]); 174 175 $existing = new conversion(0, (object) [ 176 'sourcefileid' => $sourcefile->get_id(), 177 'targetformat' => 'pdf', 178 'destfileid' => $destfile->get_id(), 179 ]); 180 $existing->create(); 181 182 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 183 184 // Only one file should be returned. 185 $this->assertCount(1, $conversions); 186 187 $conversion = array_shift($conversions); 188 189 $this->assertEquals($existing->get('id'), $conversion->get('id')); 190 $this->assertEquals($sourcefile->get_id(), $conversion->get_sourcefile()->get_id()); 191 $this->assertEquals($destfile->get_id(), $conversion->get_destfile()->get_id()); 192 } 193 194 /** 195 * Ensure that get_conversions_for_file returns an existing conversion 196 * record with matching sourcefileid and targetformat. 197 */ 198 public function test_get_conversions_for_file_existing_conversion_multiple_formats_complete() { 199 $this->resetAfterTest(); 200 201 $sourcefile = $this->create_stored_file(); 202 $destfile = $this->create_stored_file( 203 'example content', 204 $sourcefile->get_contenthash(), 205 [ 206 'component' => 'core', 207 'filearea' => 'documentconversion', 208 'filepath' => '/pdf/', 209 ]); 210 211 $existing = new conversion(0, (object) [ 212 'sourcefileid' => $sourcefile->get_id(), 213 'targetformat' => 'pdf', 214 'destfileid' => $destfile->get_id(), 215 ]); 216 $existing->create(); 217 218 $second = new conversion(0, (object) [ 219 'sourcefileid' => $sourcefile->get_id(), 220 'targetformat' => 'doc', 221 ]); 222 $second->create(); 223 224 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 225 226 // Only one file should be returned. 227 $this->assertCount(1, $conversions); 228 229 $conversion = array_shift($conversions); 230 231 $this->assertEquals($sourcefile->get_id(), $conversion->get_sourcefile()->get_id()); 232 $this->assertEquals($destfile->get_id(), $conversion->get_destfile()->get_id()); 233 } 234 235 /** 236 * Ensure that get_conversions_for_file returns an existing conversion 237 * record does not exist, but the file has previously been converted. 238 */ 239 public function test_get_conversions_for_file_existing_target() { 240 $this->resetAfterTest(); 241 242 $sourcefile = $this->create_stored_file(); 243 $destfile = $this->create_stored_file( 244 'example content', 245 $sourcefile->get_contenthash(), 246 [ 247 'component' => 'core', 248 'filearea' => 'documentconversion', 249 'filepath' => '/pdf/', 250 ]); 251 252 $conversions = conversion::get_conversions_for_file($sourcefile, 'pdf'); 253 254 $this->assertCount(1, $conversions); 255 256 $conversion = array_shift($conversions); 257 $conversionsource = $conversion->get_sourcefile(); 258 $this->assertEquals($sourcefile->get_id(), $conversionsource->get_id()); 259 $conversiondest = $conversion->get_destfile(); 260 $this->assertEquals($destfile->get_id(), $conversiondest->get_id()); 261 } 262 263 /** 264 * Ensure that set_sourcefile sets the correct fileid. 265 */ 266 public function test_set_sourcefile() { 267 $this->resetAfterTest(); 268 269 $sourcefile = $this->create_stored_file(); 270 $conversion = new conversion(0, (object) []); 271 272 $conversion->set_sourcefile($sourcefile); 273 274 $this->assertEquals($sourcefile->get_id(), $conversion->get('sourcefileid')); 275 $this->assertNull($conversion->get('destfileid')); 276 } 277 278 /** 279 * Ensure that store_destfile_from_path stores the file as expected. 280 */ 281 public function test_store_destfile_from_path() { 282 $this->resetAfterTest(); 283 284 $sourcefile = $this->create_stored_file(); 285 $conversion = new conversion(0, (object) [ 286 'sourcefileid' => $sourcefile->get_id(), 287 'targetformat' => 'pdf', 288 ]); 289 290 $fixture = __FILE__; 291 $conversion->store_destfile_from_path($fixture); 292 293 $destfile = $conversion->get_destfile(); 294 $this->assertEquals(file_get_contents($fixture), $destfile->get_content()); 295 } 296 297 /** 298 * Ensure that store_destfile_from_path stores the file as expected. 299 */ 300 public function test_store_destfile_from_path_delete_existing() { 301 $this->resetAfterTest(); 302 303 $sourcefile = $this->create_stored_file(); 304 $conversion = new conversion(0, (object) [ 305 'sourcefileid' => $sourcefile->get_id(), 306 'targetformat' => 'pdf', 307 ]); 308 309 $record = [ 310 'contextid' => \context_system::instance()->id, 311 'component' => 'core', 312 'filearea' => 'documentconversion', 313 'itemid' => 0, 314 'filepath' => '/pdf/', 315 ]; 316 $existingfile = $this->create_stored_file('foo', $sourcefile->get_contenthash(), $record); 317 318 $fixture = __FILE__; 319 $conversion->store_destfile_from_path($fixture); 320 321 $destfile = $conversion->get_destfile(); 322 $this->assertEquals(file_get_contents($fixture), $destfile->get_content()); 323 } 324 325 /** 326 * Ensure that store_destfile_from_path stores the file as expected. 327 */ 328 public function test_store_destfile_from_string() { 329 $this->resetAfterTest(); 330 331 $sourcefile = $this->create_stored_file(); 332 $conversion = new conversion(0, (object) [ 333 'sourcefileid' => $sourcefile->get_id(), 334 'targetformat' => 'pdf', 335 ]); 336 337 $fixture = 'Example content'; 338 $conversion->store_destfile_from_string($fixture); 339 340 $destfile = $conversion->get_destfile(); 341 $this->assertEquals($fixture, $destfile->get_content()); 342 } 343 344 /** 345 * Ensure that store_destfile_from_string stores the file as expected when 346 * an existing destfile is found. 347 */ 348 public function test_store_destfile_from_string_delete_existing() { 349 $this->resetAfterTest(); 350 351 $sourcefile = $this->create_stored_file(); 352 $conversion = new conversion(0, (object) [ 353 'sourcefileid' => $sourcefile->get_id(), 354 'targetformat' => 'pdf', 355 ]); 356 357 $record = [ 358 'contextid' => \context_system::instance()->id, 359 'component' => 'core', 360 'filearea' => 'documentconversion', 361 'itemid' => 0, 362 'filepath' => '/pdf/', 363 ]; 364 $existingfile = $this->create_stored_file('foo', $sourcefile->get_contenthash(), $record); 365 366 $fixture = 'Example content'; 367 $conversion->store_destfile_from_string($fixture); 368 369 $destfile = $conversion->get_destfile(); 370 $this->assertEquals($fixture, $destfile->get_content()); 371 } 372 373 /** 374 * Ensure that the get_status functions cast the status to integer correctly. 375 */ 376 public function test_get_status() { 377 $conversion = new conversion(0, (object) [ 378 'status' => (string) 1, 379 ]); 380 381 $this->assertIsInt($conversion->get('status')); 382 } 383 384 /** 385 * Ensure that get_converter_instance returns false when no converter is set. 386 */ 387 public function test_get_converter_instance_none_set() { 388 $conversion = new conversion(0, (object) []); 389 $this->assertFalse($conversion->get_converter_instance()); 390 } 391 392 /** 393 * Ensure that get_converter_instance returns false when no valid converter is set. 394 */ 395 public function test_get_converter_instance_invalid_set() { 396 $conversion = new conversion(0, (object) [ 397 'converter' => '\\fileconverter_not_a_valid_converter\\converter', 398 ]); 399 $this->assertFalse($conversion->get_converter_instance()); 400 } 401 402 /** 403 * Ensure that get_converter_instance returns an instance when a valid converter is set. 404 */ 405 public function test_get_converter_instance_valid_set() { 406 $conversion = new conversion(0, (object) [ 407 'converter' => \fileconverter_unoconv\converter::class, 408 ]); 409 $this->assertInstanceOf(\fileconverter_unoconv\converter::class, $conversion->get_converter_instance()); 410 } 411 412 /** 413 * Test that all old conversion records are removed periodically. 414 */ 415 public function test_remove_old_conversion_records_old() { 416 $this->resetAfterTest(); 417 global $DB; 418 419 $sourcefile = $this->create_stored_file(); 420 $conversion = new conversion(0, (object) [ 421 'sourcefileid' => $sourcefile->get_id(), 422 'targetformat' => 'pdf', 423 ]); 424 $conversion->create(); 425 $DB->set_field(conversion::TABLE, 'timemodified', time() - YEARSECS); 426 427 conversion::remove_old_conversion_records(); 428 429 $this->assertEquals(0, $DB->count_records(conversion::TABLE)); 430 } 431 432 /** 433 * Test that all old conversion records are removed periodically. 434 */ 435 public function test_remove_old_conversion_records_young() { 436 $this->resetAfterTest(); 437 global $DB; 438 439 $sourcefile = $this->create_stored_file(); 440 $conversion = new conversion(0, (object) [ 441 'sourcefileid' => $sourcefile->get_id(), 442 'targetformat' => 'pdf', 443 ]); 444 $conversion->create(); 445 $DB->set_field(conversion::TABLE, 'timemodified', time() - DAYSECS); 446 447 conversion::remove_old_conversion_records(); 448 449 $this->assertEquals(1, $DB->count_records(conversion::TABLE)); 450 } 451 452 /** 453 * Test orphan records are removed. 454 */ 455 public function test_remove_orphan_records() { 456 global $DB; 457 $this->resetAfterTest(); 458 459 $sf1 = $this->create_stored_file('1', '1'); 460 $sf2 = $this->create_stored_file('2', '2'); 461 $sf3 = $this->create_stored_file('3', '3'); 462 $c1 = new conversion(0, (object) ['sourcefileid' => $sf1->get_id(), 'targetformat' => 'pdf']); 463 $c1->create(); 464 $c2 = new conversion(0, (object) ['sourcefileid' => $sf2->get_id(), 'targetformat' => 'pdf']); 465 $c2->create(); 466 $c3 = new conversion(0, (object) ['sourcefileid' => $sf3->get_id(), 'targetformat' => 'pdf']); 467 $c3->create(); 468 469 $this->assertTrue(conversion::record_exists($c1->get('id'))); 470 $this->assertTrue(conversion::record_exists($c2->get('id'))); 471 $this->assertTrue(conversion::record_exists($c3->get('id'))); 472 473 // Nothing should happen here. 474 conversion::remove_orphan_records(); 475 $this->assertTrue(conversion::record_exists($c1->get('id'))); 476 $this->assertTrue(conversion::record_exists($c2->get('id'))); 477 $this->assertTrue(conversion::record_exists($c3->get('id'))); 478 479 // Delete file #2. 480 $sf2->delete(); 481 conversion::remove_orphan_records(); 482 $this->assertTrue(conversion::record_exists($c1->get('id'))); 483 $this->assertFalse(conversion::record_exists($c2->get('id'))); 484 $this->assertTrue(conversion::record_exists($c3->get('id'))); 485 486 // Delete file #1, #3. 487 $sf1->delete(); 488 $sf3->delete(); 489 conversion::remove_orphan_records(); 490 $this->assertFalse(conversion::record_exists($c1->get('id'))); 491 $this->assertFalse(conversion::record_exists($c2->get('id'))); 492 $this->assertFalse(conversion::record_exists($c3->get('id'))); 493 } 494 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body