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.