feat: add CurrencyValidator
fix: add CurrencyValidator CurrencyValidator zarad
This commit is contained in:
parent
64a07b232a
commit
1437ce4558
6
.env.test
Normal file
6
.env.test
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# define your env variables for the test env here
|
||||||
|
KERNEL_CLASS='App\Kernel'
|
||||||
|
APP_SECRET='$ecretf0rt3st'
|
||||||
|
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||||
|
PANTHER_APP_ENV=panther
|
||||||
|
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
|
10
.gitignore
vendored
10
.gitignore
vendored
@ -20,3 +20,13 @@ phpstan.neon
|
|||||||
/public/assets/
|
/public/assets/
|
||||||
/assets/vendor
|
/assets/vendor
|
||||||
###< symfony/asset-mapper ###
|
###< symfony/asset-mapper ###
|
||||||
|
|
||||||
|
###> symfony/phpunit-bridge ###
|
||||||
|
.phpunit.result.cache
|
||||||
|
/phpunit.xml
|
||||||
|
###< symfony/phpunit-bridge ###
|
||||||
|
|
||||||
|
###> phpunit/phpunit ###
|
||||||
|
/phpunit.xml
|
||||||
|
.phpunit.result.cache
|
||||||
|
###< phpunit/phpunit ###
|
||||||
|
23
bin/phpunit
Executable file
23
bin/phpunit
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (!ini_get('date.timezone')) {
|
||||||
|
ini_set('date.timezone', 'UTC');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||||
|
if (PHP_VERSION_ID >= 80000) {
|
||||||
|
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
|
||||||
|
} else {
|
||||||
|
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||||
|
require PHPUNIT_COMPOSER_INSTALL;
|
||||||
|
PHPUnit\TextUI\Command::main();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||||
|
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
|
||||||
|
}
|
@ -87,6 +87,10 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.10",
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"phpunit/phpunit": "^9.5",
|
||||||
|
"symfony/browser-kit": "7.0.*",
|
||||||
|
"symfony/css-selector": "7.0.*",
|
||||||
|
"symfony/phpunit-bridge": "^7.0",
|
||||||
"symfony/stopwatch": "7.0.*",
|
"symfony/stopwatch": "7.0.*",
|
||||||
"symfony/web-profiler-bundle": "7.0.*"
|
"symfony/web-profiler-bundle": "7.0.*"
|
||||||
}
|
}
|
||||||
|
2084
composer.lock
generated
2084
composer.lock
generated
File diff suppressed because it is too large
Load Diff
38
phpunit.xml.dist
Normal file
38
phpunit.xml.dist
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
backupGlobals="false"
|
||||||
|
colors="true"
|
||||||
|
bootstrap="tests/bootstrap.php"
|
||||||
|
convertDeprecationsToExceptions="false"
|
||||||
|
>
|
||||||
|
<php>
|
||||||
|
<ini name="display_errors" value="1" />
|
||||||
|
<ini name="error_reporting" value="-1" />
|
||||||
|
<server name="APP_ENV" value="test" force="true" />
|
||||||
|
<server name="SHELL_VERBOSITY" value="-1" />
|
||||||
|
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
|
||||||
|
<server name="SYMFONY_PHPUNIT_VERSION" value="9.6" />
|
||||||
|
</php>
|
||||||
|
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Project Test Suite">
|
||||||
|
<directory>tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
|
||||||
|
<coverage processUncoveredFiles="true">
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">src</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
|
||||||
|
<listeners>
|
||||||
|
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
||||||
|
</listeners>
|
||||||
|
|
||||||
|
<extensions>
|
||||||
|
</extensions>
|
||||||
|
</phpunit>
|
@ -3,7 +3,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Entity\QRCode;
|
namespace App\Entity\QRCode;
|
||||||
|
|
||||||
use App\Service\CurrencyListerInterface;
|
use App\Validator\Currency;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,6 +19,7 @@ class QRCodeMoney
|
|||||||
|
|
||||||
// TODO: getCurrencies validation
|
// TODO: getCurrencies validation
|
||||||
#[Assert\NotBlank(message: 'messages.fill_value')]
|
#[Assert\NotBlank(message: 'messages.fill_value')]
|
||||||
|
#[Currency(message: 'messages.not_currency')]
|
||||||
private ?string $currency;
|
private ?string $currency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
31
src/Validator/Currency.php
Normal file
31
src/Validator/Currency.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Validator;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||||
|
class Currency extends Constraint
|
||||||
|
{
|
||||||
|
public const NOT_CURRENCY_ERROR = '548618e7-95ba-473d-9101-cabd45e49115';
|
||||||
|
|
||||||
|
protected const ERROR_NAMES = [
|
||||||
|
self::NOT_CURRENCY_ERROR => 'NOT_CURRENCY_ERROR',
|
||||||
|
];
|
||||||
|
|
||||||
|
public string $message = 'This value should be currency.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed|null $options
|
||||||
|
* @param string|null $message
|
||||||
|
* @param array<string>|null $groups
|
||||||
|
* @param mixed|null $payload
|
||||||
|
*/
|
||||||
|
public function __construct(mixed $options = null, string $message = null, array $groups = null, mixed $payload = null)
|
||||||
|
{
|
||||||
|
parent::__construct($options ?? [], $groups, $payload);
|
||||||
|
|
||||||
|
$this->message = $message ?? $this->message;
|
||||||
|
}
|
||||||
|
}
|
38
src/Validator/CurrencyValidator.php
Normal file
38
src/Validator/CurrencyValidator.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Validator;
|
||||||
|
|
||||||
|
use App\Service\CurrencyListerInterface;
|
||||||
|
use Symfony\Component\Validator\Constraint;
|
||||||
|
use Symfony\Component\Validator\ConstraintValidator;
|
||||||
|
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||||
|
use Symfony\Component\Validator\Exception\UnexpectedValueException;
|
||||||
|
|
||||||
|
class CurrencyValidator extends ConstraintValidator {
|
||||||
|
public function __construct(private readonly CurrencyListerInterface $currencyLister) {}
|
||||||
|
public function validate(mixed $value, Constraint $constraint): void
|
||||||
|
{
|
||||||
|
if (!$constraint instanceof Currency) {
|
||||||
|
throw new UnexpectedTypeException($constraint, Currency::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $value || '' === $value) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($value) === false) {
|
||||||
|
throw new UnexpectedValueException($value, "string");
|
||||||
|
}
|
||||||
|
|
||||||
|
$availCurrencies = iterator_to_array($this->currencyLister->getCurrencies());
|
||||||
|
|
||||||
|
if (in_array($value, $availCurrencies, true)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->context->buildViolation($constraint->message)
|
||||||
|
->setParameter('{{ string }}', $value)
|
||||||
|
->addViolation();
|
||||||
|
}
|
||||||
|
}
|
29
symfony.lock
29
symfony.lock
@ -35,6 +35,20 @@
|
|||||||
"phpstan.dist.neon"
|
"phpstan.dist.neon"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"phpunit/phpunit": {
|
||||||
|
"version": "9.6",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "9.6",
|
||||||
|
"ref": "7364a21d87e658eb363c5020c072ecfdc12e2326"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
".env.test",
|
||||||
|
"phpunit.xml.dist",
|
||||||
|
"tests/bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/asset-mapper": {
|
"symfony/asset-mapper": {
|
||||||
"version": "7.0",
|
"version": "7.0",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
@ -93,6 +107,21 @@
|
|||||||
"src/Kernel.php"
|
"src/Kernel.php"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/phpunit-bridge": {
|
||||||
|
"version": "7.0",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "6.3",
|
||||||
|
"ref": "1f5830c331065b6e4c9d5fa2105e322d29fcd573"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
".env.test",
|
||||||
|
"bin/phpunit",
|
||||||
|
"phpunit.xml.dist",
|
||||||
|
"tests/bootstrap.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/routing": {
|
"symfony/routing": {
|
||||||
"version": "7.0",
|
"version": "7.0",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
33
tests/Validator/CurrencyValidatorTest.php
Normal file
33
tests/Validator/CurrencyValidatorTest.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\Validator;
|
||||||
|
|
||||||
|
use App\Service\CurrencyListerInterface;
|
||||||
|
use App\Validator\Currency;
|
||||||
|
use App\Validator\CurrencyValidator;
|
||||||
|
|
||||||
|
class CurrencyValidatorTest extends ValidatorTestCase
|
||||||
|
{
|
||||||
|
public function testSuccess(): void {
|
||||||
|
$currencyValidator = $this->createCurrencyValidator();
|
||||||
|
$currencyValidator->initialize($this->createExecutionContext(false));
|
||||||
|
|
||||||
|
$currencyValidator->validate('USD', new Currency(['message' => 'foo']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testFailure(): void {
|
||||||
|
$currencyValidator = $this->createCurrencyValidator();
|
||||||
|
$currencyValidator->initialize($this->createExecutionContext(true));
|
||||||
|
$currencyValidator->validate('EUR', new Currency(['message' => 'foo']));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createCurrencyValidator(): CurrencyValidator {
|
||||||
|
$mock = $this->createMock(CurrencyListerInterface::class);
|
||||||
|
$mock->expects($this->once())
|
||||||
|
->method('getCurrencies')
|
||||||
|
->will($this->returnValue(['USD', 'CZK']));
|
||||||
|
|
||||||
|
return new CurrencyValidator($mock);
|
||||||
|
}
|
||||||
|
}
|
19
tests/Validator/ValidatorTestCase.php
Normal file
19
tests/Validator/ValidatorTestCase.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Validator;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||||
|
|
||||||
|
abstract class ValidatorTestCase extends TestCase
|
||||||
|
{
|
||||||
|
protected function createExecutionContext(bool $violation): ExecutionContextInterface {
|
||||||
|
$expected = $violation ? $this->once() : $this->never();
|
||||||
|
|
||||||
|
$context = $this->createMock(ExecutionContextInterface::class);
|
||||||
|
$context->expects($expected)
|
||||||
|
->method('buildViolation');
|
||||||
|
|
||||||
|
return $context;
|
||||||
|
}
|
||||||
|
}
|
15
tests/bootstrap.php
Normal file
15
tests/bootstrap.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\Dotenv\Dotenv;
|
||||||
|
|
||||||
|
require dirname(__DIR__).'/vendor/autoload.php';
|
||||||
|
|
||||||
|
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
|
||||||
|
require dirname(__DIR__).'/config/bootstrap.php';
|
||||||
|
} elseif (method_exists(Dotenv::class, 'bootEnv')) {
|
||||||
|
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['APP_DEBUG']) {
|
||||||
|
umask(0000);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user