From 99d16c3a7239e58fb85f952bd68da4c452971b90 Mon Sep 17 00:00:00 2001 From: Lio Novelli Date: Mon, 2 Jan 2023 20:35:41 +0100 Subject: [PATCH] Fix phpstan errors, improve automated test. --- app/composer.json | 3 ++- app/src/Commands/InvoiceCommand.php | 22 ++++++++++++------- app/src/Commands/ReportCommand.php | 6 ++--- app/src/Utils/CsvReport/CsvReport.php | 4 ++-- .../Utils/CsvReport/CsvReportInterface.php | 2 ++ app/src/Utils/CsvReport/ReportCsv.php | 13 ++++++----- .../Utils/CsvReport/ReportCsvInterface.php | 2 ++ app/src/Utils/Mailer/MailerInterface.php | 15 +++++++++++-- app/src/Utils/Mailer/MailerService.php | 2 ++ app/src/Utils/PdfExport/PdfExportService.php | 1 + .../YoutrackInterface.php | 5 +++++ app/tests/Kernel/ReportCommandTest.php | 19 ++++++++-------- app/tests/data/invoice-21-03.txt | 1 + todo.txt | 12 +++++----- 14 files changed, 70 insertions(+), 37 deletions(-) diff --git a/app/composer.json b/app/composer.json index 81012fc..0a7a2ef 100644 --- a/app/composer.json +++ b/app/composer.json @@ -36,7 +36,8 @@ }, "scripts": { "cs": "phpcs --colors --standard=PSR12", - "cbf": "phpcbf" + "cbf": "phpcbf", + "phpstan": "phpstan analyze -l 5 src" }, "config": { "allow-plugins": { diff --git a/app/src/Commands/InvoiceCommand.php b/app/src/Commands/InvoiceCommand.php index 43823bf..1490915 100644 --- a/app/src/Commands/InvoiceCommand.php +++ b/app/src/Commands/InvoiceCommand.php @@ -27,6 +27,7 @@ use function explode; use function is_array; use function is_null; use function is_string; +use function PHPUnit\Framework\throwException; use function readline; use function strpos; use function strtolower; @@ -42,13 +43,15 @@ class InvoiceCommand extends Command { use SelectReportTrait; - protected $csv; + protected ReportCsvInterface $csv; - protected $config; + protected ConfigurationInterface $config; - protected $youtrack; + protected YoutrackInterface $trackingService; - protected $pdfExport; + protected PdfExportInterface $pdfExport; + + protected MailerInterface $mailer; protected const TYPE_WORK = 1; protected const TYPE_EXPENSE = 2; @@ -185,11 +188,11 @@ class InvoiceCommand extends Command if ($out = $input->getOption('output')) { $this->pdfExport->setOutput($out); } - $output_path = $this->pdfExport->fromDefaultDataToPdf($nice_data); + $output_path = $this->pdfExport->fromDefaultDataToPdf($nice_data) ?: sys_get_temp_dir(); // Notify the user where the file was generated to. $output->writeln("The file was generated at ${output_path}."); } - if ($input->getOption('send') && $output_path) { + if ($input->getOption('send') && isset($output_path)) { // @TODO If no output path print an error. // Send email to configured address. if ($recipients = $input->getOption('recipients')) { @@ -273,7 +276,7 @@ class InvoiceCommand extends Command $rows[] = new TableSeparator(); // @TODO Check rate in final result. // $rows[] = [$this->translator->trans('Sum'), $totalHours, $config['price'], $totalPrice]; - $rows[] = ['Sum', $totalHours, $config['price'], $totalPrice]; + $rows[] = ['Sum', $totalHours, NULL, $totalPrice]; $table->setRows($rows); return $table; @@ -326,7 +329,7 @@ class InvoiceCommand extends Command return $output; } - protected function getCustomWorkOrExpenses($custom, $type) + protected function getCustomWorkOrExpenses(mixed $custom, int $type) { $output = []; if (is_string($custom)) { @@ -343,6 +346,9 @@ class InvoiceCommand extends Command $message_name = 'Enter expenses name or leave empty to stop: '; $message_value = 'Enter expenses value: '; } + else { + throw new \Exception('Unknown type of custom data.'); + } while ($continue) { $name = readline($message_name); $value = (float) readline($message_value); diff --git a/app/src/Commands/ReportCommand.php b/app/src/Commands/ReportCommand.php index c6cb386..e2950ae 100644 --- a/app/src/Commands/ReportCommand.php +++ b/app/src/Commands/ReportCommand.php @@ -22,11 +22,11 @@ class ReportCommand extends Command { use SelectReportTrait; - protected $trackingService; + protected YoutrackInterface $trackingService; - protected $config; + protected ConfigurationInterface $config; - protected $csv; + protected ReportCsvInterface $csv; // phpcs:ignore public function __construct(ConfigurationInterface $configuration, YoutrackInterface $tracking_service, ReportCsvInterface $csv, ?string $name = null) diff --git a/app/src/Utils/CsvReport/CsvReport.php b/app/src/Utils/CsvReport/CsvReport.php index a36be37..06547c8 100644 --- a/app/src/Utils/CsvReport/CsvReport.php +++ b/app/src/Utils/CsvReport/CsvReport.php @@ -114,8 +114,8 @@ class CsvReport implements CsvReportInterface $rows[] = [ 'Gesamt netto', number_format($totalHours, 2, ',', '.'), - number_format($config['price'], 2, ',', '.'), - number_format($totalPrice, 2, ',', '.') + NULL, + number_format($totalPrice, 2, ',', '.'), ]; $rows[] = [null, null, 'Gessamt brutto', number_format($totalPrice, 2, ',', '.')]; diff --git a/app/src/Utils/CsvReport/CsvReportInterface.php b/app/src/Utils/CsvReport/CsvReportInterface.php index 91ee52e..59770c4 100644 --- a/app/src/Utils/CsvReport/CsvReportInterface.php +++ b/app/src/Utils/CsvReport/CsvReportInterface.php @@ -6,6 +6,8 @@ namespace RprtCli\Utils\CsvReport; /** * Handles creating report data from csv file downloaded from youtrack service. + * + * @deprecated Use ReportCsv instead. */ interface CsvReportInterface { diff --git a/app/src/Utils/CsvReport/ReportCsv.php b/app/src/Utils/CsvReport/ReportCsv.php index 89e9eec..3f9d957 100644 --- a/app/src/Utils/CsvReport/ReportCsv.php +++ b/app/src/Utils/CsvReport/ReportCsv.php @@ -98,11 +98,11 @@ class ReportCsv implements ReportCsvInterface { [$rows, $totalHours, $totalPrice, $add_separator] = [[], 0, 0, false]; $projectsConfig = $this->configurationService->get('projects'); + // @TODO Remove unnecessary header after check. // $header = $this->configurationService->get('export.labels', null); - $header = null; - if (is_array($header)) { - $rows[] = $header; - } + // if (is_array($header)) { + // $rows[] = $header; + // } // First only list work invoice elements. foreach ($data as $key => $invoice_element) { if ($invoice_element instanceof WorkInvoiceElementInterface) { @@ -186,7 +186,10 @@ class ReportCsv implements ReportCsvInterface return $rows; } - public function generateReportTable(string $filePath) + /** + * {@inheritdoc} + */ + public function generateReportTable(string $filePath): array { // ticket-id, ticket-name, time-spent $data = $this->parseReportData($filePath); diff --git a/app/src/Utils/CsvReport/ReportCsvInterface.php b/app/src/Utils/CsvReport/ReportCsvInterface.php index a758a05..2139e11 100644 --- a/app/src/Utils/CsvReport/ReportCsvInterface.php +++ b/app/src/Utils/CsvReport/ReportCsvInterface.php @@ -48,4 +48,6 @@ interface ReportCsvInterface * Parsed data from csv report. */ public function arangeDataForDefaultPdfExport(array $data): array; + + public function generateReportTable(string $filePath): array; } diff --git a/app/src/Utils/Mailer/MailerInterface.php b/app/src/Utils/Mailer/MailerInterface.php index 158e70d..0e204ff 100644 --- a/app/src/Utils/Mailer/MailerInterface.php +++ b/app/src/Utils/Mailer/MailerInterface.php @@ -7,6 +7,17 @@ namespace RprtCli\Utils\Mailer; /** * Methods for symfony (swift)mailer service. */ -interface MailerInterface -{ +interface MailerInterface { + + /** + * Recipients for message. + * + * @param string[] $to + */ + public function setRecipients(array $to): void; + + /** + * Sends default mail. + */ + public function sendDefaultMail(string $output): void; } diff --git a/app/src/Utils/Mailer/MailerService.php b/app/src/Utils/Mailer/MailerService.php index eee2f23..10a8b2a 100644 --- a/app/src/Utils/Mailer/MailerService.php +++ b/app/src/Utils/Mailer/MailerService.php @@ -46,6 +46,8 @@ class MailerService implements MailerInterface protected $email; + protected string $password; + public function __construct(ConfigurationInterface $config, PdfExportInterface $pdf) { $this->config = $config; diff --git a/app/src/Utils/PdfExport/PdfExportService.php b/app/src/Utils/PdfExport/PdfExportService.php index 32c50a0..0707a5e 100644 --- a/app/src/Utils/PdfExport/PdfExportService.php +++ b/app/src/Utils/PdfExport/PdfExportService.php @@ -69,6 +69,7 @@ class PdfExportService implements PdfExportInterface $table = ''; $header = array_shift($data); $classes = ''; + $rows = []; foreach ($header as $index => $cell) { $table .= ""; } diff --git a/app/src/Utils/TimeTrackingServices/YoutrackInterface.php b/app/src/Utils/TimeTrackingServices/YoutrackInterface.php index 97bad20..cd790aa 100644 --- a/app/src/Utils/TimeTrackingServices/YoutrackInterface.php +++ b/app/src/Utils/TimeTrackingServices/YoutrackInterface.php @@ -40,4 +40,9 @@ interface YoutrackInterface public function setReportName(?string $report_name = null): void; public function getReportName(): ?string; + + /** + * Clears cache for youtrack report. + */ + public function clearReportCache(string $report_id): int; } diff --git a/app/tests/Kernel/ReportCommandTest.php b/app/tests/Kernel/ReportCommandTest.php index 032280c..fcedf53 100644 --- a/app/tests/Kernel/ReportCommandTest.php +++ b/app/tests/Kernel/ReportCommandTest.php @@ -27,6 +27,9 @@ class ReportCommandTest extends TestCase { protected const INVOICE_OUTPUT_PDF = __DIR__ . '/../data/output/Invoice-test.pdf'; + /** + * Run report and invoice command with file option parameter. Check if pdf was generated. + */ public function testExecute() { $builder = new ContainerBuilder(); $builder->addDefinitions(__DIR__ . '/../test-dependencies.php'); @@ -60,29 +63,25 @@ class ReportCommandTest extends TestCase { $this->assertStringContainsString('21-03.csv', $output); $this->assertStringEqualsFile(self::REPORT_OUTPUT_FILE, $output); + if (file_exists(self::INVOICE_OUTPUT_PDF)) { + unlink(self::INVOICE_OUTPUT_PDF); + } $invoiceCommand = $application->find('invoice'); $invoiceCommandTester = new CommandTester($invoiceCommand); $invoiceCommandTester->execute([ '--file' => self::INPUT_CSV_FILE, '--pdf' => TRUE, + '--output' => self::INVOICE_OUTPUT_PDF, ]); $invoiceCommandTester->assertCommandIsSuccessful(); // the output of the command in the console $invoice_output = $invoiceCommandTester->getDisplay(); - var_dump($invoice_output); + // var_dump($invoice_output); $this->assertStringContainsString('21-03.csv', $invoice_output); $this->assertStringEqualsFile(self::INVOICE_OUTPUT_FILE, $invoice_output); - - // $invoiceCommandTester->execute([ - // '--file' => self::INPUT_CSV_FILE, - // '--pdf' - // ]); - // $invoice_output = $invoiceCommandTester->getDisplay(); - // var_dump($invoice_output); - // $this->assertFileExists(); - + $this->assertFileExists(self::INVOICE_OUTPUT_PDF); } } diff --git a/app/tests/data/invoice-21-03.txt b/app/tests/data/invoice-21-03.txt index 3da3ffc..ccb8e60 100644 --- a/app/tests/data/invoice-21-03.txt +++ b/app/tests/data/invoice-21-03.txt @@ -9,3 +9,4 @@ report: /home/lio/Projects/drunomix/rprt-cli/app/tests/Kernel/../data/21-03.csv +-----------------------------+--------+-------+----------+ | Gessamt brutto | 4.505,35 | +-----------------------------+--------+-------+----------+ +The file was generated at /home/lio/Projects/drunomix/rprt-cli/app/tests/Kernel/../data/output/Invoice-test.pdf. diff --git a/todo.txt b/todo.txt index 1a5e46c..287a6cb 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,4 @@ TODO: -- nice report selection - clean up the config (default reports) - Improve readme - abstract baseCommand with some input params @@ -8,13 +7,9 @@ TODO: - in dependencies.php find subdependencies.php - Create interface for 3rd party service integration and abstract class - Create factory to add correct service of a 3rd party service to the Command -- separator constant ------------------------ - add plugin system for time tracking service -- add tests ------------------------ -- question helper: https://symfony.com/doc/current/components/console/helpers/questionhelper.html -- psr-12 code check and add phpstan https://phpstan.org/user-guide/getting-started - phing for build automation - add ddev for dockerization @@ -32,6 +27,7 @@ OPTIONAL: - youtrack - jira - kimai +- build phar without most of the fonts @@ -44,4 +40,8 @@ DONE: - upload a phar file on repo - create release - clear report cache - +- nice report selection +- separator constant +- add tests +- psr-12 code check and add phpstan https://phpstan.org/user-guide/getting-started +- question helper: https://symfony.com/doc/current/components/console/helpers/questionhelper.html
{$cell}