See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 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 /** 18 * Provides the {@link core_form\filetypes_util_testcase} class. 19 * 20 * @package core_form 21 * @category test 22 * @copyright 2017 David Mudrák <david@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace core_form; 27 28 use advanced_testcase; 29 30 defined('MOODLE_INTERNAL') || die(); 31 32 global $CFG; 33 34 /** 35 * Test cases for the {@link core_form\filetypes_util} class. 36 * 37 * @copyright 2017 David Mudrak <david@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class filetypes_util_test extends advanced_testcase { 41 42 /** 43 * Test normalizing list of extensions. 44 */ 45 public function test_normalize_file_types() { 46 47 $this->resetAfterTest(true); 48 $util = new filetypes_util(); 49 50 $this->assertSame(['.odt'], $util->normalize_file_types('.odt')); 51 $this->assertSame(['.odt'], $util->normalize_file_types('odt')); 52 $this->assertSame(['.odt'], $util->normalize_file_types('.ODT')); 53 $this->assertSame(['.doc', '.jpg', '.mp3'], $util->normalize_file_types('doc, jpg, mp3')); 54 $this->assertSame(['.doc', '.jpg', '.mp3'], $util->normalize_file_types(['.doc', '.jpg', '.mp3'])); 55 $this->assertSame(['.doc', '.jpg', '.mp3'], $util->normalize_file_types('doc, *.jpg, mp3')); 56 $this->assertSame(['.doc', '.jpg', '.mp3'], $util->normalize_file_types(['doc ', ' JPG ', '.mp3'])); 57 $this->assertSame(['.rtf', '.pdf', '.docx'], 58 $util->normalize_file_types("RTF,.pdf\n...DocX,,,;\rPDF\trtf ...Rtf")); 59 $this->assertSame(['.tgz', '.tar.gz'], $util->normalize_file_types('tgz,TAR.GZ tar.gz .tar.gz tgz TGZ')); 60 $this->assertSame(['.notebook'], $util->normalize_file_types('"Notebook":notebook;NOTEBOOK;,\'NoTeBook\'')); 61 $this->assertSame([], $util->normalize_file_types('')); 62 $this->assertSame([], $util->normalize_file_types([])); 63 $this->assertSame(['.0'], $util->normalize_file_types(0)); 64 $this->assertSame(['.0'], $util->normalize_file_types('0')); 65 $this->assertSame(['.odt'], $util->normalize_file_types('*.odt')); 66 $this->assertSame([], $util->normalize_file_types('.')); 67 $this->assertSame(['.foo'], $util->normalize_file_types('. foo')); 68 $this->assertSame(['*'], $util->normalize_file_types('*')); 69 $this->assertSame([], $util->normalize_file_types('*~')); 70 $this->assertSame(['.pdf', '.ps'], $util->normalize_file_types('pdf *.ps foo* *bar .r??')); 71 $this->assertSame(['*'], $util->normalize_file_types('pdf *.ps foo* * *bar .r??')); 72 } 73 74 /** 75 * Test MIME type formal recognition. 76 */ 77 public function test_looks_like_mimetype() { 78 79 $this->resetAfterTest(true); 80 $util = new filetypes_util(); 81 82 $this->assertTrue($util->looks_like_mimetype('type/subtype')); 83 $this->assertTrue($util->looks_like_mimetype('type/x-subtype')); 84 $this->assertTrue($util->looks_like_mimetype('type/x-subtype+xml')); 85 $this->assertTrue($util->looks_like_mimetype('type/vnd.subtype.xml')); 86 $this->assertTrue($util->looks_like_mimetype('type/vnd.subtype+xml')); 87 88 $this->assertFalse($util->looks_like_mimetype('.gif')); 89 $this->assertFalse($util->looks_like_mimetype('audio')); 90 $this->assertFalse($util->looks_like_mimetype('foo/bar/baz')); 91 } 92 93 /** 94 * Test getting/checking group. 95 */ 96 public function test_is_filetype_group() { 97 98 $this->resetAfterTest(true); 99 $util = new filetypes_util(); 100 101 $audio = $util->is_filetype_group('audio'); 102 $this->assertNotFalse($audio); 103 $this->assertIsArray($audio->extensions); 104 $this->assertIsArray($audio->mimetypes); 105 106 $this->assertFalse($util->is_filetype_group('.gif')); 107 $this->assertFalse($util->is_filetype_group('somethingveryunlikelytoeverexist')); 108 } 109 110 111 /** 112 * Test describing list of extensions. 113 */ 114 public function test_describe_file_types() { 115 116 $this->resetAfterTest(true); 117 $util = new filetypes_util(); 118 119 force_current_language('en'); 120 121 // Check that it is able to describe individual file extensions. 122 $desc = $util->describe_file_types('jpg .jpeg *.jpe PNG;.gif, mudrd8mz'); 123 $this->assertTrue($desc->hasdescriptions); 124 125 $desc = $desc->descriptions; 126 $this->assertEquals(4, count($desc)); 127 128 $this->assertEquals('File', $desc[0]->description); 129 $this->assertEquals('.mudrd8mz', $desc[0]->extensions); 130 131 $this->assertEquals('Image (JPEG)', $desc[2]->description); 132 $this->assertStringContainsString('.jpg', $desc[2]->extensions); 133 $this->assertStringContainsString('.jpeg', $desc[2]->extensions); 134 $this->assertStringContainsString('.jpe', $desc[2]->extensions); 135 136 // Check that it can describe groups and mimetypes too. 137 $desc = $util->describe_file_types('audio text/plain'); 138 $this->assertTrue($desc->hasdescriptions); 139 140 $desc = $desc->descriptions; 141 $this->assertEquals(2, count($desc)); 142 143 $this->assertEquals('Audio files', $desc[0]->description); 144 $this->assertStringContainsString('.mp3', $desc[0]->extensions); 145 $this->assertStringContainsString('.wav', $desc[0]->extensions); 146 $this->assertStringContainsString('.ogg', $desc[0]->extensions); 147 148 $this->assertEquals('Text file', $desc[1]->description); 149 $this->assertStringContainsString('.txt', $desc[1]->extensions); 150 151 // Empty. 152 $desc = $util->describe_file_types(''); 153 $this->assertFalse($desc->hasdescriptions); 154 $this->assertEmpty($desc->descriptions); 155 156 // Any. 157 $desc = $util->describe_file_types('*'); 158 $this->assertTrue($desc->hasdescriptions); 159 $this->assertNotEmpty($desc->descriptions[0]->description); 160 $this->assertEmpty($desc->descriptions[0]->extensions); 161 162 // Unknown mimetype. 163 $desc = $util->describe_file_types('application/x-something-really-unlikely-ever-exist'); 164 $this->assertTrue($desc->hasdescriptions); 165 $this->assertEquals('application/x-something-really-unlikely-ever-exist', $desc->descriptions[0]->description); 166 $this->assertEmpty($desc->descriptions[0]->extensions); 167 } 168 169 /** 170 * Test expanding mime types into extensions. 171 */ 172 public function test_expand() { 173 174 $this->resetAfterTest(true); 175 $util = new filetypes_util(); 176 177 $this->assertSame([], $util->expand('')); 178 179 $expanded = $util->expand('document .cdr text/plain'); 180 $this->assertNotContains('document', $expanded); 181 $this->assertNotContains('text/plain', $expanded); 182 $this->assertContains('.doc', $expanded); 183 $this->assertContains('.odt', $expanded); 184 $this->assertContains('.txt', $expanded); 185 $this->assertContains('.cdr', $expanded); 186 187 $expanded = $util->expand('document .cdr text/plain', true, false); 188 $this->assertContains('document', $expanded); 189 $this->assertNotContains('text/plain', $expanded); 190 $this->assertContains('.doc', $expanded); 191 $this->assertContains('.odt', $expanded); 192 $this->assertContains('.txt', $expanded); 193 $this->assertContains('.cdr', $expanded); 194 195 $expanded = $util->expand('document .cdr text/plain', false, true); 196 $this->assertNotContains('document', $expanded); 197 $this->assertContains('text/plain', $expanded); 198 $this->assertContains('.doc', $expanded); 199 $this->assertContains('.odt', $expanded); 200 $this->assertContains('.txt', $expanded); 201 $this->assertContains('.cdr', $expanded); 202 203 $this->assertSame([], $util->expand('foo/bar', true, false)); 204 $this->assertSame(['foo/bar'], $util->expand('foo/bar', true, true)); 205 } 206 207 /** 208 * Test checking that a type is among others. 209 */ 210 public function test_is_listed() { 211 212 $this->resetAfterTest(true); 213 $util = new filetypes_util(); 214 215 // These should be intuitively true. 216 $this->assertTrue($util->is_listed('txt', 'text/plain')); 217 $this->assertTrue($util->is_listed('txt', 'doc txt rtf')); 218 $this->assertTrue($util->is_listed('.txt', '.doc;.txt;.rtf')); 219 $this->assertTrue($util->is_listed('audio', 'text/plain audio video')); 220 $this->assertTrue($util->is_listed('text/plain', 'text/plain audio video')); 221 $this->assertTrue($util->is_listed('jpg jpe jpeg', 'image/jpeg')); 222 $this->assertTrue($util->is_listed(['jpg', 'jpe', '.png'], 'image')); 223 224 // These should be intuitively false. 225 $this->assertFalse($util->is_listed('.gif', 'text/plain')); 226 227 // Not all text/plain formats are in the document group. 228 $this->assertFalse($util->is_listed('text/plain', 'document')); 229 230 // Not all documents (and also the group itself) is not a plain text. 231 $this->assertFalse($util->is_listed('document', 'text/plain')); 232 233 // This may look wrong at the first sight as you might expect that the 234 // mimetype should simply map to an extension ... 235 $this->assertFalse($util->is_listed('image/jpeg', '.jpg')); 236 237 // But it is principally same situation as this (there is no 1:1 mapping). 238 $this->assertFalse($util->is_listed('.c', '.txt')); 239 $this->assertTrue($util->is_listed('.txt .c', 'text/plain')); 240 $this->assertFalse($util->is_listed('text/plain', '.c')); 241 242 // Any type is included if the filter is empty. 243 $this->assertTrue($util->is_listed('txt', '')); 244 $this->assertTrue($util->is_listed('txt', '*')); 245 246 // Empty value is part of any list. 247 $this->assertTrue($util->is_listed('', '.txt')); 248 } 249 250 /** 251 * Test getting types not present in a list. 252 */ 253 public function test_get_not_listed() { 254 255 $this->resetAfterTest(true); 256 $util = new filetypes_util(); 257 258 $this->assertEmpty($util->get_not_listed('txt', 'text/plain')); 259 $this->assertEmpty($util->get_not_listed('txt', '.doc .txt .rtf')); 260 $this->assertEmpty($util->get_not_listed('txt', 'text/plain')); 261 $this->assertEmpty($util->get_not_listed(['jpg', 'jpe', 'jpeg'], 'image/jpeg')); 262 $this->assertEmpty($util->get_not_listed('', 'foo/bar')); 263 $this->assertEmpty($util->get_not_listed('.foobar', '')); 264 $this->assertEmpty($util->get_not_listed('.foobar', '*')); 265 266 // Returned list is normalized so extensions have the dot added. 267 $this->assertContains('.exe', $util->get_not_listed('exe', '.c .h')); 268 269 // If this looks wrong to you, see {@see self::test_is_listed()} for more details on this behaviour. 270 $this->assertContains('image/jpeg', $util->get_not_listed('image/jpeg', '.jpg .jpeg')); 271 } 272 273 /** 274 * Test populating the tree for the browser. 275 */ 276 public function test_data_for_browser() { 277 278 $this->resetAfterTest(true); 279 $util = new filetypes_util(); 280 281 $data = $util->data_for_browser(); 282 $this->assertContainsOnly('object', $data); 283 foreach ($data as $group) { 284 $this->assertObjectHasAttribute('key', $group); 285 $this->assertObjectHasAttribute('types', $group); 286 if ($group->key !== '') { 287 $this->assertTrue($group->selectable); 288 } 289 } 290 291 // Confirm that the reserved type '.xxx' isn't present in the 'Other files' section. 292 $types = array_reduce($data, function($carry, $group) { 293 if ($group->name === 'Other files') { 294 return $group->types; 295 } 296 }); 297 $typekeys = array_map(function($type) { 298 return $type->key; 299 }, $types); 300 $this->assertNotContains('.xxx', $typekeys); 301 302 // All these three files are in both "image" and also "web_image" 303 // groups. We display both groups. 304 $data = $util->data_for_browser('jpg png gif', true, '.gif'); 305 $this->assertEquals(3, count($data)); 306 $this->assertTrue($data[0]->key !== $data[1]->key); 307 foreach ($data as $group) { 308 $this->assertTrue(($group->key === 'image' || $group->key === 'web_image' || $group->key === 'optimised_image')); 309 $this->assertEquals(3, count($group->types)); 310 $this->assertFalse($group->selectable); 311 foreach ($group->types as $ext) { 312 if ($ext->key === '.gif') { 313 $this->assertTrue($ext->selected); 314 } else { 315 $this->assertFalse($ext->selected); 316 } 317 } 318 } 319 320 // The groups web_image and optimised_image are a subset of the group image. The 321 // file extensions that fall into these groups will be displayed thrice. 322 $data = $util->data_for_browser('web_image'); 323 foreach ($data as $group) { 324 $this->assertTrue(($group->key === 'image' || $group->key === 'web_image' || $group->key === 'optimised_image')); 325 } 326 327 // Check that "All file types" are displayed first. 328 $data = $util->data_for_browser(); 329 $group = array_shift($data); 330 $this->assertEquals('*', $group->key); 331 332 // Check that "All file types" is not displayed if should not. 333 $data = $util->data_for_browser(null, false); 334 $group = array_shift($data); 335 $this->assertNotEquals('*', $group->key); 336 337 // Groups with an extension selected start expanded. The "Other files" 338 // starts expanded. The rest start collapsed. 339 $data = $util->data_for_browser(null, false, '.png'); 340 foreach ($data as $group) { 341 if ($group->key === 'document') { 342 $this->assertfalse($group->expanded); 343 } else if ($group->key === '') { 344 $this->assertTrue($group->expanded); 345 } 346 foreach ($group->types as $ext) { 347 foreach ($group->types as $ext) { 348 if ($ext->key === '.png') { 349 $this->assertTrue($ext->selected); 350 $this->assertTrue($group->expanded); 351 } 352 } 353 } 354 } 355 } 356 357 /** 358 * Data provider for testing test_is_allowed_file_type. 359 * 360 * @return array 361 */ 362 public function is_allowed_file_type_provider() { 363 return [ 364 'Filetype not in extension list' => [ 365 'filename' => 'test.xml', 366 'list' => '.png .jpg', 367 'expected' => false 368 ], 369 'Filetype not in mimetype list' => [ 370 'filename' => 'test.xml', 371 'list' => 'image/png', 372 'expected' => false 373 ], 374 'Filetype not in group list' => [ 375 'filename' => 'test.xml', 376 'list' => 'web_file', 377 'expected' => false 378 ], 379 'Filetype in list as extension' => [ 380 'filename' => 'test.xml', 381 'list' => 'xml', 382 'expected' => true 383 ], 384 'Empty list should allow all' => [ 385 'filename' => 'test.xml', 386 'list' => '', 387 'expected' => true 388 ], 389 'Filetype in list but later on' => [ 390 'filename' => 'test.xml', 391 'list' => 'gif;jpeg,image/png xml xlsx', 392 'expected' => true 393 ], 394 'Filetype in list as mimetype' => [ 395 'filename' => 'test.xml', 396 'list' => 'image/png application/xml', 397 'expected' => true 398 ], 399 'Filetype in list as group' => [ 400 'filename' => 'test.html', 401 'list' => 'video,web_file', 402 'expected' => true 403 ], 404 ]; 405 } 406 407 /** 408 * Test is_allowed_file_type(). 409 * @dataProvider is_allowed_file_type_provider 410 * @param string $filename The filename to check 411 * @param string $list The space , or ; separated list of types supported 412 * @param boolean $expected The expected result. True if the file is allowed, false if not. 413 */ 414 public function test_is_allowed_file_type($filename, $list, $expected) { 415 $util = new filetypes_util(); 416 $this->assertSame($expected, $util->is_allowed_file_type($filename, $list)); 417 } 418 419 /** 420 * Data provider for testing test_get_unknown_file_types. 421 * 422 * @return array 423 */ 424 public function get_unknown_file_types_provider() { 425 return [ 426 'Empty list' => [ 427 'filetypes' => '', 428 'expected' => [], 429 ], 430 'Any file type' => [ 431 'filetypes' => '*', 432 'expected' => [], 433 ], 434 'Unknown extension' => [ 435 'filetypes' => '.rat', 436 'expected' => ['.rat'] 437 ], 438 'Multiple unknown extensions' => [ 439 'filetypes' => '.ricefield .rat', 440 'expected' => ['.ricefield', '.rat'] 441 ], 442 'Existant extension' => [ 443 'filetypes' => '.xml', 444 'expected' => [] 445 ], 446 'Existant group' => [ 447 'filetypes' => 'web_file', 448 'expected' => [] 449 ], 450 'Nonexistant mimetypes' => [ 451 'filetypes' => 'ricefield/rat', 452 'expected' => ['ricefield/rat'] 453 ], 454 'Existant mimetype' => [ 455 'filetypes' => 'application/xml', 456 'expected' => [] 457 ], 458 'Multiple unknown mimetypes' => [ 459 'filetypes' => 'ricefield/rat cam/ball', 460 'expected' => ['ricefield/rat', 'cam/ball'] 461 ], 462 'Strange characters in unknown extension/group' => [ 463 'filetypes' => '©ç√√ß∂å√©åß©√', 464 'expected' => ['.©ç√√ß∂å√©åß©√'] 465 ], 466 'Some existant some not' => [ 467 'filetypes' => '.txt application/xml web_file ©ç√√ß∂å√©åß©√ .png ricefield/rat document', 468 'expected' => ['.©ç√√ß∂å√©åß©√', 'ricefield/rat'] 469 ], 470 'Reserved file type xxx included' => [ 471 'filetypes' => '.xxx .html .jpg', 472 'expected' => ['.xxx'] 473 ] 474 ]; 475 } 476 477 /** 478 * Test get_unknown_file_types(). 479 * @dataProvider get_unknown_file_types_provider 480 * @param string $filetypes The filetypes to check 481 * @param array $expected The expected result. The list of non existant file types. 482 */ 483 public function test_get_unknown_file_types($filetypes, $expected) { 484 $util = new filetypes_util(); 485 $this->assertSame($expected, $util->get_unknown_file_types($filetypes)); 486 } 487 488 /** 489 * Test that a debugging noticed is displayed when calling is_whitelisted(). 490 */ 491 public function test_deprecation_is_whitelisted() { 492 493 $util = new filetypes_util(); 494 $this->assertTrue($util->is_whitelisted('txt', 'text/plain')); 495 $this->assertDebuggingCalled('filetypes_util::is_whitelisted() is deprecated. ' . 496 'Please use filetypes_util::is_listed() instead.', DEBUG_DEVELOPER); 497 } 498 499 /** 500 * Test that a debugging noticed is displayed when calling get_not_whitelisted(). 501 */ 502 public function test_deprecation_get_not_whitelisted() { 503 504 $util = new filetypes_util(); 505 $this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain')); 506 $this->assertDebuggingCalled('filetypes_util::get_not_whitelisted() is deprecated. ' . 507 'Please use filetypes_util::get_not_listed() instead.', DEBUG_DEVELOPER); 508 } 509 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body