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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user