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.
		
		
		
		
		
			
		
			
				
					
					
						
							304 lines
						
					
					
						
							10 KiB
						
					
					
				
			
		
		
	
	
							304 lines
						
					
					
						
							10 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 (array('message', 'uploadRequired', 'tooMany', 'wrongType', 'tooBig', 'tooSmall') as $attr) { | 
						|
			$this->assertTrue(is_string($val->$attr)); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	public function testTypeSplitOnInit() | 
						|
	{ | 
						|
		$val = new FileValidator(array('types' => 'jpeg, jpg, gif')); | 
						|
		$this->assertEquals(array('jpeg', 'jpg', 'gif'), $val->types); | 
						|
		$val = new FileValidator(array('types' => 'jpeg')); | 
						|
		$this->assertEquals(array('jpeg'), $val->types); | 
						|
		$val = new FileValidator(array('types' => '')); | 
						|
		$this->assertEquals(array(), $val->types); | 
						|
		$val = new FileValidator(array('types' => array())); | 
						|
		$this->assertEquals(array(), $val->types); | 
						|
		$val = new FileValidator(); | 
						|
		$this->assertEquals(array(), $val->types); | 
						|
		$val = new FileValidator(array('types' => array('jpeg', 'exe'))); | 
						|
		$this->assertEquals(array('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(array('maxFiles' => 2)); | 
						|
		$m = FakedValidationModel::createWithAttributes(array('attr_files' => 'path')); | 
						|
		$val->validateAttribute($m, 'attr_files'); | 
						|
		$this->assertTrue($m->hasErrors('attr_files')); | 
						|
		$m = FakedValidationModel::createWithAttributes(array('attr_files' => array())); | 
						|
		$val->validateAttribute($m, 'attr_files'); | 
						|
		$this->assertTrue($m->hasErrors('attr_files')); | 
						|
		$this->assertSame($val->uploadRequired, current($m->getErrors('attr_files'))); | 
						|
		$m = FakedValidationModel::createWithAttributes( | 
						|
			array( | 
						|
				'attr_files' => $this->createTestFiles( | 
						|
					array( | 
						|
						array( | 
						|
							'name' => 'test_up_1.txt', | 
						|
							'size' => 1024, | 
						|
						), | 
						|
						array( | 
						|
							'error' => UPLOAD_ERR_NO_FILE, | 
						|
						), | 
						|
					) | 
						|
				) | 
						|
			) | 
						|
		); | 
						|
		$val->validateAttribute($m, 'attr_files'); | 
						|
		$this->assertFalse($m->hasErrors('attr_files')); | 
						|
		$m = FakedValidationModel::createWithAttributes( | 
						|
			array('attr_files' => $this->createTestFiles(array(array(''), array(''), array(''),))) | 
						|
		); | 
						|
		$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 = array()) | 
						|
	{ | 
						|
		$rndString = function ($len = 10) { | 
						|
			$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; | 
						|
			$randomString = ''; | 
						|
			for ($i = 0; $i < $len; $i++) { | 
						|
				$randomString .= $characters[rand(0, strlen($characters) - 1)]; | 
						|
			} | 
						|
			return $randomString; | 
						|
		}; | 
						|
		$files = array(); | 
						|
		foreach ($params as $param) { | 
						|
			if (empty($param) && count($params) != 1) { | 
						|
				$files[] = array('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(array( | 
						|
					'name' => $name, | 
						|
					'tempName' => $tempName, | 
						|
					'type' => $type, | 
						|
					'size' => $size, | 
						|
					'error' => $error | 
						|
				)); | 
						|
			} | 
						|
			$files[] = new UploadedFile(array( | 
						|
				'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(array('maxSize' => 128)); | 
						|
		$val->validateAttribute($m, 'attr_files'); | 
						|
		$this->assertTrue($m->hasErrors('attr_files')); | 
						|
		$this->assertTrue( | 
						|
			stripos( | 
						|
				current($m->getErrors('attr_files')), | 
						|
				str_ireplace(array('{file}', '{limit}'), array($m->attr_files->name, 128), $val->tooBig) | 
						|
			) !== false | 
						|
		); | 
						|
		// to Small | 
						|
		$m = $this->createModelForAttributeTest(); | 
						|
		$val = new FileValidator(array('minSize' => 2048)); | 
						|
		$val->validateAttribute($m, 'attr_files'); | 
						|
		$this->assertTrue($m->hasErrors('attr_files')); | 
						|
		$this->assertTrue( | 
						|
			stripos( | 
						|
				current($m->getErrors('attr_files')), | 
						|
				str_ireplace(array('{file}', '{limit}'), array($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( | 
						|
					array('{file}', '{limit}'), | 
						|
					array($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'))); | 
						|
		$log = Yii::$app->getLog()->toArray(); | 
						|
		$this->assertSame(FileValidator::className() . '::validateFile', $log['messages'][0][2]); | 
						|
	} | 
						|
 | 
						|
	public function testValidateAttributeType() | 
						|
	{ | 
						|
		$val = new FileValidator(array('types' => 'jpeg, jpg')); | 
						|
		$m = FakedValidationModel::createWithAttributes( | 
						|
			array( | 
						|
				'attr_jpg' => $this->createTestFiles(array(array('name' => 'one.jpeg'))), | 
						|
				'attr_exe' => $this->createTestFiles(array(array('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( | 
						|
			array( | 
						|
				'attr_files' => $this->createTestFiles( | 
						|
					array( | 
						|
						array('name' => 'abc.jpg', 'size' => 1024, 'type' => 'image/jpeg'), | 
						|
					) | 
						|
				), | 
						|
				'attr_files_empty' => $this->createTestFiles(array(array())), | 
						|
				'attr_err_ini' => $this->createTestFiles(array(array('error' => UPLOAD_ERR_INI_SIZE))), | 
						|
				'attr_err_part' => $this->createTestFiles(array(array('error' => UPLOAD_ERR_PARTIAL))), | 
						|
				'attr_err_tmp' => $this->createTestFiles(array(array('error' => UPLOAD_ERR_NO_TMP_DIR))), | 
						|
				'attr_err_write' => $this->createTestFiles(array(array('error' => UPLOAD_ERR_CANT_WRITE))), | 
						|
				'attr_err_ext' => $this->createTestFiles(array(array('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(); | 
						|
		$this->assertSame(FileValidator::className() . '::validateFile', $log['messages'][0][2]); | 
						|
		$this->assertContains('File was only', $log['messages'][0][0]); | 
						|
	} | 
						|
 | 
						|
	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(); | 
						|
		$this->assertSame(FileValidator::className() . '::validateFile', $log['messages'][0][2]); | 
						|
		$this->assertContains('Failed to write', $log['messages'][0][0]); | 
						|
	} | 
						|
 | 
						|
	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(); | 
						|
		$this->assertSame(FileValidator::className() . '::validateFile', $log['messages'][0][2]); | 
						|
		$this->assertContains('PHP extension', $log['messages'][0][0]); | 
						|
	} | 
						|
 | 
						|
	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(); | 
						|
		$this->assertSame(FileValidator::className() . '::validateFile', $log['messages'][0][2]); | 
						|
		$this->assertContains('Missing the temporary folder', $log['messages'][0][0]); | 
						|
	} | 
						|
} |