Apply contribution guidelines to "Mimetype" rule

This commit will also replace the usage of "mime" to "MIME" since it is
an acronym.

Co-authored-by: Henrique Moody <henriquemoody@gmail.com>
This commit is contained in:
Danilo Correa 2018-09-16 04:47:16 -03:00 committed by Henrique Moody
parent fd13b03d18
commit e2e9197f29
No known key found for this signature in database
GPG key ID: 221E9281655813A6
5 changed files with 101 additions and 84 deletions

View file

@ -2,7 +2,7 @@
- `Mimetype(string $mimetype)`
Validates if the file mimetype matches the expected one:
Validates if the input is a file and if its MIME type matches the expected one.
```php
v::mimetype('image/png')->validate('image.png'); // true

View file

@ -16,19 +16,20 @@ namespace Respect\Validation\Exceptions;
/**
* Exception class for Mimetype rule.
*
* @author Danilo Correa <danilosilva87@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
class MimetypeException extends ValidationException
final class MimetypeException extends ValidationException
{
/**
* @var array
* {@inheritdoc}
*/
public static $defaultTemplates = [
self::MODE_DEFAULT => [
self::STANDARD => '{{name}} must have {{mimetype}} mimetype',
self::STANDARD => '{{name}} must have {{mimetype}} MIME type',
],
self::MODE_NEGATIVE => [
self::STANDARD => '{{name}} must not have {{mimetype}} mimetype',
self::STANDARD => '{{name}} must not have {{mimetype}} MIME type',
],
];
}

View file

@ -15,18 +15,22 @@ namespace Respect\Validation\Rules;
use finfo;
use SplFileInfo;
use const FILEINFO_MIME_TYPE;
use function is_file;
use function is_string;
/**
* Validate file mimetypes.
* Validates if the input is a file and if its MIME type matches the expected one.
*
* @author Danilo Correa <danilosilva87@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
class Mimetype extends AbstractRule
final class Mimetype extends AbstractRule
{
/**
* @var string
*/
public $mimetype;
private $mimetype;
/**
* @var finfo
@ -34,13 +38,15 @@ class Mimetype extends AbstractRule
private $fileInfo;
/**
* Initializes the rule by defining the expected mimetype from the input.
*
* @param string $mimetype
* @param finfo $fileInfo
* @param finfo $fileInfo
*/
public function __construct($mimetype, finfo $fileInfo = null)
public function __construct(string $mimetype, finfo $fileInfo = null)
{
$this->mimetype = $mimetype;
$this->fileInfo = $fileInfo ?: new finfo(FILEINFO_MIME_TYPE);
$this->fileInfo = $fileInfo ?: new finfo();
}
/**
@ -49,7 +55,7 @@ class Mimetype extends AbstractRule
public function validate($input): bool
{
if ($input instanceof SplFileInfo) {
$input = $input->getPathname();
return $this->validate($input->getPathname());
}
if (!is_string($input)) {
@ -60,6 +66,6 @@ class Mimetype extends AbstractRule
return false;
}
return $this->fileInfo->file($input) == $this->mimetype;
return $this->mimetype === $this->fileInfo->file($input, FILEINFO_MIME_TYPE);
}
}

View file

@ -0,0 +1,37 @@
--FILE--
<?php
require 'vendor/autoload.php';
use Respect\Validation\Exceptions\MimetypeException;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Validator as v;
try {
v::mimetype('image/png')->check('image.png');
} catch (MimetypeException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::not(v::mimetype('image/png'))->check('tests/fixtures/valid-image.png');
} catch (MimetypeException $exception) {
echo $exception->getMessage().PHP_EOL;
}
try {
v::mimetype('image/png')->assert('tests/fixtures/invalid-image.png');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
try {
v::not(v::mimetype('image/png'))->assert('tests/fixtures/valid-image.png');
} catch (NestedValidationException $exception) {
echo $exception->getFullMessage().PHP_EOL;
}
?>
--EXPECTF--
"image.png" must have "image/png" MIME type
"tests/fixtures/valid-image.png" must not have "image/png" MIME type
- "tests/fixtures/invalid-image.png" must have "image/png" MIME type
- "tests/fixtures/valid-image.png" must not have "image/png" MIME type

View file

@ -13,40 +13,37 @@ declare(strict_types=1);
namespace Respect\Validation\Rules;
use PHPUnit\Framework\TestCase;
use finfo;
use Respect\Validation\Test\RuleTestCase;
use SplFileInfo;
use SplFileObject;
use const FILEINFO_MIME_TYPE;
use const PHP_INT_MAX;
use function random_int;
use function tmpfile;
/**
* @author Henrique Moody <henriquemoody@gmail.com>
* @group rule
* @covers \Respect\Validation\Exceptions\MimetypeException
* @group rule
*
* @covers \Respect\Validation\Rules\Mimetype
*
* @author Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
* @author Danilo Correa <danilosilva87@gmail.com>
* @author Gabriel Caruso <carusogabriel34@gmail.com>
* @author Henrique Moody <henriquemoody@gmail.com>
*/
class MimetypeTest extends TestCase
final class MimetypeTest extends RuleTestCase
{
private $filename;
protected function setUp(): void
{
$this->filename = sprintf('%s/validation.txt', sys_get_temp_dir());
file_put_contents($this->filename, 'File content');
}
protected function tearDown(): void
{
unlink($this->filename);
}
/**
* @test
*/
public function shouldValidateMimetype(): void
public function itShouldValidateWithDefinedFinfoInstance(): void
{
$mimetype = 'plain/text';
$mimetype = 'application/octet-stream';
$filename = $this->getFixtureDirectory().'/valid-image.png';
$fileInfoMock = $this
->getMockBuilder('finfo')
->getMockBuilder(finfo::class)
->disableOriginalConstructor()
->setMethods(['file'])
->getMock();
@ -54,68 +51,44 @@ class MimetypeTest extends TestCase
$fileInfoMock
->expects(self::once())
->method('file')
->with($this->filename)
->with($filename, FILEINFO_MIME_TYPE)
->will(self::returnValue($mimetype));
$rule = new Mimetype($mimetype, $fileInfoMock);
$rule->validate($this->filename);
self::assertTrue($rule->validate($filename));
}
/**
* @test
* {@inheritdoc}
*/
public function shouldValidateSplFileInfoMimetype(): void
public function providerForValidInput(): array
{
$fileInfo = new SplFileInfo($this->filename);
$mimetype = 'plain/text';
$fileInfoMock = $this
->getMockBuilder('finfo')
->disableOriginalConstructor()
->setMethods(['file'])
->getMock();
$fileInfoMock
->expects(self::once())
->method('file')
->with($fileInfo->getPathname())
->will(self::returnValue($mimetype));
$rule = new Mimetype($mimetype, $fileInfoMock);
self::assertTrue($rule->validate($fileInfo));
return [
'image/png' => [new Mimetype('image/png'), $this->getFixtureDirectory().'/valid-image.png'],
'image/gif' => [new Mimetype('image/gif'), $this->getFixtureDirectory().'/valid-image.gif'],
'image/jpeg' => [new Mimetype('image/jpeg'), $this->getFixtureDirectory().'/valid-image.jpg'],
'text/plain' => [new Mimetype('text/plain'), $this->getFixtureDirectory().'/executable'],
'SplFileInfo' => [new Mimetype('image/png'), new SplFileInfo($this->getFixtureDirectory().'/valid-image.png')],
'SplFileObject' => [new Mimetype('image/png'), new SplFileObject($this->getFixtureDirectory().'/valid-image.png')],
];
}
/**
* @test
* {@inheritdoc}
*/
public function shouldInvalidateWhenNotStringNorSplFileInfo(): void
public function providerForInvalidInput(): array
{
$rule = new Mimetype('application/octet-stream');
self::assertFalse($rule->validate([__FILE__]));
}
/**
* @test
*/
public function shouldInvalidateWhenItIsNotAValidFile(): void
{
$rule = new Mimetype('application/octet-stream');
self::assertFalse($rule->validate(__DIR__));
}
/**
* @expectedException \Respect\Validation\Exceptions\MimetypeException
* @expectedExceptionMessageRegExp #".+MimetypeTest.php" must have "application.?/json" mimetype#
*
* @test
*/
public function shouldThrowMimetypeExceptionWhenCheckingValue(): void
{
$rule = new Mimetype('application/json');
$rule->check(__FILE__);
return [
'invalid file' => [new Mimetype('image/png'), $this->getFixtureDirectory().'/invalid-image.png'],
'mismatch' => [new Mimetype('image/gif'), $this->getFixtureDirectory().'/valid-image.png'],
'directory' => [new Mimetype('application/octet-stream'), __DIR__],
'boolean' => [new Mimetype('application/octet-stream'), true],
'array' => [new Mimetype('application/octet-stream'), [__FILE__]],
'integer' => [new Mimetype('application/octet-stream'), random_int(1, PHP_INT_MAX)],
'float' => [new Mimetype('application/octet-stream'), random_int(1, 9) / 10],
'null' => [new Mimetype('application/octet-stream'), null],
'resource' => [new Mimetype('application/octet-stream'), tmpfile()],
];
}
}