1<?php 2 3namespace Drupal\Tests\file\Kernel; 4 5use Drupal\file\Entity\File; 6 7/** 8 * Tests the functions used to validate uploaded files. 9 * 10 * @group file 11 */ 12class ValidatorTest extends FileManagedUnitTestBase { 13 14 /** 15 * An image file. 16 * 17 * @var \Drupal\file\FileInterface 18 */ 19 protected $image; 20 21 /** 22 * A file which is not an image. 23 * 24 * @var \Drupal\file\Entity\File 25 */ 26 protected $nonImage; 27 28 protected function setUp() { 29 parent::setUp(); 30 31 $this->image = File::create(); 32 $this->image->setFileUri('core/misc/druplicon.png'); 33 /** @var \Drupal\Core\File\FileSystemInterface $file_system */ 34 $file_system = \Drupal::service('file_system'); 35 $this->image->setFilename($file_system->basename($this->image->getFileUri())); 36 37 $this->nonImage = File::create(); 38 $this->nonImage->setFileUri('core/assets/vendor/jquery/jquery.min.js'); 39 $this->nonImage->setFilename($file_system->basename($this->nonImage->getFileUri())); 40 } 41 42 /** 43 * Test the file_validate_extensions() function. 44 */ 45 public function testFileValidateExtensions() { 46 $file = File::create(['filename' => 'asdf.txt']); 47 $errors = file_validate_extensions($file, 'asdf txt pork'); 48 $this->assertCount(0, $errors, 'Valid extension accepted.'); 49 50 $file->setFilename('asdf.txt'); 51 $errors = file_validate_extensions($file, 'exe png'); 52 $this->assertCount(1, $errors, 'Invalid extension blocked.'); 53 } 54 55 /** 56 * This ensures a specific file is actually an image. 57 */ 58 public function testFileValidateIsImage() { 59 $this->assertFileExists($this->image->getFileUri()); 60 $errors = file_validate_is_image($this->image); 61 $this->assertCount(0, $errors, 'No error reported for our image file.'); 62 63 $this->assertFileExists($this->nonImage->getFileUri()); 64 $errors = file_validate_is_image($this->nonImage); 65 $this->assertCount(1, $errors, 'An error reported for our non-image file.'); 66 } 67 68 /** 69 * This ensures the resolution of a specific file is within bounds. 70 * 71 * The image will be resized if it's too large. 72 */ 73 public function testFileValidateImageResolution() { 74 // Non-images. 75 $errors = file_validate_image_resolution($this->nonImage); 76 $this->assertCount(0, $errors, 'Should not get any errors for a non-image file.'); 77 $errors = file_validate_image_resolution($this->nonImage, '50x50', '100x100'); 78 $this->assertCount(0, $errors, 'Do not check the resolution on non files.'); 79 80 // Minimum size. 81 $errors = file_validate_image_resolution($this->image); 82 $this->assertCount(0, $errors, 'No errors for an image when there is no minimum or maximum resolution.'); 83 $errors = file_validate_image_resolution($this->image, 0, '200x1'); 84 $this->assertCount(1, $errors, 'Got an error for an image that was not wide enough.'); 85 $errors = file_validate_image_resolution($this->image, 0, '1x200'); 86 $this->assertCount(1, $errors, 'Got an error for an image that was not tall enough.'); 87 $errors = file_validate_image_resolution($this->image, 0, '200x200'); 88 $this->assertCount(1, $errors, 'Small images report an error.'); 89 90 // Maximum size. 91 if ($this->container->get('image.factory')->getToolkitId()) { 92 // Copy the image so that the original doesn't get resized. 93 copy('core/misc/druplicon.png', 'temporary://druplicon.png'); 94 $this->image->setFileUri('temporary://druplicon.png'); 95 96 $errors = file_validate_image_resolution($this->image, '10x5'); 97 $this->assertCount(0, $errors, 'No errors should be reported when an oversized image can be scaled down.'); 98 99 $image = $this->container->get('image.factory')->get($this->image->getFileUri()); 100 $this->assertTrue($image->getWidth() <= 10, 'Image scaled to correct width.', 'File'); 101 $this->assertTrue($image->getHeight() <= 5, 'Image scaled to correct height.', 'File'); 102 103 // Once again, now with negative width and height to force an error. 104 copy('core/misc/druplicon.png', 'temporary://druplicon.png'); 105 $this->image->setFileUri('temporary://druplicon.png'); 106 $errors = file_validate_image_resolution($this->image, '-10x-5'); 107 $this->assertCount(1, $errors, 'An error reported for an oversized image that can not be scaled down.'); 108 109 \Drupal::service('file_system')->unlink('temporary://druplicon.png'); 110 } 111 else { 112 // TODO: should check that the error is returned if no toolkit is available. 113 $errors = file_validate_image_resolution($this->image, '5x10'); 114 $this->assertCount(1, $errors, 'Oversize images that cannot be scaled get an error.'); 115 } 116 } 117 118 /** 119 * This will ensure the filename length is valid. 120 */ 121 public function testFileValidateNameLength() { 122 // Create a new file entity. 123 $file = File::create(); 124 125 // Add a filename with an allowed length and test it. 126 $file->setFilename(str_repeat('x', 240)); 127 $this->assertEqual(strlen($file->getFilename()), 240); 128 $errors = file_validate_name_length($file); 129 $this->assertCount(0, $errors, 'No errors reported for 240 length filename.'); 130 131 // Add a filename with a length too long and test it. 132 $file->setFilename(str_repeat('x', 241)); 133 $errors = file_validate_name_length($file); 134 $this->assertCount(1, $errors, 'An error reported for 241 length filename.'); 135 136 // Add a filename with an empty string and test it. 137 $file->setFilename(''); 138 $errors = file_validate_name_length($file); 139 $this->assertCount(1, $errors, 'An error reported for 0 length filename.'); 140 } 141 142 /** 143 * Test file_validate_size(). 144 */ 145 public function testFileValidateSize() { 146 // Create a file with a size of 1000 bytes, and quotas of only 1 byte. 147 $file = File::create(['filesize' => 1000]); 148 $errors = file_validate_size($file, 0, 0); 149 $this->assertCount(0, $errors, 'No limits means no errors.'); 150 $errors = file_validate_size($file, 1, 0); 151 $this->assertCount(1, $errors, 'Error for the file being over the limit.'); 152 $errors = file_validate_size($file, 0, 1); 153 $this->assertCount(1, $errors, 'Error for the user being over their limit.'); 154 $errors = file_validate_size($file, 1, 1); 155 $this->assertCount(2, $errors, 'Errors for both the file and their limit.'); 156 } 157 158} 159