diff --git a/composer.json b/composer.json index 1373aa2..28b7243 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,9 @@ "symfony/http-kernel": "^4.4", "symfony/config": "^4.4", "symfony/yaml": "^4.4", - "symfony/dependency-injection": "^4.4" + "symfony/dependency-injection": "^4.4", + "doctrine/orm": "^2.9", + "doctrine/doctrine-bundle": "^2.4" }, "require-dev": { "squizlabs/php_codesniffer": "^3.6", @@ -26,7 +28,12 @@ "phpstan/phpstan": "^0.12.90", "phpunit/phpunit": "^9.5", "phpstan/phpstan-symfony": "^0.12.37", - "symfony/framework-bundle": "^4.4" + "symfony/framework-bundle": "^4.4", + "phpstan/phpstan-doctrine": "^0.12.39", + "dama/doctrine-test-bundle": "^6.6", + "liip/test-fixtures-bundle": "^1.11", + "theofidry/alice-data-fixtures": "^1.4", + "doctrine/doctrine-fixtures-bundle": "^3.4" }, "autoload": { "psr-4": { diff --git a/config/.gitkeep b/config/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..b83ad50 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,10 @@ +services: + smart_parameter.parameter_provider: + class: Smart\ParameterBundle\Provider\ParameterProvider + public: true + arguments: + - '@Doctrine\ORM\EntityManagerInterface' + + Smart\ParameterBundle\Provider\ParameterProvider: + public: false + alias: smart_parameter.parameter_provider diff --git a/phpstan.neon b/phpstan.neon index d7b3498..85140b7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,8 @@ includes: - vendor/phpstan/phpstan-symfony/extension.neon - vendor/phpstan/phpstan-symfony/rules.neon + - vendor/phpstan/phpstan-doctrine/extension.neon + - vendor/phpstan/phpstan-doctrine/rules.neon parameters: checkMissingIterableValueType: false diff --git a/phpunit.xml b/phpunit.xml index 99ad480..a01df4d 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -8,6 +8,7 @@ + @@ -22,4 +23,7 @@ ./src/SmartParameterBundle.php + + + diff --git a/src/DependencyInjection/SmartParameterExtension.php b/src/DependencyInjection/SmartParameterExtension.php index 6fe34b1..9381845 100644 --- a/src/DependencyInjection/SmartParameterExtension.php +++ b/src/DependencyInjection/SmartParameterExtension.php @@ -2,6 +2,8 @@ namespace Smart\ParameterBundle\DependencyInjection; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -19,5 +21,8 @@ class SmartParameterExtension extends Extension public function load(array $configs, ContainerBuilder $container) { $this->processConfiguration(new Configuration(), $configs); + + $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../../config')); + $loader->load('services.yaml'); } } diff --git a/src/Entity/Parameter.php b/src/Entity/Parameter.php new file mode 100644 index 0000000..3184bc0 --- /dev/null +++ b/src/Entity/Parameter.php @@ -0,0 +1,94 @@ + + * + * @ORM\Table(name="smart_parameter") + * @ORM\Entity(repositoryClass="Smart\ParameterBundle\Repository\ParameterRepository") + */ +class Parameter +{ + /** + * @ORM\Id + * @ORM\GeneratedValue(strategy="AUTO") + * @ORM\Column(name="id", type="integer") + */ + private int $id; + + /** + * @ORM\Column(name="code", type="string", nullable=false, unique=true) + */ + private string $code; + + /** + * @ORM\Column(name="value", type="text", nullable=false) + */ + private string $value; + + /** + * @ORM\Column(name="help", type="text", nullable=true) + */ + private ?string $help; + + public function __toString() + { + return (string) $this->getCode(); + } + + public function getId(): ?int + { + return $this->id; + } + + /** + * @return string + */ + public function getCode(): string + { + return $this->code; + } + + /** + * @param string $code + */ + public function setCode(string $code): void + { + $this->code = $code; + } + + /** + * @return string + */ + public function getValue(): string + { + return $this->value; + } + + /** + * @param string $value + */ + public function setValue(string $value): void + { + $this->value = $value; + } + + /** + * @return string|null + */ + public function getHelp(): ?string + { + return $this->help; + } + + /** + * @param string|null $help + */ + public function setHelp(?string $help): void + { + $this->help = $help; + } +} diff --git a/src/Provider/ParameterProvider.php b/src/Provider/ParameterProvider.php new file mode 100644 index 0000000..e29774d --- /dev/null +++ b/src/Provider/ParameterProvider.php @@ -0,0 +1,44 @@ + + */ +class ParameterProvider +{ + private EntityManagerInterface $entityManager; + + public function __construct(EntityManagerInterface $entityManager) + { + $this->entityManager = $entityManager; + } + + /** + * Get a Parameter instance + * + * @throws EntityNotFoundException + */ + public function get(string $code): Parameter + { + $parameter = $this->entityManager->getRepository(Parameter::class)->findOneBy(['code' => $code]); + + if ($parameter == null) { + throw new EntityNotFoundException("The parameter with code \"$code\" was not found."); + } + + return $parameter; + } + + /** + * Get a Parameter value + */ + public function getValue(string $code): string + { + return $this->get($code)->getValue(); + } +} diff --git a/src/Repository/ParameterRepository.php b/src/Repository/ParameterRepository.php new file mode 100644 index 0000000..956e070 --- /dev/null +++ b/src/Repository/ParameterRepository.php @@ -0,0 +1,16 @@ + + * + * @extends \Doctrine\ORM\EntityRepository + */ +class ParameterRepository extends EntityRepository +{ + +} diff --git a/tests/AbstractWebTestCase.php b/tests/AbstractWebTestCase.php new file mode 100644 index 0000000..68235d0 --- /dev/null +++ b/tests/AbstractWebTestCase.php @@ -0,0 +1,26 @@ + + */ +abstract class AbstractWebTestCase extends WebTestCase +{ + use FixturesTrait; + + public function setUp(): void + { + parent::setUp(); + + self::bootKernel(); + } + + protected function getFixtureDir(): string + { + return __DIR__ . '/fixtures'; + } +} diff --git a/tests/App/AppKernel.php b/tests/App/AppKernel.php deleted file mode 100644 index 3029069..0000000 --- a/tests/App/AppKernel.php +++ /dev/null @@ -1,26 +0,0 @@ - - */ -class AppKernel extends Kernel -{ - public function registerBundles() - { - return [ - new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), - new SmartParameterBundle(), - ]; - } - - public function registerContainerConfiguration(LoaderInterface $loader): void - { - $loader->load(__DIR__ . '/../fixtures/config/full.yml'); - } -} diff --git a/tests/App/AppKernelTest.php b/tests/App/AppKernelTest.php deleted file mode 100644 index 3f749e5..0000000 --- a/tests/App/AppKernelTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * vendor/bin/phpunit tests/App/AppKernelTest.php - */ -class AppKernelTest extends WebTestCase -{ - protected static function getKernelClass() - { - return AppKernel::class; - } - - public function testBootingKernel(): void - { - self::bootKernel(); - - $this->assertInstanceOf(KernelInterface::class, self::$kernel); - } -} diff --git a/tests/AppKernel.php b/tests/AppKernel.php new file mode 100644 index 0000000..c527260 --- /dev/null +++ b/tests/AppKernel.php @@ -0,0 +1,42 @@ + + */ +class AppKernel extends Kernel +{ + public function registerBundles() + { + return [ + new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new \Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), + new \Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(), + new \DAMA\DoctrineTestBundle\DAMADoctrineTestBundle(), + new \Liip\TestFixturesBundle\LiipTestFixturesBundle(), + new \Fidry\AliceDataFixtures\Bridge\Symfony\FidryAliceDataFixturesBundle(), + new \Nelmio\Alice\Bridge\Symfony\NelmioAliceBundle(), + new \Smart\ParameterBundle\SmartParameterBundle(), + ]; + } + + public function registerContainerConfiguration(LoaderInterface $loader): void + { + $loader->load(__DIR__ . '/config_test.yml'); + } + + // https://github.com/dmaicher/doctrine-test-bundle/blob/master/tests/Functional/app/AppKernel.php + protected function build(ContainerBuilder $container): void + { + // remove logger info + $container->register('logger', NullLogger::class); + } +} diff --git a/tests/DependencyInjection/DependencyInjectionTest.php b/tests/DependencyInjection/DependencyInjectionTest.php index d47b1c4..d405d7f 100644 --- a/tests/DependencyInjection/DependencyInjectionTest.php +++ b/tests/DependencyInjection/DependencyInjectionTest.php @@ -2,12 +2,13 @@ namespace Smart\ParameterBundle\Tests\DependencyInjection; +use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\TestCase; use Smart\ParameterBundle\SmartParameterBundle; use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\FileLoader; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; /** @@ -23,13 +24,7 @@ protected function setUp(): void { $bundle = new SmartParameterBundle(); $this->container = new ContainerBuilder(); - - $this->container->setParameter('kernel.debug', true); - $this->container->setParameter('kernel.bundles', [ - 'FrameworkBundle' => \Symfony\Bundle\FrameworkBundle\FrameworkBundle::class, - ]); - $this->container->setParameter('kernel.environment', 'test'); - + $this->container->setDefinition('Doctrine\ORM\EntityManagerInterface', new Definition(EntityManagerInterface::class)); $this->container->registerExtension($bundle->getContainerExtension()); $bundle->build($this->container); } diff --git a/tests/Provider/ParameterProviderTest.php b/tests/Provider/ParameterProviderTest.php new file mode 100644 index 0000000..804e24f --- /dev/null +++ b/tests/Provider/ParameterProviderTest.php @@ -0,0 +1,51 @@ + + * + * vendor/bin/phpunit tests/Provider/ParameterProviderTest.php + */ +class ParameterProviderTest extends AbstractWebTestCase +{ + private ?ParameterProvider $provider; + + public function setUp(): void + { + parent::setUp(); + + $this->provider = self::$container->get(ParameterProvider::class); + } + + public function testGetNotFoundException(): void + { + $this->expectException(EntityNotFoundException::class); + $this->expectExceptionMessage('The parameter with code "not_found" was not found.'); + + $this->loadFixtureFiles([]); + $this->provider->getValue("not_found"); + } + + public function testGetOk(): void + { + $this->loadFixtureFiles([$this->getFixtureDir() . "/Provider/ParameterProvider/parameter.yaml"]); + + $parameter = $this->provider->get('full_param'); + $this->assertSame("full_param", (string) $parameter); + $this->assertIsInt($parameter->getId()); + $this->assertSame("Expected Parameter Value", $parameter->getValue()); + $this->assertSame("Expected Parameter Help", $parameter->getHelp()); + } + + public function testGetValueOk(): void + { + $this->loadFixtureFiles([$this->getFixtureDir() . "/Provider/ParameterProvider/parameter.yaml"]); + + $this->assertSame("Text Value", $this->provider->getValue("minimal_param")); + } +} diff --git a/tests/config_test.yml b/tests/config_test.yml new file mode 100644 index 0000000..727bc5b --- /dev/null +++ b/tests/config_test.yml @@ -0,0 +1,36 @@ +framework: + test: true + secret: test + +doctrine: + dbal: + driver: pdo_sqlite + charset: UTF8 + path: "%kernel.cache_dir%/test.db" + orm: + auto_generate_proxy_classes: "%kernel.debug%" + auto_mapping: true + +smart_parameter: + parameters: + # Textual paramter + dummy_support_emails: + value: "support@example.com, technical-support@example.com" + help: "This parameter is used by the mailer for support recipients. Format : Separate email by comma." + # Number parameter + dummy_homepage_cache_duration: + value: 3600 + help: "This parameter is used by the backend to set the duration of cache applied to the Homepage. Set the duration in second." + +dama_doctrine_test: + enable_static_connection: true + enable_static_meta_data_cache: true + enable_static_query_cache: true + +fidry_alice_data_fixtures: + default_purge_mode: delete # default is "delete" but you can change it to "truncate" or "no_purge" + db_drivers: + doctrine_orm: true + doctrine_mongodb_odm: false + doctrine_phpcr_odm: false + eloquent_orm: false diff --git a/tests/fixtures/Provider/ParameterProvider/parameter.yaml b/tests/fixtures/Provider/ParameterProvider/parameter.yaml new file mode 100644 index 0000000..7561a49 --- /dev/null +++ b/tests/fixtures/Provider/ParameterProvider/parameter.yaml @@ -0,0 +1,9 @@ +Smart\ParameterBundle\Entity\Parameter: + minimal_param: + code: minimal_param + value: "Text Value" + + full_param: + code: full_param + value: "Expected Parameter Value" + help: "Expected Parameter Help" diff --git a/tests/fixtures/config/invalid_missing_parameter_value.yml b/tests/fixtures/config/invalid_missing_parameter_value.yml index c47846b..8bcab18 100644 --- a/tests/fixtures/config/invalid_missing_parameter_value.yml +++ b/tests/fixtures/config/invalid_missing_parameter_value.yml @@ -1,4 +1,4 @@ -# +# Fixture config with undefined parameter value smart_parameter: parameters: parameter_without_value: diff --git a/tests/fixtures/config/invalid_no_parameter_defined.yml b/tests/fixtures/config/invalid_no_parameter_defined.yml index d5bc9d2..e707cb6 100644 --- a/tests/fixtures/config/invalid_no_parameter_defined.yml +++ b/tests/fixtures/config/invalid_no_parameter_defined.yml @@ -1,3 +1,3 @@ -# +# Fixture config with empty parameters config smart_parameter: parameters: