From 4e3477c4a0dadfcc37bfa9cd283fe5a361e7f4b7 Mon Sep 17 00:00:00 2001 From: Lio Novelli Date: Tue, 10 Jan 2023 10:42:36 +0100 Subject: [PATCH] Add entity type management system. --- app/composer.json | 9 +- app/composer.lock | 443 +++++++++++++++--- app/dependencies.php | 12 +- app/phpcs.xml | 5 +- app/rprt.php | 2 + app/src/Commands/AbstractCliCommand.php | 3 + .../TimeTrackingServices/EntityDefinition.php | 54 +++ .../TimeTrackingServices/EntityInterface.php | 14 + .../EntityManagerInterface.php | 27 ++ .../YoutrackInterface.php | 5 + .../YoutrackRestApi/EntityManager.php | 124 +++++ .../SimpleYoutrackEntityManager.php | 24 + .../YoutrackRestApi/YoutrackEntity.php | 14 + .../YoutrackEntityTypes/.#YoutrackEntity.php | 1 + .../YoutrackEntityTypes/YoutrackIssue.php | 42 ++ .../YoutrackEntityTypes/YoutrackProject.php | 19 + .../YoutrackEntityTypes/YoutrackWorkItem.php | 32 ++ .../YoutrackRestApiInterface.php | 37 ++ app/tests/Kernel/ReportCommandTest.php | 11 +- .../YoutrackRestApi/EntityManagerTest.php | 38 ++ app/tests/Unit/YoutrackRestApi/README.md | 4 + 21 files changed, 831 insertions(+), 89 deletions(-) create mode 100644 app/src/Utils/TimeTrackingServices/EntityDefinition.php create mode 100644 app/src/Utils/TimeTrackingServices/EntityInterface.php create mode 100644 app/src/Utils/TimeTrackingServices/EntityManagerInterface.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/EntityManager.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/SimpleYoutrackEntityManager.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntity.php create mode 120000 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntityTypes/.#YoutrackEntity.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntityTypes/YoutrackIssue.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntityTypes/YoutrackProject.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntityTypes/YoutrackWorkItem.php create mode 100644 app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackRestApiInterface.php create mode 100644 app/tests/Unit/YoutrackRestApi/EntityManagerTest.php create mode 100644 app/tests/Unit/YoutrackRestApi/README.md diff --git a/app/composer.json b/app/composer.json index 0e679bf..691e36b 100644 --- a/app/composer.json +++ b/app/composer.json @@ -15,12 +15,14 @@ ], "require": { "symfony/console": "^5.2", - "guzzlehttp/guzzle": "^7.3", + "guzzlehttp/guzzle": "^6.2", "php-di/php-di": "^6.3", "symfony/yaml": "^5.2", "mpdf/mpdf": "^8.0", "symfony/mailer": "^5.3", - "symfony/google-mailer": "^5.3" + "symfony/google-mailer": "^5.3", + "cybercog/youtrack-rest-php": "^7.0", + "symfony/finder": "^6.2" }, "autoload": { "psr-4": { @@ -32,7 +34,8 @@ "phpunit/phpunit": "^9.5", "opsway/psr12-strict-coding-standard": "^1.0", "phpcompatibility/php-compatibility": "^9.3", - "phpstan/phpstan": "^1.9" + "phpstan/phpstan": "^1.9", + "psy/psysh": "^0.11.10" }, "scripts": { "cs": "vendor/bin/phpcs --colors", diff --git a/app/composer.lock b/app/composer.lock index c8af7f2..e0233b0 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -4,8 +4,88 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dcf2d10608163dc9004a26e38e06a533", + "content-hash": "ca5a759d17cf48faeda14bdaab8f4985", "packages": [ + { + "name": "cybercog/youtrack-rest-php", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/cybercog/youtrack-rest-php.git", + "reference": "eb0315133d1d3d161da23d26537201afb253dec9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cybercog/youtrack-rest-php/zipball/eb0315133d1d3d161da23d26537201afb253dec9", + "reference": "eb0315133d1d3d161da23d26537201afb253dec9", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/guzzle": "^6.2", + "php": "^7.1|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^0.12.32", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "suggest": { + "cybercog/laravel-youtrack-sdk": "Laravel integration with PHP YouTrack SDK.", + "cybercog/youtrack-php-sdk": "PHP YouTrack SDK." + }, + "type": "library", + "autoload": { + "psr-4": { + "Cog\\YouTrack\\Rest\\": "src/", + "Cog\\Contracts\\YouTrack\\Rest\\": "contracts/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Komarev", + "email": "anton@komarev.com", + "homepage": "https://komarev.com", + "role": "Developer" + } + ], + "description": "YouTrack REST API PHP Client.", + "homepage": "https://komarev.com/sources/php-youtrack-rest", + "keywords": [ + "api", + "bugtracker", + "client", + "cog", + "cybercog", + "helpdesk", + "issues", + "jetbrains", + "laravel", + "pm", + "rest", + "tickets", + "youtrack", + "yt" + ], + "support": { + "docs": "https://github.com/cybercog/youtrack-rest-php/wiki", + "email": "open@cybercog.su", + "issues": "https://github.com/cybercog/youtrack-rest-php/issues", + "source": "https://github.com/cybercog/youtrack-rest-php", + "wiki": "https://github.com/cybercog/youtrack-rest-php/wiki" + }, + "funding": [ + { + "url": "https://paypal.me/antonkomarev", + "type": "custom" + } + ], + "time": "2022-10-02T18:52:01+00:00" + }, { "name": "doctrine/lexer", "version": "1.2.1", @@ -156,68 +236,86 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.3.0", + "version": "6.5.7", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "7008573787b430c1c1f650e3722d9bba59967628" + "reference": "724562fa861e21a4071c652c8a159934e4f05592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", - "reference": "7008573787b430c1c1f650e3722d9bba59967628", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/724562fa861e21a4071c652c8a159934e4f05592", + "reference": "724562fa861e21a4071c652c8a159934e4f05592", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.7 || ^2.0", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", "psr/log": "^1.1" }, "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.3-dev" + "dev-master": "6.5-dev" } }, "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], "description": "Guzzle is a PHP HTTP client library", @@ -228,12 +326,28 @@ "framework", "http", "http client", - "psr-18", - "psr-7", "rest", "web service" ], - "time": "2021-03-23T11:33:13+00:00" + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5.7" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-06-09T21:36:50+00:00" }, { "name": "guzzlehttp/promises", @@ -901,55 +1015,6 @@ }, "time": "2019-01-08T18:20:26+00:00" }, - { - "name": "psr/http-client", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], - "time": "2020-06-29T06:28:15+00:00" - }, { "name": "psr/http-message", "version": "1.0.1", @@ -1495,6 +1560,70 @@ ], "time": "2021-03-23T23:28:01+00:00" }, + { + "name": "symfony/finder", + "version": "v6.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/81eefbddfde282ee33b437ba5e13d7753211ae8e", + "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-22T17:55:15+00:00" + }, { "name": "symfony/google-mailer", "version": "v5.3.0", @@ -3777,6 +3906,82 @@ ], "time": "2022-04-01T12:37:26+00:00" }, + { + "name": "psy/psysh", + "version": "v0.11.10", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "e9eadffbed9c9deb5426fd107faae0452bf20a36" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/e9eadffbed9c9deb5426fd107faae0452bf20a36", + "reference": "e9eadffbed9c9deb5426fd107faae0452bf20a36", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.10" + }, + "time": "2022-12-23T17:47:18+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.1", @@ -4862,6 +5067,94 @@ }, "time": "2022-06-18T07:21:10+00:00" }, + { + "name": "symfony/var-dumper", + "version": "v6.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", + "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-12-22T17:55:15+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.1", diff --git a/app/dependencies.php b/app/dependencies.php index a01bc46..6d5e8c0 100644 --- a/app/dependencies.php +++ b/app/dependencies.php @@ -20,6 +20,8 @@ use RprtCli\Utils\PdfExport\PdfExportService; use RprtCli\Utils\TimeTrackingServices\YoutrackInterface; use RprtCli\Utils\TimeTrackingServices\YoutrackService; use Psr\Container\ContainerInterface; +use Symfony\Component\Finder\Finder; +use RprtCli\Utils\TimeTrackingServices\YoutrackRestApi\EntityManager; # use Symfony\Component\Translation\Translator; #use Symfony\Component\Translation\Loader\PoFileLoader; @@ -38,9 +40,9 @@ return [ 'mpdf' => factory(function (ContainerInterface $c) { return new Mpdf(['tempDir' => sys_get_temp_dir()]); }), - // 'mpdf' => function () { - // return new Mpdf(['tempDir' => sys_get_temp_dir()]); - // }, + 'finder' => factory(function (ContainerInterface $c) { + return new Finder(); + }), ConfigurationInterface::class => get(ConfigurationService::class), ConfigurationService::class => create()->constructor( get('config.path'), @@ -73,6 +75,10 @@ return [ get('pdf_export.service') ), 'mailer' => get(MailerInterface::class), + EntityManager::class => create()->constructor( + get('finder') + ), + 'youtrack.entity_manager' => get(EntityManager::class), InvoiceCommand::class => create()->constructor( get('csv.report'), get('config.service'), diff --git a/app/phpcs.xml b/app/phpcs.xml index 50e669d..1b6178d 100644 --- a/app/phpcs.xml +++ b/app/phpcs.xml @@ -16,9 +16,10 @@ src - + + - + diff --git a/app/rprt.php b/app/rprt.php index ec94230..c6cde93 100755 --- a/app/rprt.php +++ b/app/rprt.php @@ -9,6 +9,7 @@ use DI\ContainerBuilder; require __DIR__ . '/vendor/autoload.php'; $builder = new ContainerBuilder(); + $builder->addDefinitions(__DIR__ . '/dependencies.php'); $container = $builder->build(); @@ -19,4 +20,5 @@ $application->add($invoiceCommand); $reportCommand = $container->get(ReportCommand::class); $application->add($reportCommand); +// eval(\Psy\sh()); $application->run(); diff --git a/app/src/Commands/AbstractCliCommand.php b/app/src/Commands/AbstractCliCommand.php index c158467..00cbf4b 100644 --- a/app/src/Commands/AbstractCliCommand.php +++ b/app/src/Commands/AbstractCliCommand.php @@ -21,6 +21,9 @@ class AbstractCliCommand extends Command // @TODO Add service factory service. // protected $trackingServiceFactory; + /** + * Dependency inversion. + */ public function __construct( ConfigurationInterface $configuration, ?string $name = null diff --git a/app/src/Utils/TimeTrackingServices/EntityDefinition.php b/app/src/Utils/TimeTrackingServices/EntityDefinition.php new file mode 100644 index 0000000..7707e00 --- /dev/null +++ b/app/src/Utils/TimeTrackingServices/EntityDefinition.php @@ -0,0 +1,54 @@ +id; + } + + public function getProvider() { + return $this->provider; + } + + public function getName() { + return $this->name; + } + + public function getFields() { + return $this->fields; + } + + public function getFilters() { + return $this->filters; + } + + public function getDefinition() { + return [ + 'id' => $this->id, + 'provider' => $this->provider, + 'name' => $this->name, + 'fields' => $this->fields, + 'filters' => $this->filters, + ]; + } +} diff --git a/app/src/Utils/TimeTrackingServices/EntityInterface.php b/app/src/Utils/TimeTrackingServices/EntityInterface.php new file mode 100644 index 0000000..a0cec81 --- /dev/null +++ b/app/src/Utils/TimeTrackingServices/EntityInterface.php @@ -0,0 +1,14 @@ +finder = $finder; + } + + /** + * Attributes based discovery from EntityTypes folder. + */ + public function list() :array { + return $this->listEntityDefinitions(); + } + + /** + * Returns all the entity definitions. + */ + public function listEntityDefinitions() { + if (!$this->entityDefinitions) { + $this->discoverEntities(); + } + return $this->entityDefinitions; + } + + /** + * Discovers entity definitions. + */ + private function discoverEntities() { + if (!empty($this->entityDefinitions)) { + return $this->entityDefinitions; + } + $path = __DIR__ . '/' . self::ENTITIES_DIR; + $definitions = []; + // @todo create a proxy service for finder. + $this->finder->files()->in($path); + /** @var SplFileInfo $file */ + foreach ($this->finder as $file) { + $class = self::ENTITIES_NAMESPACE . '\\' . self::ENTITIES_DIR . '\\' . $file->getBasename('.php'); + $reflection = new \ReflectionClass($class); + $attribute = $this->getAttributeOfInstance($reflection, EntityDefinition::class); + // We expect a single attribute of this kind. + if (!$attribute) { + var_dump($file); + continue; + } + $instance = $attribute->newInstance(); + $id = $instance->getId(); + $content = $instance->getDefinition(); + $content['class'] = $class; + $definitions[$id] = $content; + } + $this->entityDefinitions = $definitions; + return $definitions; + } + + /** + * Returns an attribute of a given instance or NULL. + * + * @param \ReflectionClass $reflection + * The reflection class. + * @param string $instance + * The instance the attribute should be of. + * + * @return + * The attribute instance. + */ + protected function getAttributeOfInstance(\ReflectionClass $reflection, string $instance) { + $t = $reflection->getAttributes(); + var_dump($t); + var_dump($t[0]->getName()); + var_dump($t[0]->getArguments()); + var_dump($t[0]->newInstance()); + $s = $reflection->getAttributes(EntityDefinition::class, \ReflectionAttribute::IS_INSTANCEOF); + var_dump($s); + $attributes = $reflection->getAttributes($instance, \ReflectionAttribute::IS_INSTANCEOF); + var_dump($attributes); + if (empty($attributes)) { + return NULL; + } + + return reset($attributes); + } + + public function getDefinition(string $id) :?array { + if (!isset($this->entityDefinitions)) { + $this->list(); + } + if (!isset($this->entityDefinitions[$id])) { + // @TODO maybe we should throw an error here. + return NULL; + } + return $this->entityDefinitions[$id]; + } + + public function createInstance(string $id, array $values) :?EntityInterface { + if (!isset($this->entityDefinitions)) { + $this->list(); + } + if (!isset($this->entityDefinitions[$id])) { + // @TODO maybe we should throw an error here. + return NULL; + } + $definition = $this->getDefinition($id); + $reflection = new \ReflectionClass($definition['class']); + return new $reflection->newInstanceArgs($values); + } + +} diff --git a/app/src/Utils/TimeTrackingServices/YoutrackRestApi/SimpleYoutrackEntityManager.php b/app/src/Utils/TimeTrackingServices/YoutrackRestApi/SimpleYoutrackEntityManager.php new file mode 100644 index 0000000..e0b3439 --- /dev/null +++ b/app/src/Utils/TimeTrackingServices/YoutrackRestApi/SimpleYoutrackEntityManager.php @@ -0,0 +1,24 @@ + [ + 'fields' => [ + 'id', + 'idReadable', + ], + ], + 'project', + 'work_item', + ]; + } + +} diff --git a/app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntity.php b/app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntity.php new file mode 100644 index 0000000..b0b36b1 --- /dev/null +++ b/app/src/Utils/TimeTrackingServices/YoutrackRestApi/YoutrackEntity.php @@ -0,0 +1,14 @@ +getDisplay(); - // var_dump($output); - $this->assertStringContainsString('21-03.csv', $output); - $this->assertStringEqualsFile(self::REPORT_OUTPUT_FILE, $output); + $this->assertStringContainsString('21-03.csv', $output, 'Check that report name is included in console output.'); + $this->assertStringEqualsFile(self::REPORT_OUTPUT_FILE, $output, 'Check that report is still the same as it was.'); if (file_exists(self::INVOICE_OUTPUT_PDF)) { unlink(self::INVOICE_OUTPUT_PDF); @@ -82,8 +81,8 @@ class ReportCommandTest extends TestCase // the output of the command in the console $invoice_output = $invoiceCommandTester->getDisplay(); // var_dump($invoice_output); - $this->assertStringContainsString('21-03.csv', $invoice_output); - $this->assertStringEqualsFile(self::INVOICE_OUTPUT_FILE, $invoice_output); - $this->assertFileExists(self::INVOICE_OUTPUT_PDF); + $this->assertStringContainsString('21-03.csv', $invoice_output, 'Check that invoice command output contains report name.'); + $this->assertStringEqualsFile(self::INVOICE_OUTPUT_FILE, $invoice_output, 'Check that invoice command output is the same as it was.'); + $this->assertFileExists(self::INVOICE_OUTPUT_PDF, 'Check that pdf file was generated.'); } } diff --git a/app/tests/Unit/YoutrackRestApi/EntityManagerTest.php b/app/tests/Unit/YoutrackRestApi/EntityManagerTest.php new file mode 100644 index 0000000..7b9bf3a --- /dev/null +++ b/app/tests/Unit/YoutrackRestApi/EntityManagerTest.php @@ -0,0 +1,38 @@ +addDefinitions(__DIR__ . '/../../test-dependencies.php'); + $container = $builder->build(); + $entityManagerService = $container->get('youtrack.entity_manager'); + // Instance of EntityMangerInterface; + // $this->assertInstanceOf('EntityManagerInterface', $entityManagerService); + $definitions = $entityManagerService->list(); + var_dump($definitions); + $this->assertCount(3, $definitions); + $entities = ['project', 'issue', 'work_item']; + foreach ($entities as $entity) { + $this->assertArrayHasKey($entity, $definitions, 'Check that key exists in entity types definitions.'); + } + // list method returns definitions: project, issue, worktItem + // Check one definition, compare. + + } + +} diff --git a/app/tests/Unit/YoutrackRestApi/README.md b/app/tests/Unit/YoutrackRestApi/README.md new file mode 100644 index 0000000..4b8fd74 --- /dev/null +++ b/app/tests/Unit/YoutrackRestApi/README.md @@ -0,0 +1,4 @@ +# YoutrackRestApi Unit tests + +1. Check that EntityManager lists defined entity types. +2. Check that EntityTypeManager properly creates entity.