diff --git a/.gitignore b/.gitignore index 2ebb444..65bc83a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .idea/ build/ vendor/ +tests/uploads/ +tests/data/db.sqlite \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8ab62f5..73675e2 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -10,7 +10,7 @@ processIsolation="false" stopOnFailure="false"> - + ./tests diff --git a/src/Module.php b/src/Module.php index ef88073..2b73481 100644 --- a/src/Module.php +++ b/src/Module.php @@ -4,6 +4,7 @@ use nemmo\attachments\models\File; use yii\base\Exception; +use yii\helpers\ArrayHelper; use yii\helpers\FileHelper; use yii\i18n\PhpMessageSource; @@ -27,7 +28,7 @@ public function init() throw new Exception('Setup {storePath} and {tempPath} in module properties'); } - $this->rules = array_replace(['maxFiles' => 3], $this->rules); + $this->rules = ArrayHelper::merge(['maxFiles' => 3], $this->rules); $this->defaultRoute = 'file'; $this->registerTranslations(); } diff --git a/src/controllers/FileController.php b/src/controllers/FileController.php index d049a20..39dd6eb 100644 --- a/src/controllers/FileController.php +++ b/src/controllers/FileController.php @@ -5,9 +5,11 @@ use nemmo\attachments\models\File; use nemmo\attachments\models\UploadForm; use nemmo\attachments\ModuleTrait; +use Yii; use yii\helpers\FileHelper; use yii\helpers\Url; use yii\web\Controller; +use yii\web\Response; use yii\web\UploadedFile; class FileController extends Controller @@ -19,8 +21,8 @@ public function actionUpload() $model = new UploadForm(); $model->file = UploadedFile::getInstances($model, 'file'); - if ($model->rules()[0]['maxFiles'] == 1) { - $model->file = UploadedFile::getInstances($model, 'file')[0]; + if ($model->rules()[0]['maxFiles'] == 1 && sizeof($model->file) == 1) { + $model->file = $model->file[0]; } if ($model->file && $model->validate()) { @@ -34,12 +36,15 @@ public function actionUpload() } else { $path = $this->getModule()->getUserDirPath() . DIRECTORY_SEPARATOR . $model->file->name; $model->file->saveAs($path); + $result['uploadedFiles'][] = $model->file->name; } - return json_encode($result); + Yii::$app->response->format = Response::FORMAT_JSON; + return $result; } else { - return json_encode([ + Yii::$app->response->format = Response::FORMAT_JSON; + return [ 'error' => $model->getErrors('file') - ]); + ]; } } @@ -48,14 +53,14 @@ public function actionDownload($id) $file = File::findOne(['id' => $id]); $filePath = $this->getModule()->getFilesDirPath($file->hash) . DIRECTORY_SEPARATOR . $file->hash . '.' . $file->type; - return \Yii::$app->response->sendFile($filePath, "$file->name.$file->type"); + return Yii::$app->response->sendFile($filePath, "$file->name.$file->type"); } public function actionDelete($id) { $this->getModule()->detachFile($id); - if (\Yii::$app->request->isAjax) { + if (Yii::$app->request->isAjax) { return json_encode([]); } else { return $this->redirect(Url::previous()); @@ -66,7 +71,7 @@ public function actionDownloadTemp($filename) { $filePath = $this->getModule()->getUserDirPath() . DIRECTORY_SEPARATOR . $filename; - return \Yii::$app->response->sendFile($filePath, $filename); + return Yii::$app->response->sendFile($filePath, $filename); } public function actionDeleteTemp($filename) @@ -78,7 +83,7 @@ public function actionDeleteTemp($filename) rmdir($userTempDir); } - if (\Yii::$app->request->isAjax) { + if (Yii::$app->request->isAjax) { return json_encode([]); } else { return $this->redirect(Url::previous()); diff --git a/src/models/UploadForm.php b/src/models/UploadForm.php index 79d5437..64dffcf 100644 --- a/src/models/UploadForm.php +++ b/src/models/UploadForm.php @@ -4,6 +4,7 @@ use nemmo\attachments\ModuleTrait; use yii\base\Model; +use yii\helpers\ArrayHelper; use yii\web\UploadedFile; /** @@ -17,7 +18,7 @@ class UploadForm extends Model use ModuleTrait; /** - * @var UploadedFile|Null file attribute + * @var UploadedFile[]|UploadedFile file attribute */ public $file; @@ -27,7 +28,7 @@ class UploadForm extends Model public function rules() { return [ - array_replace([['file'], 'file'], $this->getModule()->rules) + ArrayHelper::merge(['file', 'file'], $this->getModule()->rules) ]; } } \ No newline at end of file diff --git a/tests/FileControllerTest.php b/tests/FileControllerTest.php new file mode 100644 index 0000000..77b76bb --- /dev/null +++ b/tests/FileControllerTest.php @@ -0,0 +1,117 @@ +generateFiles($types); + $output = Yii::$app->runAction('attachments/file/upload'); + $this->assertArrayHasKey('uploadedFiles', $output); + $this->assertTrue(in_array('file.png', $output['uploadedFiles'])); + $this->checkFilesExist($types); + } + + public function testUpload2() + { + $types = ['png', 'txt', 'jpg', 'zip']; + $this->generateFiles($types); + $output = Yii::$app->runAction('attachments/file/upload'); + $this->assertArrayHasKey('error', $output); + } + + public function testUpload3() + { + Yii::$app->setModule('attachments', [ + 'class' => Module::className(), + 'rules' => [ + 'maxFiles' => 1 + ] + ]); + $types = ['png', 'zip']; + $this->generateFiles($types); + $output = Yii::$app->runAction('attachments/file/upload'); + $this->assertArrayHasKey('error', $output); + } + + public function testUpload4() + { + Yii::$app->setModule('attachments', [ + 'class' => Module::className(), + 'rules' => [ + 'maxFiles' => 1 + ] + ]); + $types = ['png']; + $this->generateFiles($types); + $output = Yii::$app->runAction('attachments/file/upload'); + $this->assertArrayHasKey('uploadedFiles', $output); + $this->assertTrue(in_array('file.png', $output['uploadedFiles'])); + $this->checkFilesExist($types); + } + + public function testUpload5() + { + Yii::$app->setModule('attachments', [ + 'class' => Module::className(), + 'rules' => [ + 'maxFiles' => 3, + 'mimeTypes' => ['image/png', 'image/jpeg'] + ] + ]); + $types = ['png', 'jpg', 'zip']; + $this->generateFiles($types); + $output = Yii::$app->runAction('attachments/file/upload'); + var_dump($output); + $this->assertArrayHasKey('error', $output); + } + + public function generateFiles($types) + { + $_FILES = []; + foreach ($types as $index => $type) { + $file = "file.$type"; + $path = Yii::getAlias("@tests/files/$file"); + $_FILES["UploadForm[file][$index]"] = [ + 'name' => $file, + 'type' => mime_content_type($path), + 'size' => filesize($path), + 'tmp_name' => $path, + 'error' => 0 + ]; + } + } + + public function checkFilesExist($types) + { + foreach ($types as $type) { + $filePath = Yii::getAlias('@tests/uploads/temp/' . Yii::$app->session->id . '/file.' . $type); + $this->assertTrue(file_exists($filePath)); + } + } +} diff --git a/tests/ModuleTest.php b/tests/ModuleTest.php index a1214df..6e8047f 100644 --- a/tests/ModuleTest.php +++ b/tests/ModuleTest.php @@ -37,7 +37,9 @@ public function testInitException() public function testInit() { - Yii::$app->language = 'ru'; + Yii::$app->setModule('attachments', [ + 'class' => Module::className() + ]); /** @var Module $module */ $module = Yii::$app->getModule('attachments'); $this->assertEquals([ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index fde655e..815dc81 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -6,10 +6,13 @@ * Time: 9:46 PM */ -namespace tests; +namespace yii\web; use Yii; +/** + * Turn on all error reports + */ error_reporting(E_ALL | E_STRICT); defined('YII_DEBUG') or define('YII_DEBUG', true); @@ -20,7 +23,9 @@ Yii::setAlias('@tests', __DIR__); -// Overwrite +/** + * Overwrite functions for fake uploads + */ function is_uploaded_file($filename) { return file_exists($filename); @@ -31,10 +36,13 @@ function move_uploaded_file($filename, $destination) return copy($filename, $destination); } +/** + * Run yii web application + */ new \yii\web\Application([ 'id' => 'unit', - 'basePath' => __DIR__, - 'vendorPath' => __DIR__ . '/../vendor', + 'basePath' => Yii::getAlias('@tests'), + 'vendorPath' => Yii::getAlias('@tests/../vendor'), 'modules' => [ 'attachments' => [ 'class' => \nemmo\attachments\Module::className(), @@ -48,7 +56,7 @@ function move_uploaded_file($filename, $destination) ], 'db' => [ 'class' => \yii\db\Connection::className(), - 'dsn' => 'sqlite:' . __DIR__ . '/data/db.sqlite' + 'dsn' => 'sqlite:' . Yii::getAlias('@tests/data/db.sqlite') ] ] ]); \ No newline at end of file diff --git a/tests/files/file.bmp b/tests/files/file.bmp new file mode 100644 index 0000000..e148d13 Binary files /dev/null and b/tests/files/file.bmp differ diff --git a/tests/files/file.gif b/tests/files/file.gif new file mode 100644 index 0000000..c0ad10a Binary files /dev/null and b/tests/files/file.gif differ diff --git a/tests/files/file.jpg b/tests/files/file.jpg new file mode 100644 index 0000000..628ad97 Binary files /dev/null and b/tests/files/file.jpg differ diff --git a/tests/files/file.mp3 b/tests/files/file.mp3 new file mode 100644 index 0000000..ed6a42a Binary files /dev/null and b/tests/files/file.mp3 differ diff --git a/tests/files/yii.png b/tests/files/file.png similarity index 100% rename from tests/files/yii.png rename to tests/files/file.png diff --git a/tests/files/file.txt b/tests/files/file.txt new file mode 100644 index 0000000..6c8db5d --- /dev/null +++ b/tests/files/file.txt @@ -0,0 +1 @@ +file 1 \ No newline at end of file diff --git a/tests/files/file.wav b/tests/files/file.wav new file mode 100644 index 0000000..f224049 Binary files /dev/null and b/tests/files/file.wav differ diff --git a/tests/files/file.zip b/tests/files/file.zip new file mode 100644 index 0000000..693c6ca Binary files /dev/null and b/tests/files/file.zip differ