Allow file-related rules to validate PSR-7 interfaces

The PSR-7 has two interfaces that allow us to validate them as files.
This commit will allow some rules to validate those interfaces.

Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
Signed-off-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
v0idpwn 2019-06-06 17:09:12 -03:00 committed by Henrique Moody
parent 029fa7fe73
commit ff253c78b3
No known key found for this signature in database
GPG key ID: 221E9281655813A6
13 changed files with 60 additions and 0 deletions

View file

@ -27,6 +27,7 @@
"phpstan/phpstan-deprecation-rules": "^0.12", "phpstan/phpstan-deprecation-rules": "^0.12",
"phpstan/phpstan-phpunit": "^0.12", "phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^9.3", "phpunit/phpunit": "^9.3",
"psr/http-message": "^1.0",
"respect/coding-standard": "^3.0", "respect/coding-standard": "^3.0",
"squizlabs/php_codesniffer": "^3.5", "squizlabs/php_codesniffer": "^3.5",
"symfony/validator": "^3.0||^4.0", "symfony/validator": "^3.0||^4.0",

View file

@ -16,6 +16,7 @@ v::readable()->validate('file.txt'); // true
Version | Description Version | Description
--------|------------- --------|-------------
2.1.0 | Add PSR-7 support
0.5.0 | Created 0.5.0 | Created
*** ***

View file

@ -40,6 +40,7 @@ Message template for this validator includes `{{minSize}}` and `{{maxSize}}`.
Version | Description Version | Description
--------|------------- --------|-------------
2.1.0 | Add PSR-7 support
1.0.0 | Created 1.0.0 | Created
*** ***

View file

@ -16,6 +16,7 @@ v::uploaded()->validate('/path/of/an/uploaded/file'); // true
Version | Description Version | Description
--------|------------- --------|-------------
2.1.0 | Add PSR-7 support
0.5.0 | Created 0.5.0 | Created
*** ***

View file

@ -16,6 +16,7 @@ v::writable()->validate('file.txt'); // true
Version | Description Version | Description
--------|------------- --------|-------------
2.1.0 | Add PSR-7 support
0.5.0 | Created 0.5.0 | Created
*** ***

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\StreamInterface;
use SplFileInfo; use SplFileInfo;
use function is_readable; use function is_readable;
@ -35,6 +36,10 @@ final class Readable extends AbstractRule
return $input->isReadable(); return $input->isReadable();
} }
if ($input instanceof StreamInterface) {
return $input->isReadable();
}
return is_string($input) && is_readable($input); return is_string($input) && is_readable($input);
} }
} }

View file

@ -13,6 +13,8 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UploadedFileInterface;
use Respect\Validation\Exceptions\ComponentException; use Respect\Validation\Exceptions\ComponentException;
use SplFileInfo; use SplFileInfo;
@ -27,6 +29,7 @@ use function sprintf;
* *
* @author Danilo Correa <danilosilva87@gmail.com> * @author Danilo Correa <danilosilva87@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com> * @author Henrique Moody <henriquemoody@gmail.com>
* @author Felipe Stival <v0idpwn@gmail.com>
*/ */
final class Size extends AbstractRule final class Size extends AbstractRule
{ {
@ -71,6 +74,14 @@ final class Size extends AbstractRule
return $this->isValidSize($input->getSize()); return $this->isValidSize($input->getSize());
} }
if ($input instanceof UploadedFileInterface) {
return $this->isValidSize($input->getSize());
}
if ($input instanceof StreamInterface) {
return $this->isValidSize($input->getSize());
}
if (is_string($input)) { if (is_string($input)) {
return $this->isValidSize((int) filesize($input)); return $this->isValidSize((int) filesize($input));
} }

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\UploadedFileInterface;
use SplFileInfo; use SplFileInfo;
use function is_scalar; use function is_scalar;
@ -35,6 +36,10 @@ final class Uploaded extends AbstractRule
return $this->validate($input->getPathname()); return $this->validate($input->getPathname());
} }
if ($input instanceof UploadedFileInterface) {
return true;
}
if (!is_scalar($input)) { if (!is_scalar($input)) {
return false; return false;
} }

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\StreamInterface;
use SplFileInfo; use SplFileInfo;
use function is_string; use function is_string;
@ -35,6 +36,10 @@ final class Writable extends AbstractRule
return $input->isWritable(); return $input->isWritable();
} }
if ($input instanceof StreamInterface) {
return $input->isWritable();
}
return is_string($input) && is_writable($input); return is_string($input) && is_writable($input);
} }
} }

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\StreamInterface;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
use SplFileInfo; use SplFileInfo;
use stdClass; use stdClass;
@ -38,6 +39,7 @@ final class ReadableTest extends RuleTestCase
return [ return [
[$rule, $file], [$rule, $file],
[$rule, new SplFileInfo($file)], [$rule, new SplFileInfo($file)],
[$rule, $this->createPsr7Stream(true)],
]; ];
} }
@ -53,6 +55,15 @@ final class ReadableTest extends RuleTestCase
[$rule, $file], [$rule, $file],
[$rule, new SplFileInfo($file)], [$rule, new SplFileInfo($file)],
[$rule, new stdClass()], [$rule, new stdClass()],
[$rule, $this->createPsr7Stream(false)],
]; ];
} }
private function createPsr7Stream(bool $isReadable): StreamInterface
{
$stream = $this->createMock(StreamInterface::class);
$stream->expects(self::any())->method('isReadable')->willReturn($isReadable);
return $stream;
}
} }

