You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							293 lines
						
					
					
						
							9.3 KiB
						
					
					
				
			
		
		
	
	
							293 lines
						
					
					
						
							9.3 KiB
						
					
					
				| <?php | |
|  | |
| namespace yiiunit\framework\validators; | |
|  | |
|  | |
| use yii\validators\FileValidator; | |
| use yii\web\UploadedFile; | |
| use Yii; | |
| use yiiunit\data\validators\models\FakedValidationModel; | |
| use yiiunit\TestCase; | |
|  | |
| class FileValidatorTest extends TestCase | |
| { | |
| 	public function setUp() | |
| 	{ | |
| 		$this->mockApplication(); | |
| 	} | |
|  | |
| 	public function testAssureMessagesSetOnInit() | |
| 	{ | |
| 		$val = new FileValidator(); | |
| 		foreach (['message', 'uploadRequired', 'tooMany', 'wrongType', 'tooBig', 'tooSmall'] as $attr) { | |
| 			$this->assertTrue(is_string($val->$attr)); | |
| 		} | |
| 	} | |
|  | |
| 	public function testTypeSplitOnInit() | |
| 	{ | |
| 		$val = new FileValidator(['types' => 'jpeg, jpg, gif']); | |
| 		$this->assertEquals(['jpeg', 'jpg', 'gif'], $val->types); | |
| 		$val = new FileValidator(['types' => 'jpeg']); | |
| 		$this->assertEquals(['jpeg'], $val->types); | |
| 		$val = new FileValidator(['types' => '']); | |
| 		$this->assertEquals([], $val->types); | |
| 		$val = new FileValidator(['types' => []]); | |
| 		$this->assertEquals([], $val->types); | |
| 		$val = new FileValidator(); | |
| 		$this->assertEquals([], $val->types); | |
| 		$val = new FileValidator(['types' => ['jpeg', 'exe']]); | |
| 		$this->assertEquals(['jpeg', 'exe'], $val->types); | |
| 	} | |
|  | |
| 	public function testGetSizeLimit() | |
| 	{ | |
| 		$size = $this->sizeToBytes(ini_get('upload_max_filesize')); | |
| 		$val = new FileValidator(); | |
| 		$this->assertEquals($size, $val->getSizeLimit()); | |
| 		$val->maxSize = $size + 1; // set and test if value is overridden | |
| 		$this->assertEquals($size, $val->getSizeLimit()); | |
| 		$val->maxSize = abs($size - 1); | |
| 		$this->assertEquals($size - 1, $val->getSizeLimit()); | |
| 		$_POST['MAX_FILE_SIZE'] = $size + 1; | |
| 		$this->assertEquals($size - 1, $val->getSizeLimit()); | |
| 		$_POST['MAX_FILE_SIZE'] = abs($size - 2); | |
| 		$this->assertSame($_POST['MAX_FILE_SIZE'], $val->getSizeLimit()); | |
| 	} | |
|  | |
| 	protected function sizeToBytes($sizeStr) | |
| 	{ | |
| 		switch (substr($sizeStr, -1)) { | |
| 			case 'M': | |
| 			case 'm': | |
| 				return (int)$sizeStr * 1048576; | |
| 			case 'K': | |
| 			case 'k': | |
| 				return (int)$sizeStr * 1024; | |
| 			case 'G': | |
| 			case 'g': | |
| 				return (int)$sizeStr * 1073741824; | |
| 			default: | |
| 				return (int)$sizeStr; | |
| 		} | |
| 	} | |
|  | |
| 	public function testValidateAttributeMultiple() | |
| 	{ | |
| 		$val = new FileValidator(['maxFiles' => 2]); | |
| 		$m = FakedValidationModel::createWithAttributes(['attr_files' => 'path']); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertTrue($m->hasErrors('attr_files')); | |
| 		$m = FakedValidationModel::createWithAttributes(['attr_files' => []]); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertTrue($m->hasErrors('attr_files')); | |
| 		$this->assertSame($val->uploadRequired, current($m->getErrors('attr_files'))); | |
| 		$m = FakedValidationModel::createWithAttributes( | |
| 			[ | |
| 				'attr_files' => $this->createTestFiles( | |
| 					[ | |
| 						[ | |
| 							'name' => 'test_up_1.txt', | |
| 							'size' => 1024, | |
| 						], | |
| 						[ | |
| 							'error' => UPLOAD_ERR_NO_FILE, | |
| 						], | |
| 					] | |
| 				) | |
| 			] | |
| 		); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertFalse($m->hasErrors('attr_files')); | |
| 		$m = FakedValidationModel::createWithAttributes([ | |
| 			'attr_files' => $this->createTestFiles([ | |
| 				[''], [''], [''] | |
| 			]) | |
| 		]); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertTrue($m->hasErrors()); | |
| 		$this->assertTrue(stripos(current($m->getErrors('attr_files')), 'you can upload at most') !== false); | |
| 	} | |
|  | |
| 	/** | |
| 	 * @param array $params | |
| 	 * @return UploadedFile[] | |
| 	 */ | |
| 	protected function createTestFiles($params = []) | |
| 	{ | |
| 		$rndString = function ($len = 10) { | |
| 			$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
| 			$randomString = ''; | |
| 			for ($i = 0; $i < $len; $i++) { | |
| 				$randomString .= $characters[rand(0, strlen($characters) - 1)]; | |
| 			} | |
| 			return $randomString; | |
| 		}; | |
| 		$files = []; | |
| 		foreach ($params as $param) { | |
| 			if (empty($param) && count($params) != 1) { | |
| 				$files[] = ['no instance of UploadedFile']; | |
| 				continue; | |
| 			} | |
| 			$name = isset($param['name']) ? $param['name'] : $rndString(); | |
| 			$tempName = \Yii::getAlias('@yiiunit/runtime/validators/file/tmp') . $name; | |
| 			if (is_readable($tempName)) { | |
| 				$size = filesize($tempName); | |
| 			} else { | |
| 				$size = isset($param['size']) ? $param['size'] : rand( | |
| 					1, | |
| 					$this->sizeToBytes(ini_get('upload_max_filesize')) | |
| 				); | |
| 			} | |
| 			$type = isset($param['type']) ? $param['type'] : 'text/plain'; | |
| 			$error = isset($param['error']) ? $param['error'] : UPLOAD_ERR_OK; | |
| 			if (count($params) == 1) { | |
| 				$error = empty($param) ? UPLOAD_ERR_NO_FILE : $error; | |
| 				return new UploadedFile([ | |
| 					'name' => $name, | |
| 					'tempName' => $tempName, | |
| 					'type' => $type, | |
| 					'size' => $size, | |
| 					'error' => $error | |
| 				]); | |
| 			} | |
| 			$files[] = new UploadedFile([ | |
| 				'name' => $name, | |
| 				'tempName' => $tempName, | |
| 				'type' => $type, | |
| 				'size' => $size, | |
| 				'error' => $error | |
| 			]); | |
| 		} | |
| 		return $files; | |
| 	} | |
|  | |
| 	public function testValidateAttribute() | |
| 	{ | |
| 		// single File | |
| 		$val = new FileValidator(); | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertFalse($m->hasErrors()); | |
| 		$val->validateAttribute($m, 'attr_files_empty'); | |
| 		$this->assertTrue($m->hasErrors('attr_files_empty')); | |
| 		$this->assertSame($val->uploadRequired, current($m->getErrors('attr_files_empty'))); | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		// too big | |
| 		$val = new FileValidator(['maxSize' => 128]); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertTrue($m->hasErrors('attr_files')); | |
| 		$this->assertTrue( | |
| 			stripos( | |
| 				current($m->getErrors('attr_files')), | |
| 				str_ireplace(['{file}', '{limit}'], [$m->attr_files->name, 128], $val->tooBig) | |
| 			) !== false | |
| 		); | |
| 		// to Small | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(['minSize' => 2048]); | |
| 		$val->validateAttribute($m, 'attr_files'); | |
| 		$this->assertTrue($m->hasErrors('attr_files')); | |
| 		$this->assertTrue( | |
| 			stripos( | |
| 				current($m->getErrors('attr_files')), | |
| 				str_ireplace(['{file}', '{limit}'], [$m->attr_files->name, 2048], $val->tooSmall) | |
| 			) !== false | |
| 		); | |
| 		// UPLOAD_ERR_INI_SIZE/UPLOAD_ERR_FORM_SIZE | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_ini'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_ini')); | |
| 		$this->assertTrue( | |
| 			stripos( | |
| 				current($m->getErrors('attr_err_ini')), | |
| 				str_ireplace( | |
| 					['{file}', '{limit}'], | |
| 					[$m->attr_err_ini->name, $val->getSizeLimit()], | |
| 					$val->tooBig | |
| 				) | |
| 			) !== false | |
| 		); | |
| 		// UPLOAD_ERR_PARTIAL | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_part'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_part')); | |
| 		$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_part'))); | |
| 	} | |
|  | |
| 	public function testValidateAttributeType() | |
| 	{ | |
| 		$val = new FileValidator(['types' => 'jpeg, jpg']); | |
| 		$m = FakedValidationModel::createWithAttributes( | |
| 			[ | |
| 				'attr_jpg' => $this->createTestFiles([['name' => 'one.jpeg']]), | |
| 				'attr_exe' => $this->createTestFiles([['name' => 'bad.exe']]), | |
| 			] | |
| 		); | |
| 		$val->validateAttribute($m, 'attr_jpg'); | |
| 		$this->assertFalse($m->hasErrors('attr_jpg')); | |
| 		$val->validateAttribute($m, 'attr_exe'); | |
| 		$this->assertTrue($m->hasErrors('attr_exe')); | |
| 		$this->assertTrue(stripos(current($m->getErrors('attr_exe')), 'Only files with these extensions ') !== false); | |
| 	} | |
|  | |
|  | |
| 	protected function createModelForAttributeTest() | |
| 	{ | |
| 		return FakedValidationModel::createWithAttributes( | |
| 			[ | |
| 				'attr_files' => $this->createTestFiles([ | |
| 					['name' => 'abc.jpg', 'size' => 1024, 'type' => 'image/jpeg'], | |
| 				]), | |
| 				'attr_files_empty' => $this->createTestFiles([[]]), | |
| 				'attr_err_ini' => $this->createTestFiles([['error' => UPLOAD_ERR_INI_SIZE]]), | |
| 				'attr_err_part' => $this->createTestFiles([['error' => UPLOAD_ERR_PARTIAL]]), | |
| 				'attr_err_tmp' => $this->createTestFiles([['error' => UPLOAD_ERR_NO_TMP_DIR]]), | |
| 				'attr_err_write' => $this->createTestFiles([['error' => UPLOAD_ERR_CANT_WRITE]]), | |
| 				'attr_err_ext' => $this->createTestFiles([['error' => UPLOAD_ERR_EXTENSION]]), | |
| 			] | |
| 		); | |
| 	} | |
|  | |
| 	public function testValidateAttributeErrPartial() | |
| 	{ | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_part'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_part')); | |
| 		$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_part'))); | |
| 		$log = Yii::$app->getLog()->toArray(); | |
| 	} | |
|  | |
| 	public function testValidateAttributeErrCantWrite() | |
| 	{ | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_write'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_write')); | |
| 		$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_write'))); | |
| 		$log = Yii::$app->getLog()->toArray(); | |
| 	} | |
|  | |
| 	public function testValidateAttributeErrExtension() | |
| 	{ | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_ext'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_ext')); | |
| 		$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_ext'))); | |
| 		$log = Yii::$app->getLog()->toArray(); | |
| 	} | |
|  | |
| 	public function testValidateAttributeErrNoTmpDir() | |
| 	{ | |
| 		$m = $this->createModelForAttributeTest(); | |
| 		$val = new FileValidator(); | |
| 		$val->validateAttribute($m, 'attr_err_tmp'); | |
| 		$this->assertTrue($m->hasErrors('attr_err_tmp')); | |
| 		$this->assertSame(Yii::t('yii', 'File upload failed.'), current($m->getErrors('attr_err_tmp'))); | |
| 		$log = Yii::$app->getLog()->toArray(); | |
| 	} | |
| }
 | |
| 
 |