From 170aa3052dd9079ccd3d45da159c589e56b6b3ae Mon Sep 17 00:00:00 2001 From: Laurent Muller Date: Mon, 9 Oct 2023 16:34:21 +0200 Subject: [PATCH] Reworked tests. --- composer.lock | 12 +- src/Chart/MonthChart.php | 7 +- src/Controller/ChartController.php | 12 ++ src/Controller/ThemeController.php | 4 +- src/Report/CalculationByMonthReport.php | 59 +++++++--- src/Report/CalculationByStateReport.php | 72 +++++++----- src/Report/CalculationStatesReport.php | 26 +++-- src/Service/SchemaService.php | 11 +- templates/chart/chart_state.html.twig | 16 +-- .../Controller/AbstractControllerTestCase.php | 4 +- .../CalculationBelowControllerTest.php | 74 +++++------- .../Controller/CalculationControllerTest.php | 49 +++----- .../CalculationDuplicateControllerTest.php | 71 ++++-------- .../CalculationEmptyControllerTest.php | 72 +++++------- .../CalculationStateControllerTest.php | 12 +- tests/Controller/CategoryControllerTest.php | 24 ++-- tests/Controller/ChartControllerTest.php | 105 +++++++----------- tests/Controller/CustomerControllerTest.php | 12 +- .../Controller/GlobalMarginControllerTest.php | 14 +-- tests/Controller/GroupControllerTest.php | 12 +- tests/Controller/IndexControllerTest.php | 1 + tests/Controller/LogControllerTest.php | 22 +++- tests/Controller/PivotControllerTest.php | 83 +++++--------- tests/Controller/ProductControllerTest.php | 40 ++----- tests/Controller/TaskControllerTest.php | 51 +++------ tests/Controller/ThemeControllerTest.php | 22 +++- .../Controller/UpdateEntityControllerTest.php | 64 +++++------ tests/EntityTrait/CalculationStateTrait.php | 47 ++++++++ tests/EntityTrait/CalculationTrait.php | 65 +++++++++++ tests/EntityTrait/CategoryTrait.php | 49 ++++++++ tests/EntityTrait/GlobalMarginTrait.php | 49 ++++++++ tests/EntityTrait/GroupTrait.php | 47 ++++++++ tests/EntityTrait/ProductTrait.php | 50 +++++++++ tests/EntityTrait/TaskItemTrait.php | 49 ++++++++ tests/EntityTrait/TaskTrait.php | 49 ++++++++ translations/messages+intl-icu.fr_CH.yaml | 4 +- translations/messages.fr_CH.yaml | 6 +- 37 files changed, 832 insertions(+), 534 deletions(-) create mode 100644 tests/EntityTrait/CalculationStateTrait.php create mode 100644 tests/EntityTrait/CalculationTrait.php create mode 100644 tests/EntityTrait/CategoryTrait.php create mode 100644 tests/EntityTrait/GlobalMarginTrait.php create mode 100644 tests/EntityTrait/GroupTrait.php create mode 100644 tests/EntityTrait/ProductTrait.php create mode 100644 tests/EntityTrait/TaskItemTrait.php create mode 100644 tests/EntityTrait/TaskTrait.php diff --git a/composer.lock b/composer.lock index e97977be1..ebabfe032 100644 --- a/composer.lock +++ b/composer.lock @@ -484,16 +484,16 @@ }, { "name": "doctrine/dbal", - "version": "3.7.0", + "version": "3.7.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + "reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", - "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/5b7bd66c9ff58c04c5474ab85edce442f8081cb2", + "reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2", "shasum": "" }, "require": { @@ -577,7 +577,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.7.0" + "source": "https://github.com/doctrine/dbal/tree/3.7.1" }, "funding": [ { @@ -593,7 +593,7 @@ "type": "tidelift" } ], - "time": "2023-09-26T20:56:55+00:00" + "time": "2023-10-06T05:06:20+00:00" }, { "name": "doctrine/deprecations", diff --git a/src/Chart/MonthChart.php b/src/Chart/MonthChart.php index c5f9942f2..1d232cf8b 100644 --- a/src/Chart/MonthChart.php +++ b/src/Chart/MonthChart.php @@ -148,8 +148,13 @@ private function getAllowedMonths(): array { $step = 6; $maxMonths = $this->repository->countDistinctMonths(); + if ($maxMonths <= $step) { + return [$maxMonths]; + } + if ($maxMonths % $step > 0) { - $maxMonths += $step; + $delta = $step % $maxMonths; + $maxMonths += $delta; } return \range($step, $maxMonths, $step); diff --git a/src/Controller/ChartController.php b/src/Controller/ChartController.php index 08efe3c5d..33429c060 100644 --- a/src/Controller/ChartController.php +++ b/src/Controller/ChartController.php @@ -14,6 +14,8 @@ use App\Chart\MonthChart; use App\Chart\StateChart; +use App\Entity\Calculation; +use App\Enums\EntityPermission; use App\Interfaces\RoleInterface; use App\Report\CalculationByMonthReport; use App\Report\CalculationByStateReport; @@ -48,6 +50,7 @@ class ChartController extends AbstractController #[Route(path: '/month', name: 'chart_by_month', methods: Request::METHOD_GET)] public function month(Request $request, MonthChart $chart): Response { + $this->checkAccess(); $key = 'chart_by_month'; $months = $this->getMonths($request); $parameters = $chart->generate($months); @@ -62,6 +65,7 @@ public function month(Request $request, MonthChart $chart): Response #[Route(path: '/month/pdf', name: 'chart_by_month_pdf', methods: Request::METHOD_GET)] public function monthPdf(Request $request, CalculationRepository $repository): PdfResponse { + $this->checkAccess(EntityPermission::EXPORT); $months = $this->getMonths($request); $data = $repository->getByMonth($months); $report = new CalculationByMonthReport($this, $data); @@ -77,18 +81,26 @@ public function monthPdf(Request $request, CalculationRepository $repository): P #[Route(path: '/state', name: 'chart_by_state', methods: Request::METHOD_GET)] public function state(StateChart $chart): Response { + $this->checkAccess(); + return $this->render('chart/chart_state.html.twig', $chart->generate()); } #[Route(path: '/state/pdf', name: 'chart_by_state_pdf', methods: Request::METHOD_GET)] public function statePdf(CalculationStateRepository $repository): PdfResponse { + $this->checkAccess(EntityPermission::EXPORT); $data = $repository->getCalculations(); $report = new CalculationByStateReport($this, $data); return $this->renderPdfDocument($report); } + private function checkAccess(EntityPermission $permission = EntityPermission::SHOW): void + { + $this->denyAccessUnlessGranted($permission, Calculation::class); + } + private function getMonths(Request $request): int { $count = $this->getSessionInt('chart_by_month', 6); diff --git a/src/Controller/ThemeController.php b/src/Controller/ThemeController.php index 55c9c6e43..dd181ec7d 100644 --- a/src/Controller/ThemeController.php +++ b/src/Controller/ThemeController.php @@ -13,8 +13,8 @@ namespace App\Controller; use App\Enums\Theme; -use App\Interfaces\RoleInterface; use App\Service\ThemeService; +use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -26,7 +26,7 @@ */ #[AsController] #[Route(path: '/theme')] -#[IsGranted(RoleInterface::ROLE_USER)] +#[IsGranted(new Expression('is_granted("ROLE_USER") and user.isEnabled()'))] class ThemeController extends AbstractController { #[Route(path: '/dialog', name: 'theme_dialog', methods: Request::METHOD_GET)] diff --git a/src/Report/CalculationByMonthReport.php b/src/Report/CalculationByMonthReport.php index 74bbf66eb..d99d395cb 100644 --- a/src/Report/CalculationByMonthReport.php +++ b/src/Report/CalculationByMonthReport.php @@ -12,9 +12,13 @@ namespace App\Report; +use App\Pdf\PdfCell; use App\Pdf\PdfColumn; +use App\Pdf\PdfStyle; use App\Pdf\PdfTableBuilder; +use App\Pdf\PdfTextColor; use App\Repository\CalculationRepository; +use App\Traits\MathTrait; use App\Utils\FormatUtils; /** @@ -26,6 +30,8 @@ */ class CalculationByMonthReport extends AbstractArrayReport { + use MathTrait; + /** * @psalm-param CalculationByMonthType[] $entities */ @@ -37,14 +43,14 @@ protected function doRender(array $entities): bool $table = $this->createTable(); foreach ($entities as $entity) { - $table->startRow() - ->add($this->formatDate($entity['date'])) - ->add(FormatUtils::formatInt($entity['count'])) - ->add(FormatUtils::formatInt($entity['items'])) - ->add(FormatUtils::formatInt($entity['total'] - $entity['items'])) - ->add(FormatUtils::formatPercent($entity['margin'], false)) - ->add(FormatUtils::formatInt($entity['total'])) - ->endRow(); + $table->startRow()->addValues( + $this->formatDate($entity['date']), + FormatUtils::formatInt($entity['count']), + FormatUtils::formatInt($entity['items']), + FormatUtils::formatInt($entity['total'] - $entity['items']), + $this->formatPercent($entity['margin']), + FormatUtils::formatInt($entity['total']) + )->endRow(); } // total @@ -52,16 +58,16 @@ protected function doRender(array $entities): bool $items = $this->sum($entities, 'items'); $total = $this->sum($entities, 'total'); $net = $total - $items; - $margin = 1.0 + $net / $items; + $margin = 1.0 + $this->safeDivide($net, $items); - $table->startHeaderRow() - ->add($this->transChart('fields.total')) - ->add(FormatUtils::formatInt($count)) - ->add(FormatUtils::formatInt($items)) - ->add(FormatUtils::formatInt($net)) - ->add(FormatUtils::formatPercent($margin, false)) - ->add(FormatUtils::formatInt($total)) - ->endRow(); + $table->startHeaderRow()->addValues( + $this->transChart('fields.total'), + FormatUtils::formatInt($count), + FormatUtils::formatInt($items), + FormatUtils::formatInt($net), + $this->formatPercent($margin, true), + FormatUtils::formatInt($total) + )->endRow(); return true; } @@ -73,7 +79,7 @@ private function createTable(): PdfTableBuilder PdfColumn::right($this->transChart('fields.count'), 25, true), PdfColumn::right($this->transChart('fields.net'), 25, true), PdfColumn::right($this->transChart('fields.margin_amount'), 25, true), - PdfColumn::right($this->transChart('fields.margin_percent'), 25, true), + PdfColumn::right($this->transChart('fields.margin_percent'), 20, true), PdfColumn::right($this->transChart('fields.total'), 25, true), ]; @@ -87,6 +93,23 @@ private function formatDate(\DateTimeInterface $date): string return \ucfirst(FormatUtils::formatDate(date: $date, pattern: 'MMMM Y')); } + private function formatPercent(float $value, bool $bold = false): PdfCell + { + $cell = new PdfCell(FormatUtils::formatPercent($value, false)); + $style = $bold ? PdfStyle::getHeaderStyle() : PdfStyle::getCellStyle(); + if ($this->isMinMargin($value)) { + $style->setTextColor(PdfTextColor::red()); + } + $cell->setStyle($style); + + return $cell; + } + + private function isMinMargin(float $value): bool + { + return !$this->isFloatZero($value) && $value < $this->controller->getMinMargin(); + } + private function sum(array $entities, string $key): float { return \array_sum(\array_column($entities, $key)); diff --git a/src/Report/CalculationByStateReport.php b/src/Report/CalculationByStateReport.php index 85a4d8990..e6a6ce092 100644 --- a/src/Report/CalculationByStateReport.php +++ b/src/Report/CalculationByStateReport.php @@ -12,9 +12,13 @@ namespace App\Report; +use App\Pdf\PdfCell; use App\Pdf\PdfColumn; +use App\Pdf\PdfStyle; use App\Pdf\PdfTableBuilder; +use App\Pdf\PdfTextColor; use App\Repository\CalculationStateRepository; +use App\Traits\MathTrait; use App\Utils\FormatUtils; /** @@ -26,6 +30,8 @@ */ class CalculationByStateReport extends AbstractArrayReport { + use MathTrait; + /** * @psalm-param QueryCalculationType[] $entities */ @@ -37,36 +43,38 @@ protected function doRender(array $entities): bool $table = $this->createTable(); foreach ($entities as $entity) { - $table->startRow() - ->add($entity['code']) - ->add(FormatUtils::formatInt($entity['count'])) - ->add($this->formatPercent($entity['percentCalculation'])) - ->add(FormatUtils::formatInt($entity['items'])) - ->add(FormatUtils::formatInt($entity['marginAmount'])) - ->add(FormatUtils::formatPercent($entity['margin'])) - ->add(FormatUtils::formatInt($entity['total'])) - ->add($this->formatPercent($entity['percentAmount'])) - ->endRow(); + $table->startRow()->addValues( + $entity['code'], + FormatUtils::formatInt($entity['count']), + $this->formatPercent($entity['percentCalculation'], 2), + FormatUtils::formatInt($entity['items']), + FormatUtils::formatInt($entity['marginAmount']), + $this->formatPercent($entity['margin'], 0, true), + FormatUtils::formatInt($entity['total']), + $this->formatPercent($entity['percentAmount'], 2) + )->endRow(); } // total $count = $this->sum($entities, 'count'); + $percentCalculation = $this->sum($entities, 'percentCalculation'); $items = $this->sum($entities, 'items'); $marginAmount = $this->sum($entities, 'marginAmount'); $total = $this->sum($entities, 'total'); $net = $total - $items; - $margin = 1.0 + $net / $items; - - $table->startHeaderRow() - ->add($this->transChart('fields.total')) - ->add(FormatUtils::formatInt($count)) - ->add($this->formatPercent(1.0)) - ->add(FormatUtils::formatInt($items)) - ->add(FormatUtils::formatInt($marginAmount)) - ->add($this->formatPercent($margin, 0)) - ->add(FormatUtils::formatInt($total)) - ->add($this->formatPercent(1.0)) - ->endRow(); + $margin = 1.0 + $this->safeDivide($net, $items); + $percentAmount = $this->sum($entities, 'percentAmount'); + + $table->startHeaderRow()->addValues( + $this->transChart('fields.total'), + FormatUtils::formatInt($count), + $this->formatPercent($percentCalculation, 2, bold: true), + FormatUtils::formatInt($items), + FormatUtils::formatInt($marginAmount), + $this->formatPercent($margin, 0, bold: true), + FormatUtils::formatInt($total), + $this->formatPercent($percentAmount, 2, bold: true), + )->endRow(); return true; } @@ -76,12 +84,12 @@ private function createTable(): PdfTableBuilder $columns = [ PdfColumn::left($this->transChart('fields.state'), 20), PdfColumn::right($this->transChart('fields.count'), 25, true), - PdfColumn::right($this->transChart('fields.percent'), 25, true), + PdfColumn::right('%', 15, true), PdfColumn::right($this->transChart('fields.net'), 20, true), PdfColumn::right($this->transChart('fields.margin_amount'), 20, true), PdfColumn::right($this->transChart('fields.margin_percent'), 20, true), PdfColumn::right($this->transChart('fields.total'), 20, true), - PdfColumn::right($this->transChart('fields.percent'), 25, true), + PdfColumn::right('%', 15, true), ]; return PdfTableBuilder::instance($this) @@ -89,9 +97,21 @@ private function createTable(): PdfTableBuilder ->outputHeaders(); } - private function formatPercent(float $value, int $decimals = 1): string + private function formatPercent(float $value, int $decimals = 1, bool $useStyle = false, bool $bold = false): PdfCell + { + $style = $bold ? PdfStyle::getHeaderStyle() : PdfStyle::getCellStyle(); + $cell = new PdfCell(FormatUtils::formatPercent($value, false, $decimals, \NumberFormatter::ROUND_HALFEVEN)); + if ($useStyle && $this->isMinMargin($value)) { + $style->setTextColor(PdfTextColor::red()); + } + $cell->setStyle($style); + + return $cell; + } + + private function isMinMargin(float $value): bool { - return FormatUtils::formatPercent($value, true, $decimals, \NumberFormatter::ROUND_HALFEVEN); + return !$this->isFloatZero($value) && $value < $this->controller->getMinMargin(); } private function sum(array $entities, string $key): float diff --git a/src/Report/CalculationStatesReport.php b/src/Report/CalculationStatesReport.php index d31558087..ab90eacf7 100644 --- a/src/Report/CalculationStatesReport.php +++ b/src/Report/CalculationStatesReport.php @@ -39,20 +39,22 @@ public function AddPage($orientation = '', $size = '', $rotation = 0): void public function drawCellBackground(PdfTableBuilder $builder, int $index, PdfRectangle $bounds): bool { - if (3 === $index) { - if ($this->started) { - $doc = $builder->getParent(); - $margin = $doc->getCellMargin(); - $bounds->inflateXY(-3.0 * $margin, -$margin) - ->setHeight(self::LINE_HEIGHT - 2.0 * $margin); - $doc->rectangle($bounds, PdfRectangleStyle::BOTH); - - return true; - } + if (3 !== $index) { + return false; + } + if (!$this->started) { $this->started = true; + + return false; } - return false; + $doc = $builder->getParent(); + $margin = $doc->getCellMargin(); + $bounds->inflateXY(-3.0 * $margin, -$margin) + ->setHeight(self::LINE_HEIGHT - 2.0 * $margin); + $doc->rectangle($bounds, PdfRectangleStyle::BOTH); + + return true; } /** @@ -62,6 +64,7 @@ protected function doRender(array $entities): bool { $this->setTitleTrans('calculationstate.list.title'); $this->AddPage(); + $table = PdfTableBuilder::instance($this) ->setBackgroundListener($this) ->addColumns( @@ -71,6 +74,7 @@ protected function doRender(array $entities): bool PdfColumn::center($this->trans('calculationstate.fields.color'), 15, true), PdfColumn::right($this->trans('calculationstate.fields.calculations'), 22, true) )->outputHeaders(); + foreach ($entities as $entity) { $table->startRow() ->add($entity->getCode()) diff --git a/src/Service/SchemaService.php b/src/Service/SchemaService.php index 750fd0bd7..374f441d1 100644 --- a/src/Service/SchemaService.php +++ b/src/Service/SchemaService.php @@ -265,16 +265,21 @@ private function getConnection(): Connection private function getDefaultValue(Column $column): string { - $type = $column->getType(); + /** @psalm-var string|null $default */ $default = $column->getDefault(); - if (null !== $default && $type instanceof BooleanType) { + if (!\is_string($default)) { + return ''; + } + + $type = $column->getType(); + if ($type instanceof BooleanType) { return StringUtils::encodeJson(\filter_var($default, \FILTER_VALIDATE_BOOLEAN)); } if ('0' === $default && $type instanceof FloatType) { return '0.00'; } - return $default ?? ''; + return $default; } /** diff --git a/templates/chart/chart_state.html.twig b/templates/chart/chart_state.html.twig index d189cd776..904e20b86 100644 --- a/templates/chart/chart_state.html.twig +++ b/templates/chart/chart_state.html.twig @@ -13,12 +13,12 @@ {{ 'fields.state'|trans }} {{ 'fields.count'|trans }} - {{ 'fields.percent'|trans }} + % {{ 'fields.net'|trans }} {{ 'fields.margin_amount'|trans }} {{ 'fields.margin_percent'|trans }} {{ 'fields.total'|trans }} - {{ 'fields.percent'|trans }} + % @@ -28,12 +28,12 @@ {{- item.code }} {{ item.count|integer }} - {{ item.percentCalculation|percent(true, 1, 4) }} + {{ item.percentCalculation|percent(false, 2, 4) }} {{ item.items|integer }} {{ item.marginAmount|integer }} - {{ item.margin|percent }} + {{ item.margin|percent(false) }} {{ item.total|integer }} - {{ item.percentAmount|percent(true, 1, 4) }} + {{ item.percentAmount|percent(false, 2, 4) }} {% endfor -%} @@ -41,12 +41,12 @@ {{ 'fields.total'|trans }} {{ count|integer }} - {{ 1.0|percent(true, 1, 4) }} + {{ 1.0|percent(false, 2, 4) }} {{ items|integer }} {{ marginAmount|integer }} - {{- margin|percent(true) -}} + {{- margin|percent(false) -}} {{ total|integer }} - {{ 1.0|percent(true, 1, 4) }} + {{ 1.0|percent(false, 2, 4) }} {% endblock %} diff --git a/tests/Controller/AbstractControllerTestCase.php b/tests/Controller/AbstractControllerTestCase.php index 4f0e05e4b..1a5093de8 100644 --- a/tests/Controller/AbstractControllerTestCase.php +++ b/tests/Controller/AbstractControllerTestCase.php @@ -24,7 +24,9 @@ abstract class AbstractControllerTestCase extends AbstractAuthenticateWebTestCase { /** - * Gets the routes to test. Each entry must contain a URL, a username, an optional expected result, request method and xml http request. + * Gets the routes to test. + * + * Each entry must contain a URL, a username, an optional expected result, request method and xml http request. */ abstract public static function getRoutes(): array|\Generator; diff --git a/tests/Controller/CalculationBelowControllerTest.php b/tests/Controller/CalculationBelowControllerTest.php index ed9b47d81..de88c3d17 100644 --- a/tests/Controller/CalculationBelowControllerTest.php +++ b/tests/Controller/CalculationBelowControllerTest.php @@ -13,22 +13,22 @@ namespace App\Tests\Controller; use App\Controller\CalculationBelowController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; use Doctrine\ORM\Exception\ORMException; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(CalculationBelowController::class)] class CalculationBelowControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; + use ProductTrait; public static function getRoutes(): array { @@ -52,41 +52,17 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test Product') - ->setPrice(1.0) - ->setCategory(self::$category); - $this->addEntity(self::$product); - } - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state) - ->addProduct(self::$product); + $group = $this->getGroup(); + $category = $this->getCategory($group); + $product = $this->getProduct($category); + $state = $this->getCalculationState(); - self::$calculation->setItemsTotal(1.0) - ->setGlobalMargin(1.0) - ->setOverallTotal(2.0); - $this->addEntity(self::$calculation); - } + $calculation = $this->getCalculation($state) + ->addProduct($product) + ->setItemsTotal(1.0) + ->setGlobalMargin(1.0) + ->setOverallTotal(2.0); + $this->addEntity($calculation); } /** @@ -94,10 +70,10 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$product = $this->deleteEntity(self::$product); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CalculationControllerTest.php b/tests/Controller/CalculationControllerTest.php index 65e0b6355..8e7541de8 100644 --- a/tests/Controller/CalculationControllerTest.php +++ b/tests/Controller/CalculationControllerTest.php @@ -13,18 +13,18 @@ namespace App\Tests\Controller; use App\Controller\CalculationController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; #[\PHPUnit\Framework\Attributes\CoversClass(CalculationController::class)] class CalculationControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; public static function getRoutes(): array { @@ -84,29 +84,8 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state); - $this->addEntity(self::$calculation); - } + $this->getCategory($this->getGroup()); + $this->getCalculation($this->getCalculationState()); } /** @@ -114,9 +93,9 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CalculationDuplicateControllerTest.php b/tests/Controller/CalculationDuplicateControllerTest.php index 1c37b4a79..c4d7bda9d 100644 --- a/tests/Controller/CalculationDuplicateControllerTest.php +++ b/tests/Controller/CalculationDuplicateControllerTest.php @@ -13,21 +13,21 @@ namespace App\Tests\Controller; use App\Controller\CalculationDuplicateController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(CalculationDuplicateController::class)] class CalculationDuplicateControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; + use ProductTrait; public static function getRoutes(): array { @@ -51,38 +51,15 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test Product') - ->setPrice(10) - ->setCategory(self::$category); - $this->addEntity(self::$product); - } - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state) - ->addProduct(self::$product) - ->addProduct(self::$product); - $this->addEntity(self::$calculation); - } + $group = $this->getGroup(); + $category = $this->getCategory($group); + $product = $this->getProduct($category); + $state = $this->getCalculationState(); + + $calculation = $this->getCalculation($state); + $calculation->addProduct($product) + ->addProduct($product); + $this->addEntity($calculation); } /** @@ -90,10 +67,10 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$product = $this->deleteEntity(self::$product); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CalculationEmptyControllerTest.php b/tests/Controller/CalculationEmptyControllerTest.php index e79368d60..a2368fcfc 100644 --- a/tests/Controller/CalculationEmptyControllerTest.php +++ b/tests/Controller/CalculationEmptyControllerTest.php @@ -13,21 +13,21 @@ namespace App\Tests\Controller; use App\Controller\CalculationEmptyController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(CalculationEmptyController::class)] class CalculationEmptyControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; + use ProductTrait; public static function getRoutes(): array { @@ -51,37 +51,17 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test Product') - ->setPrice(0) - ->setCategory(self::$category); - $this->addEntity(self::$product); - } - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state) - ->addProduct(self::$product, 0); - $this->addEntity(self::$calculation); - } + $group = $this->getGroup(); + $category = $this->getCategory($group); + $state = $this->getCalculationState(); + + $product = $this->getProduct($category) + ->setPrice(0.0); + $this->addEntity($product); + + $calculation = $this->getCalculation($state) + ->addProduct($product); + $this->addEntity($calculation); } /** @@ -89,10 +69,10 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$product = $this->deleteEntity(self::$product); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CalculationStateControllerTest.php b/tests/Controller/CalculationStateControllerTest.php index 8c9961fef..d528bea85 100644 --- a/tests/Controller/CalculationStateControllerTest.php +++ b/tests/Controller/CalculationStateControllerTest.php @@ -13,13 +13,13 @@ namespace App\Tests\Controller; use App\Controller\CalculationStateController; -use App\Entity\CalculationState; +use App\Tests\EntityTrait\CalculationStateTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(CalculationStateController::class)] class CalculationStateControllerTest extends AbstractControllerTestCase { - private static ?CalculationState $entity = null; + use CalculationStateTrait; public static function getRoutes(): array { @@ -59,11 +59,7 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$entity instanceof CalculationState) { - self::$entity = new CalculationState(); - self::$entity->setCode('Test Code'); - $this->addEntity(self::$entity); - } + $this->getCalculationState(); } /** @@ -71,6 +67,6 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$entity = $this->deleteEntity(self::$entity); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CategoryControllerTest.php b/tests/Controller/CategoryControllerTest.php index 3724ca0e9..555d5c9d2 100644 --- a/tests/Controller/CategoryControllerTest.php +++ b/tests/Controller/CategoryControllerTest.php @@ -13,15 +13,15 @@ namespace App\Tests\Controller; use App\Controller\CategoryController; -use App\Entity\Category; -use App\Entity\Group; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(CategoryController::class)] class CategoryControllerTest extends AbstractControllerTestCase { - private static ?Category $entity = null; - private static ?Group $group = null; + use CategoryTrait; + use GroupTrait; public static function getRoutes(): array { @@ -65,17 +65,7 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Parent'); - $this->addEntity(self::$group); - } - if (!self::$entity instanceof Category) { - self::$entity = new Category(); - self::$entity->setCode('Test Code') - ->setGroup(self::$group); - $this->addEntity(self::$entity); - } + $this->getCategory($this->getGroup()); } /** @@ -83,7 +73,7 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$entity = $this->deleteEntity(self::$entity); - self::$group = $this->deleteEntity(self::$group); + $this->deleteCategory(); + $this->deleteGroup(); } } diff --git a/tests/Controller/ChartControllerTest.php b/tests/Controller/ChartControllerTest.php index be0b764c4..f0c97fe21 100644 --- a/tests/Controller/ChartControllerTest.php +++ b/tests/Controller/ChartControllerTest.php @@ -13,40 +13,43 @@ namespace App\Tests\Controller; use App\Controller\ChartController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; +use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(ChartController::class)] class ChartControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; + use ProductTrait; - public static function getRoutes(): array + public static function getRoutes(): \Generator { - return [ - ['/chart/month', self::ROLE_USER], - ['/chart/month', self::ROLE_ADMIN], - ['/chart/month', self::ROLE_SUPER_ADMIN], - - ['/chart/month/pdf', self::ROLE_USER], - ['/chart/month/pdf', self::ROLE_ADMIN], - ['/chart/month/pdf', self::ROLE_SUPER_ADMIN], - - ['/chart/state', self::ROLE_USER], - ['/chart/state', self::ROLE_ADMIN], - ['/chart/state', self::ROLE_SUPER_ADMIN], - - ['/chart/state/pdf', self::ROLE_USER], - ['/chart/state/pdf', self::ROLE_ADMIN], - ['/chart/state/pdf', self::ROLE_SUPER_ADMIN], + $routes = [ + '/chart/month', + '/chart/month/pdf', + '/chart/state', + '/chart/state/pdf', ]; + $users = [ + self::ROLE_USER, + self::ROLE_ADMIN, + self::ROLE_SUPER_ADMIN, + ]; + foreach ($routes as $route) { + foreach ($users as $user) { + yield [$route, $user]; + } + } + foreach ($routes as $route) { + yield [$route, self::ROLE_DISABLED, Response::HTTP_FORBIDDEN]; + } } /** @@ -54,37 +57,13 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test description') - ->setPrice(125.00) - ->setCategory(self::$category); - $this->addEntity(self::$product); - } - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state); - $this->addEntity(self::$calculation); - self::$calculation->addProduct(self::$product, 12.5); - } + $group = $this->getGroup(); + $category = $this->getCategory($group); + $product = $this->getProduct($category); + $state = $this->getCalculationState(); + $calculation = $this->getCalculation($state); + $calculation->addProduct($product, 12.5); + $this->updateCalculation(); } /** @@ -92,10 +71,10 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$product = $this->deleteEntity(self::$product); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/CustomerControllerTest.php b/tests/Controller/CustomerControllerTest.php index edfecd815..e3b0ee06d 100644 --- a/tests/Controller/CustomerControllerTest.php +++ b/tests/Controller/CustomerControllerTest.php @@ -19,7 +19,7 @@ #[\PHPUnit\Framework\Attributes\CoversClass(CustomerController::class)] class CustomerControllerTest extends AbstractControllerTestCase { - private static ?Customer $entity = null; + private ?Customer $entity = null; public static function getRoutes(): array { @@ -59,10 +59,10 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$entity instanceof Customer) { - self::$entity = new Customer(); - self::$entity->setCompany('Test Company'); - $this->addEntity(self::$entity); + if (!$this->entity instanceof Customer) { + $this->entity = new Customer(); + $this->entity->setCompany('Test Company'); + $this->addEntity($this->entity); } } @@ -71,6 +71,6 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$entity = $this->deleteEntity(self::$entity); + $this->entity = $this->deleteEntity($this->entity); } } diff --git a/tests/Controller/GlobalMarginControllerTest.php b/tests/Controller/GlobalMarginControllerTest.php index 2b01fdf5a..ec6b2ef93 100644 --- a/tests/Controller/GlobalMarginControllerTest.php +++ b/tests/Controller/GlobalMarginControllerTest.php @@ -13,13 +13,13 @@ namespace App\Tests\Controller; use App\Controller\GlobalMarginController; -use App\Entity\GlobalMargin; +use App\Tests\EntityTrait\GlobalMarginTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(GlobalMarginController::class)] class GlobalMarginControllerTest extends AbstractControllerTestCase { - private static ?GlobalMargin $entity = null; + use GlobalMarginTrait; public static function getRoutes(): array { @@ -51,13 +51,7 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$entity instanceof GlobalMargin) { - self::$entity = new GlobalMargin(); - self::$entity->setMinimum(0) - ->setMaximum(100) - ->setMargin(0.1); - $this->addEntity(self::$entity); - } + $this->getGlobalMargin(); } /** @@ -65,6 +59,6 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$entity = $this->deleteEntity(self::$entity); + $this->deleteGlobalMargin(); } } diff --git a/tests/Controller/GroupControllerTest.php b/tests/Controller/GroupControllerTest.php index 95ce8fe30..b55bd4e20 100644 --- a/tests/Controller/GroupControllerTest.php +++ b/tests/Controller/GroupControllerTest.php @@ -13,13 +13,13 @@ namespace App\Tests\Controller; use App\Controller\GroupController; -use App\Entity\Group; +use App\Tests\EntityTrait\GroupTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(GroupController::class)] class GroupControllerTest extends AbstractControllerTestCase { - private static ?Group $entity = null; + use GroupTrait; public static function getRoutes(): array { @@ -63,11 +63,7 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$entity instanceof Group) { - self::$entity = new Group(); - self::$entity->setCode('Test Code'); - $this->addEntity(self::$entity); - } + $this->getGroup(); } /** @@ -75,6 +71,6 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$entity = $this->deleteEntity(self::$entity); + $this->deleteGroup(); } } diff --git a/tests/Controller/IndexControllerTest.php b/tests/Controller/IndexControllerTest.php index d6f3a7074..bcade28f1 100644 --- a/tests/Controller/IndexControllerTest.php +++ b/tests/Controller/IndexControllerTest.php @@ -20,6 +20,7 @@ class IndexControllerTest extends AbstractControllerTestCase public static function getRoutes(): array { return [ + ['/', self::ROLE_DISABLED], ['/', self::ROLE_USER], ['/', self::ROLE_ADMIN], ['/', self::ROLE_SUPER_ADMIN], diff --git a/tests/Controller/LogControllerTest.php b/tests/Controller/LogControllerTest.php index 68d4202a0..81ede714e 100644 --- a/tests/Controller/LogControllerTest.php +++ b/tests/Controller/LogControllerTest.php @@ -25,7 +25,6 @@ class LogControllerTest extends AbstractControllerTestCase protected function setUp(): void { parent::setUp(); - $logger = $this->getService(LoggerInterface::class); $logger->info('LogControllerTest: A message for testing purposes.'); } @@ -33,25 +32,40 @@ protected function setUp(): void public static function getRoutes(): array { return [ + ['/log', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], ['/log', self::ROLE_USER, Response::HTTP_FORBIDDEN], ['/log', self::ROLE_ADMIN], ['/log', self::ROLE_SUPER_ADMIN], + ['/log/delete', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], ['/log/delete', self::ROLE_USER, Response::HTTP_FORBIDDEN], ['/log/delete', self::ROLE_ADMIN], ['/log/delete', self::ROLE_SUPER_ADMIN], + ['/log/download', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], + ['/log/download', self::ROLE_USER, Response::HTTP_FORBIDDEN], + ['/log/download', self::ROLE_ADMIN], + ['/log/download', self::ROLE_SUPER_ADMIN], + + ['/log/excel', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], ['/log/excel', self::ROLE_USER, Response::HTTP_FORBIDDEN], ['/log/excel', self::ROLE_ADMIN], ['/log/excel', self::ROLE_SUPER_ADMIN], + ['/log/refresh', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], + ['/log/refresh', self::ROLE_USER, Response::HTTP_FORBIDDEN], + ['/log/refresh', self::ROLE_ADMIN, Response::HTTP_FOUND], + ['/log/refresh', self::ROLE_SUPER_ADMIN, Response::HTTP_FOUND], + + ['/log/pdf', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], ['/log/pdf', self::ROLE_USER, Response::HTTP_FORBIDDEN], ['/log/pdf', self::ROLE_ADMIN], ['/log/pdf', self::ROLE_SUPER_ADMIN], - ['/log/refresh', self::ROLE_USER, Response::HTTP_FORBIDDEN], - ['/log/refresh', self::ROLE_ADMIN, Response::HTTP_FOUND], - ['/log/refresh', self::ROLE_SUPER_ADMIN, Response::HTTP_FOUND], + ['/log/show/1', self::ROLE_DISABLED, Response::HTTP_FORBIDDEN], + ['/log/show/1', self::ROLE_USER, Response::HTTP_FORBIDDEN], + ['/log/show/1', self::ROLE_ADMIN], + ['/log/show/1', self::ROLE_SUPER_ADMIN], ]; } } diff --git a/tests/Controller/PivotControllerTest.php b/tests/Controller/PivotControllerTest.php index f30f87fd8..87952239e 100644 --- a/tests/Controller/PivotControllerTest.php +++ b/tests/Controller/PivotControllerTest.php @@ -13,21 +13,21 @@ namespace App\Tests\Controller; use App\Controller\PivotController; -use App\Entity\Calculation; -use App\Entity\CalculationState; -use App\Entity\Category; -use App\Entity\Group; use App\Entity\GroupMargin; -use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CalculationTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; #[\PHPUnit\Framework\Attributes\CoversClass(PivotController::class)] class PivotControllerTest extends AbstractControllerTestCase { - private static ?Calculation $calculation = null; - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; - private static ?CalculationState $state = null; + use CalculationStateTrait; + use CalculationTrait; + use CategoryTrait; + use GroupTrait; + use ProductTrait; public static function getRoutes(): array { @@ -43,46 +43,23 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test State'); - $this->addEntity(self::$state); - } + $margin = new GroupMargin(); + $margin->setMinimum(0) + ->setMaximum(1000) + ->setMargin(0.1); + $group = $this->getGroup() + ->addMargin($margin); + $this->addEntity($group); - if (!self::$group instanceof Group) { - $margin = new GroupMargin(); - $margin->setMinimum(0) - ->setMaximum(1000) - ->setMargin(0.1); - self::$group = new Group(); - self::$group->setCode('Test Group'); - self::$group->addMargin($margin); - $this->addEntity(self::$group); - } + $category = $this->getCategory($group); + $product = $this->getProduct($category) + ->setPrice(10.0); + $this->addEntity($product); - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test Product') - ->setPrice(10.0) - ->setCategory(self::$category); - $this->addEntity(self::$product); - } - - if (!self::$calculation instanceof Calculation) { - self::$calculation = new Calculation(); - self::$calculation->setCustomer('Test Customer') - ->setDescription('Test Description') - ->setState(self::$state) - ->addProduct(self::$product, 10.0); - $this->addEntity(self::$calculation); - } + $state = $this->getCalculationState(); + $calculation = $this->getCalculation($state) + ->addProduct($product, 10.0); + $this->addEntity($calculation); } /** @@ -90,10 +67,10 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$calculation = $this->deleteEntity(self::$calculation); - self::$product = $this->deleteEntity(self::$product); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); + $this->deleteCalculation(); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); } } diff --git a/tests/Controller/ProductControllerTest.php b/tests/Controller/ProductControllerTest.php index e43939ffe..031052c26 100644 --- a/tests/Controller/ProductControllerTest.php +++ b/tests/Controller/ProductControllerTest.php @@ -13,17 +13,17 @@ namespace App\Tests\Controller; use App\Controller\ProductController; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Product; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\ProductTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(ProductController::class)] class ProductControllerTest extends AbstractControllerTestCase { - private static ?Category $category = null; - private static ?Group $group = null; - private static ?Product $product = null; + use CategoryTrait; + use GroupTrait; + use ProductTrait; public static function getRoutes(): array { @@ -67,25 +67,9 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - - if (!self::$product instanceof Product) { - self::$product = new Product(); - self::$product->setDescription('Test Product') - ->setCategory(self::$category); - $this->addEntity(self::$product); - } + $group = $this->getGroup(); + $category = $this->getCategory($group); + $this->getProduct($category); } /** @@ -93,8 +77,8 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$product = $this->deleteEntity(self::$product); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); + $this->deleteProduct(); + $this->deleteCategory(); + $this->deleteGroup(); } } diff --git a/tests/Controller/TaskControllerTest.php b/tests/Controller/TaskControllerTest.php index 06d154dcb..99f32cfcd 100644 --- a/tests/Controller/TaskControllerTest.php +++ b/tests/Controller/TaskControllerTest.php @@ -13,19 +13,19 @@ namespace App\Tests\Controller; use App\Controller\TaskController; -use App\Entity\Category; -use App\Entity\Group; -use App\Entity\Task; -use App\Entity\TaskItem; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; +use App\Tests\EntityTrait\TaskItemTrait; +use App\Tests\EntityTrait\TaskTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(TaskController::class)] class TaskControllerTest extends AbstractControllerTestCase { - private static ?Category $category = null; - private static ?Task $entity = null; - private static ?Group $group = null; - private static ?TaskItem $item = null; + use CategoryTrait; + use GroupTrait; + use TaskItemTrait; + use TaskTrait; public static function getRoutes(): array { @@ -77,29 +77,10 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (!self::$entity instanceof Task) { - self::$entity = new Task(); - self::$entity->setName('Test Task') - ->setCategory(self::$category); - $this->addEntity(self::$entity); - } - if (!self::$item instanceof TaskItem) { - self::$item = new TaskItem(); - self::$item->setName('Test Item'); - self::$item->setTask(self::$entity); - $this->addEntity(self::$item); - } + $group = $this->getGroup(); + $category = $this->getCategory($group); + $task = $this->getTask($category); + $this->getTaskItem($task); } /** @@ -107,9 +88,9 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - self::$item = $this->deleteEntity(self::$item); - self::$entity = $this->deleteEntity(self::$entity); - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); + $this->deleteTaskItem(); + $this->deleteTask(); + $this->deleteCategory(); + $this->deleteGroup(); } } diff --git a/tests/Controller/ThemeControllerTest.php b/tests/Controller/ThemeControllerTest.php index 1b99c7481..1a55531e9 100644 --- a/tests/Controller/ThemeControllerTest.php +++ b/tests/Controller/ThemeControllerTest.php @@ -19,16 +19,26 @@ #[\PHPUnit\Framework\Attributes\CoversClass(ThemeController::class)] class ThemeControllerTest extends AbstractControllerTestCase { - private const ROUTES = ['/theme/dialog', '/theme/save']; - - private const USERS = [self::ROLE_USER, self::ROLE_ADMIN, self::ROLE_SUPER_ADMIN]; - public static function getRoutes(): \Generator { - foreach (self::ROUTES as $route) { - foreach (self::USERS as $user) { + $routes = [ + '/theme/dialog', + '/theme/save', + ]; + $users = [ + self::ROLE_USER, + self::ROLE_ADMIN, + self::ROLE_SUPER_ADMIN, + ]; + + foreach ($routes as $route) { + foreach ($users as $user) { yield [$route, $user, Response::HTTP_OK, Request::METHOD_GET, true]; } } + + foreach ($routes as $route) { + yield [$route, self::ROLE_DISABLED, Response::HTTP_FORBIDDEN, Request::METHOD_GET, true]; + } } } diff --git a/tests/Controller/UpdateEntityControllerTest.php b/tests/Controller/UpdateEntityControllerTest.php index 71c7cfd85..8872be79d 100644 --- a/tests/Controller/UpdateEntityControllerTest.php +++ b/tests/Controller/UpdateEntityControllerTest.php @@ -13,22 +13,23 @@ namespace App\Tests\Controller; use App\Controller\UpdateEntityController; -use App\Entity\CalculationState; -use App\Entity\Category; use App\Entity\Customer; -use App\Entity\Group; use App\Entity\Product; +use App\Tests\EntityTrait\CalculationStateTrait; +use App\Tests\EntityTrait\CategoryTrait; +use App\Tests\EntityTrait\GroupTrait; use Symfony\Component\HttpFoundation\Response; #[\PHPUnit\Framework\Attributes\CoversClass(UpdateEntityController::class)] class UpdateEntityControllerTest extends AbstractControllerTestCase { - private static ?Category $category = null; - private static ?Customer $customer = null; - private static ?Group $group = null; + use CalculationStateTrait; + use CategoryTrait; + use GroupTrait; + + private ?Customer $customer = null; /** @var Product[]|null */ - private static ?array $products = null; - private static ?CalculationState $state = null; + private ?array $products = null; public static function getRoutes(): array { @@ -52,36 +53,23 @@ public static function getRoutes(): array */ protected function addEntities(): void { - if (!self::$customer instanceof Customer) { - self::$customer = new Customer(); - self::$customer->setCompany('Test Company'); - $this->addEntity(self::$customer); - } + $this->getCalculationState(); + $group = $this->getGroup(); + $category = $this->getCategory($group); - if (!self::$state instanceof CalculationState) { - self::$state = new CalculationState(); - self::$state->setCode('Test Code'); - $this->addEntity(self::$state); + if (!$this->customer instanceof Customer) { + $this->customer = new Customer(); + $this->customer->setCompany('Test Company'); + $this->addEntity($this->customer); } - if (!self::$group instanceof Group) { - self::$group = new Group(); - self::$group->setCode('Test Group'); - $this->addEntity(self::$group); - } - if (!self::$category instanceof Category) { - self::$category = new Category(); - self::$category->setCode('Test Category') - ->setGroup(self::$group); - $this->addEntity(self::$category); - } - if (null === self::$products) { + if (null === $this->products) { for ($i = 0; $i < 15; ++$i) { $product = new Product(); $product->setDescription("Test Product $i") - ->setCategory(self::$category); + ->setCategory($category); $this->addEntity($product); - self::$products[] = $product; + $this->products[] = $product; } } } @@ -91,15 +79,15 @@ protected function addEntities(): void */ protected function deleteEntities(): void { - if (null !== self::$products) { - foreach (self::$products as $product) { + if (null !== $this->products) { + foreach ($this->products as $product) { $this->deleteEntity($product); } - self::$products = null; + $this->products = null; } - self::$category = $this->deleteEntity(self::$category); - self::$group = $this->deleteEntity(self::$group); - self::$state = $this->deleteEntity(self::$state); - self::$customer = $this->deleteEntity(self::$customer); + $this->deleteCategory(); + $this->deleteGroup(); + $this->deleteCalculationState(); + $this->customer = $this->deleteEntity($this->customer); } } diff --git a/tests/EntityTrait/CalculationStateTrait.php b/tests/EntityTrait/CalculationStateTrait.php new file mode 100644 index 000000000..33c3ac74e --- /dev/null +++ b/tests/EntityTrait/CalculationStateTrait.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\CalculationState; + +/** + * Trait to manage a calculation state. + */ +trait CalculationStateTrait +{ + private ?CalculationState $calculationState = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteCalculationState(): void + { + if ($this->calculationState instanceof CalculationState) { + $this->calculationState = $this->deleteEntity($this->calculationState); + } + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function getCalculationState(string $code = 'Test State'): CalculationState + { + if (!$this->calculationState instanceof CalculationState) { + $this->calculationState = new CalculationState(); + $this->calculationState->setCode($code); + $this->addEntity($this->calculationState); + } + + return $this->calculationState; // @phpstan-ignore-line + } +} diff --git a/tests/EntityTrait/CalculationTrait.php b/tests/EntityTrait/CalculationTrait.php new file mode 100644 index 000000000..fd507bcae --- /dev/null +++ b/tests/EntityTrait/CalculationTrait.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Calculation; +use App\Entity\CalculationState; +use App\Service\CalculationService; + +/** + * Trait to manage a calculation. + */ +trait CalculationTrait +{ + private ?Calculation $calculation = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + public function getCalculation(CalculationState $state, string $customer = 'Test Customer', string $description = 'Test Description'): Calculation + { + if (!$this->calculation instanceof Calculation) { + $this->calculation = new Calculation(); + $this->calculation->setState($state) + ->setCustomer($customer) + ->setDescription($description); + $this->addEntity($this->calculation); + } + + return $this->calculation; // @phpstan-ignore-line + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + * @throws \Exception + */ + public function updateCalculation(): void + { + if ($this->calculation instanceof Calculation) { + $service = self::getContainer()->get(CalculationService::class); + // @phpstan-ignore-next-line + $service->updateTotal($this->calculation); + $this->addEntity($this->calculation); + } + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteCalculation(): void + { + if ($this->calculation instanceof Calculation) { + $this->calculation = $this->deleteEntity($this->calculation); + } + } +} diff --git a/tests/EntityTrait/CategoryTrait.php b/tests/EntityTrait/CategoryTrait.php new file mode 100644 index 000000000..26f865116 --- /dev/null +++ b/tests/EntityTrait/CategoryTrait.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Category; +use App\Entity\Group; + +/** + * Trait to manage a category. + */ +trait CategoryTrait +{ + private ?Category $category = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + public function getCategory(Group $group, string $code = 'Test Category'): Category + { + if (!$this->category instanceof Category) { + $this->category = new Category(); + $this->category->setGroup($group) + ->setCode($code); + $this->addEntity($this->category); + } + + return $this->category; // @phpstan-ignore-line + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteCategory(): void + { + if ($this->category instanceof Category) { + $this->category = $this->deleteEntity($this->category); + } + } +} diff --git a/tests/EntityTrait/GlobalMarginTrait.php b/tests/EntityTrait/GlobalMarginTrait.php new file mode 100644 index 000000000..bb096e682 --- /dev/null +++ b/tests/EntityTrait/GlobalMarginTrait.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\GlobalMargin; + +/** + * Trait to manage a global margin. + */ +trait GlobalMarginTrait +{ + private ?GlobalMargin $globalMargin = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteGlobalMargin(): void + { + if ($this->globalMargin instanceof GlobalMargin) { + $this->globalMargin = $this->deleteEntity($this->globalMargin); + } + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function getGlobalMargin(float $minimum = 1.0, float $maximum = 100.0, float $margin = 0.1): GlobalMargin + { + if (!$this->globalMargin instanceof GlobalMargin) { + $this->globalMargin = new GlobalMargin(); + $this->globalMargin->setMinimum($minimum) + ->setMaximum($maximum) + ->setMargin($margin); + $this->addEntity($this->globalMargin); + } + + return $this->globalMargin; // @phpstan-ignore-line + } +} diff --git a/tests/EntityTrait/GroupTrait.php b/tests/EntityTrait/GroupTrait.php new file mode 100644 index 000000000..51cc39d3f --- /dev/null +++ b/tests/EntityTrait/GroupTrait.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Group; + +/** + * Trait to manage a group. + */ +trait GroupTrait +{ + private ?Group $group = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + public function getGroup(string $code = 'Test Group'): Group + { + if (!$this->group instanceof Group) { + $this->group = new Group(); + $this->group->setCode($code); + $this->addEntity($this->group); + } + + return $this->group; // @phpstan-ignore-line + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteGroup(): void + { + if ($this->group instanceof Group) { + $this->group = $this->deleteEntity($this->group); + } + } +} diff --git a/tests/EntityTrait/ProductTrait.php b/tests/EntityTrait/ProductTrait.php new file mode 100644 index 000000000..c82217f30 --- /dev/null +++ b/tests/EntityTrait/ProductTrait.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Category; +use App\Entity\Product; + +/** + * Trait to manage a product. + */ +trait ProductTrait +{ + private ?Product $product = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + public function getProduct(Category $category, float $price = 1.0, string $description = 'Test description'): Product + { + if (!$this->product instanceof Product) { + $this->product = new Product(); + $this->product->setCategory($category) + ->setPrice($price) + ->setDescription($description); + $this->addEntity($this->product); + } + + return $this->product; // @phpstan-ignore-line + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteProduct(): void + { + if ($this->product instanceof Product) { + $this->product = $this->deleteEntity($this->product); + } + } +} diff --git a/tests/EntityTrait/TaskItemTrait.php b/tests/EntityTrait/TaskItemTrait.php new file mode 100644 index 000000000..cfd0fc07d --- /dev/null +++ b/tests/EntityTrait/TaskItemTrait.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Task; +use App\Entity\TaskItem; + +/** + * Trait to manage a task item. + */ +trait TaskItemTrait +{ + private ?TaskItem $taskItem = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteTaskItem(): void + { + if ($this->taskItem instanceof TaskItem) { + $this->taskItem = $this->deleteEntity($this->taskItem); + } + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function getTaskItem(Task $task, string $name = 'Test Task Item'): TaskItem + { + if (!$this->taskItem instanceof TaskItem) { + $this->taskItem = new TaskItem(); + $this->taskItem->setTask($task) + ->setName($name); + $this->addEntity($this->taskItem); + } + + return $this->taskItem; // @phpstan-ignore-line + } +} diff --git a/tests/EntityTrait/TaskTrait.php b/tests/EntityTrait/TaskTrait.php new file mode 100644 index 000000000..85d959c05 --- /dev/null +++ b/tests/EntityTrait/TaskTrait.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace App\Tests\EntityTrait; + +use App\Entity\Category; +use App\Entity\Task; + +/** + * Trait to manage a task. + */ +trait TaskTrait +{ + private ?Task $task = null; + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function deleteTask(): void + { + if ($this->task instanceof Task) { + $this->task = $this->deleteEntity($this->task); + } + } + + /** + * @throws \Doctrine\ORM\Exception\ORMException + */ + protected function getTask(Category $category, string $name = 'Test Task'): Task + { + if (!$this->task instanceof Task) { + $this->task = new Task(); + $this->task->setCategory($category) + ->setName($name); + $this->addEntity($this->task); + } + + return $this->task; // @phpstan-ignore-line + } +} diff --git a/translations/messages+intl-icu.fr_CH.yaml b/translations/messages+intl-icu.fr_CH.yaml index f3118385e..48d9460d9 100644 --- a/translations/messages+intl-icu.fr_CH.yaml +++ b/translations/messages+intl-icu.fr_CH.yaml @@ -195,13 +195,13 @@ counters: {count, plural, =0 {Aucun statut} one {1 statut} - other {# status} + other {# statuts} } states_lower: >- {count, plural, =0 {aucun statut} one {1 statut} - other {# status} + other {# statuts} } users: >- {count, plural, diff --git a/translations/messages.fr_CH.yaml b/translations/messages.fr_CH.yaml index 846b7262f..35979332c 100644 --- a/translations/messages.fr_CH.yaml +++ b/translations/messages.fr_CH.yaml @@ -144,7 +144,7 @@ calculation: description: Cette page vous permet de recalculer et de mettre à jour le total général des calculations. dateFrom: Date de début dateTo: Date de fin - states: Status + states: Statuts submit: Mettre à jour last_update: 'Dernière mise à jour : %date%' result: @@ -852,7 +852,7 @@ parameters: panel_calculation: Nombre de calculations à afficher. panel_catalog: Afficher le nombre d'objets du catalogue (base de données). panel_month: Afficher la liste des calculations regroupées par mois. - panel_state: Afficher la liste des calculations regroupées par status. + panel_state: Afficher la liste des calculations regroupées par statut. print_address: L'adresse du client est imprimée sur les entêtes des documents Excel®, Word® et PDF. qr_code: Un code QR est imprimé à la fin du document PDF permettant d'afficher la calculation. status_bar: Afficher la barre d'état au bas de l'application. @@ -1417,7 +1417,7 @@ archive: fields: date: Date limite target: Nouveau statut - sources: Anciens status + sources: Anciens statuts notification: csp_title: Violation de règles CSP csp_description: L'agent utilisateur de l'application %name% a rapporté des violations des règles de la politique de sécurité de contenu (Content Security Policy).