View file

@ -15,6 +15,7 @@ namespace Respect\Validation\Rules;
use org\bovigo\vfs\content\LargeFileContent; use org\bovigo\vfs\content\LargeFileContent;
use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStream;
use Psr\Http\Message\StreamInterface;
use Respect\Validation\Exceptions\ComponentException; use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
use SplFileInfo; use SplFileInfo;
@ -71,6 +72,9 @@ final class SizeTest extends RuleTestCase
->withContent(LargeFileContent::withMegabytes(2)) ->withContent(LargeFileContent::withMegabytes(2))
->at($root); ->at($root);
$psr7Stream1Mb = $this->createMock(StreamInterface::class);
$psr7Stream1Mb->expects(self::once())->method('getSize')->willReturn(1024);
return [ return [
'file with at least 3kb' => [new Size('3kb', null), $file2Kb->url()], 'file with at least 3kb' => [new Size('3kb', null), $file2Kb->url()],
'file with up to 1kb' => [new Size(null, '1kb'), $file2Kb->url()], 'file with up to 1kb' => [new Size(null, '1kb'), $file2Kb->url()],
@ -81,6 +85,7 @@ final class SizeTest extends RuleTestCase
'file between 1pb and 3pb' => [new Size('1pb', '3pb'), $file2Mb->url()], 'file between 1pb and 3pb' => [new Size('1pb', '3pb'), $file2Mb->url()],
'SplFileInfo instancia' => [new Size('1pb', '3pb'), new SplFileInfo($file2Mb->url())], 'SplFileInfo instancia' => [new Size('1pb', '3pb'), new SplFileInfo($file2Mb->url())],
'parameter invalid' => [new Size('1pb', '3pb'), []], 'parameter invalid' => [new Size('1pb', '3pb'), []],
'PSR-7 stream' => [new Size('1MB', '1.1MB'), $psr7Stream1Mb],
]; ];
} }

View file

@ -14,6 +14,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use PHPUnit\Framework\SkippedTestError; use PHPUnit\Framework\SkippedTestError;
use Psr\Http\Message\UploadedFileInterface;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
use SplFileInfo; use SplFileInfo;
use stdClass; use stdClass;
@ -44,6 +45,7 @@ final class UploadedTest extends RuleTestCase
return [ return [
[$rule, self::UPLOADED_FILENAME], [$rule, self::UPLOADED_FILENAME],
[$rule, new SplFileInfo(self::UPLOADED_FILENAME)], [$rule, new SplFileInfo(self::UPLOADED_FILENAME)],
[$rule, $this->createMock(UploadedFileInterface::class)],
]; ];
} }

View file

@ -13,6 +13,7 @@ declare(strict_types=1);
namespace Respect\Validation\Rules; namespace Respect\Validation\Rules;
use Psr\Http\Message\StreamInterface;
use Respect\Validation\Test\RuleTestCase; use Respect\Validation\Test\RuleTestCase;
use SplFileInfo; use SplFileInfo;
use SplFileObject; use SplFileObject;
@ -44,6 +45,7 @@ final class WritableTest extends RuleTestCase
'writable directory' => [$sut, $this->getFixtureDirectory()], 'writable directory' => [$sut, $this->getFixtureDirectory()],
'writable SplFileInfo file' => [$sut, new SplFileInfo($filename)], 'writable SplFileInfo file' => [$sut, new SplFileInfo($filename)],
'writable SplFileObject file' => [$sut, new SplFileObject($filename)], 'writable SplFileObject file' => [$sut, new SplFileObject($filename)],
'writable PSR-7 stream' => [$sut, $this->createPsr7Stream(true)],
]; ];
} }
@ -58,6 +60,7 @@ final class WritableTest extends RuleTestCase
$this->changeFileModeToUnwritable($filename); $this->changeFileModeToUnwritable($filename);
return [ return [
'unwritable PSR-7 stream' => [$rule, $this->createPsr7Stream(false)],
'unwritable filename' => [$rule, $filename], 'unwritable filename' => [$rule, $filename],
'unwritable SplFileInfo file' => [$rule, new SplFileInfo($filename)], 'unwritable SplFileInfo file' => [$rule, new SplFileInfo($filename)],
'unwritable SplFileObject file' => [$rule, new SplFileObject($filename)], 'unwritable SplFileObject file' => [$rule, new SplFileObject($filename)],
@ -72,6 +75,14 @@ final class WritableTest extends RuleTestCase
]; ];
} }
private function createPsr7Stream(bool $isWritable): StreamInterface
{
$stream = $this->createMock(StreamInterface::class);
$stream->expects(self::any())->method('isWritable')->willReturn($isWritable);
return $stream;
}
private function changeFileModeToUnwritable(string $filename): void private function changeFileModeToUnwritable(string $filename): void
{ {
chmod($filename, 0555); chmod($filename, 0555);