From 43b3e1896c105f4cd151003f0117685058f2c6c7 Mon Sep 17 00:00:00 2001 From: Nicolas Joubert Date: Fri, 9 Oct 2026 09:45:01 +0200 Subject: [PATCH] #18 PHPStan level 10 Co-Authored-By: Claude Opus 5.5 (1M context) --- CHANGELOG.md | 3 +++ phpstan.neon | 2 +- src/Admin/Filter/LogProcessFilter.php | 3 ++- src/Command/UserCreateCommand.php | 4 ++++ .../Admin/LogRecordCrudController.php | 4 +++- src/Controller/Admin/Process/LaunchAction.php | 10 +++++----- .../Admin/ProcessDashboardController.php | 1 + src/Controller/Admin/UserCrudController.php | 11 +++++++---- src/Controller/ProcessExecuteController.php | 12 ++++++------ .../CleverAgeUiProcessExtension.php | 7 +++++++ src/Entity/LogRecord.php | 2 +- src/Entity/ProcessExecution.php | 3 +++ src/Entity/ProcessSchedule.php | 8 +++++++- src/Form/Type/LaunchType.php | 3 ++- .../HttpProcessExecuteValueResolver.php | 1 + src/Manager/ProcessConfigurationsManager.php | 17 ++++++++++++++--- src/Manager/ProcessExecutionManager.php | 10 ++++++---- src/Message/CronProcessMessageHandler.php | 4 +++- src/Repository/ProcessExecutionRepository.php | 6 ++++-- tests/DependencyInjection/ConfigurationTest.php | 6 +++++- tests/Functional/LaunchActionTest.php | 2 ++ tests/Functional/ProcessScheduleCrudTest.php | 3 +++ tests/Functional/UserCrudTest.php | 2 ++ .../ProcessConfigurationsManagerTest.php | 11 ++++++++--- ...ProcessExecutionManagerEntityManagerTest.php | 6 +++++- tests/Notifier/ProcessExecutionNotifierTest.php | 4 +++- 26 files changed, 108 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dd13af..fb3a02d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ Latest ------ +## Changes +* [#18](https://github.com/cleverage/ui-process-bundle/issues/18) PHPStan level 10 (was 8), on `src` and `tests`: `LogProcessFilter::new()` `$label` typed as `TranslatableInterface|string|false|null` (the type of `setLabel()`), `LogRecord::$context` documented as `array` (the Monolog context), conditional return type of `ProcessExecution::getReport()`. + v3.1 ------ diff --git a/phpstan.neon b/phpstan.neon index 1cd333b..e9a9e7e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ parameters: - level: 8 + level: 10 paths: - src - tests diff --git a/src/Admin/Filter/LogProcessFilter.php b/src/Admin/Filter/LogProcessFilter.php index 173d45a..1a78932 100644 --- a/src/Admin/Filter/LogProcessFilter.php +++ b/src/Admin/Filter/LogProcessFilter.php @@ -21,6 +21,7 @@ use EasyCorp\Bundle\EasyAdminBundle\Filter\FilterTrait; use EasyCorp\Bundle\EasyAdminBundle\Form\Filter\Type\ChoiceFilterType; use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType; +use Symfony\Contracts\Translation\TranslatableInterface; class LogProcessFilter implements FilterInterface { @@ -30,7 +31,7 @@ class LogProcessFilter implements FilterInterface * @param string[] $choices */ public static function new( - mixed $label, + TranslatableInterface|string|false|null $label, array $choices, string|int|null $executionId = null, ): self { diff --git a/src/Command/UserCreateCommand.php b/src/Command/UserCreateCommand.php index 55b323b..b75ea90 100644 --- a/src/Command/UserCreateCommand.php +++ b/src/Command/UserCreateCommand.php @@ -72,6 +72,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int ); } + /** + * @var string $username + * @var string $password + */ $user = new User(); $user->setEmail($username); $user->setRoles(['ROLE_USER', 'ROLE_ADMIN']); diff --git a/src/Controller/Admin/LogRecordCrudController.php b/src/Controller/Admin/LogRecordCrudController.php index 38caf6a..a2efbfd 100644 --- a/src/Controller/Admin/LogRecordCrudController.php +++ b/src/Controller/Admin/LogRecordCrudController.php @@ -89,7 +89,9 @@ public function configureActions(Actions $actions): Actions #[\Override] public function configureFilters(Filters $filters): Filters { - $id = $this->requestStack->getMainRequest()?->query->all('filters')['process']['value'] ?? null; + /** @var array{process?: array{value?: string|int|null}} $queryFilters */ + $queryFilters = $this->requestStack->getMainRequest()?->query->all('filters') ?? []; + $id = $queryFilters['process']['value'] ?? null; $processList = $this->processConfigurationsManager->getPublicProcesses(); $processList = array_map(static fn (ProcessConfiguration $cfg) => $cfg->getCode(), $processList); diff --git a/src/Controller/Admin/Process/LaunchAction.php b/src/Controller/Admin/Process/LaunchAction.php index 07fc58e..067af7d 100644 --- a/src/Controller/Admin/Process/LaunchAction.php +++ b/src/Controller/Admin/Process/LaunchAction.php @@ -98,11 +98,11 @@ public function __invoke( (new Filesystem())->dumpFile($filename, $input->getContent()); $input = $filename; } - $this->dispatch( - $form->getConfig()->getOption('process_code'), - $input, - $form->get('context')->getData() - ); + /** @var string $processCode */ + $processCode = $form->getConfig()->getOption('process_code'); + /** @var mixed[] $context */ + $context = $form->get('context')->getData(); + $this->dispatch($processCode, $input, $context); $this->addFlash( 'success', 'Process has been added to queue. It will start as soon as possible' diff --git a/src/Controller/Admin/ProcessDashboardController.php b/src/Controller/Admin/ProcessDashboardController.php index 743c7ef..9315a41 100644 --- a/src/Controller/Admin/ProcessDashboardController.php +++ b/src/Controller/Admin/ProcessDashboardController.php @@ -37,6 +37,7 @@ public function __construct( #[\Override] public function index(): Response { + /** @var AdminUrlGenerator $adminUrlGenerator */ $adminUrlGenerator = $this->container->get(AdminUrlGenerator::class); return $this->redirect($adminUrlGenerator->setController(ProcessExecutionCrudController::class)->generateUrl()); diff --git a/src/Controller/Admin/UserCrudController.php b/src/Controller/Admin/UserCrudController.php index 1ce2c92..86e2daa 100644 --- a/src/Controller/Admin/UserCrudController.php +++ b/src/Controller/Admin/UserCrudController.php @@ -14,6 +14,8 @@ namespace CleverAge\UiProcessBundle\Controller\Admin; use CleverAge\UiProcessBundle\Entity\User; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\Persistence\ManagerRegistry; use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminRoute; use EasyCorp\Bundle\EasyAdminBundle\Config\Action; use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; @@ -114,10 +116,11 @@ public function generateToken(): Response $user = $adminContext?->getEntity()->getInstance(); $token = md5(uniqid(date('YmdHis'))); $user->setToken((new Pbkdf2PasswordHasher())->hash($token)); - $this->persistEntity( - $this->container->get('doctrine')->getManagerForClass($adminContext?->getEntity()->getFqcn()), - $user - ); + /** @var ManagerRegistry $doctrine */ + $doctrine = $this->container->get('doctrine'); + /** @var EntityManagerInterface $entityManager */ + $entityManager = $doctrine->getManagerForClass(User::class); + $this->persistEntity($entityManager, $user); $this->addFlash('success', 'New token generated '.$token.' (keep it in secured area. This token will never be displayed anymore)'); return $this->redirect( diff --git a/src/Controller/ProcessExecuteController.php b/src/Controller/ProcessExecuteController.php index 8479fa9..790cd11 100644 --- a/src/Controller/ProcessExecuteController.php +++ b/src/Controller/ProcessExecuteController.php @@ -51,14 +51,16 @@ public function __invoke( } throw new UnprocessableEntityHttpException(implode('. ', $violationsMessages)); } + /** @var mixed[] $context */ + $context = \is_string($httpProcessExecution->context) + ? json_decode($httpProcessExecution->context, true) + : $httpProcessExecution->context; if ($httpProcessExecution->queue) { $this->bus->dispatch( new ProcessExecuteMessage( $httpProcessExecution->code ?? '', $httpProcessExecution->input, - \is_string($httpProcessExecution->context) - ? json_decode($httpProcessExecution->context, true) - : $httpProcessExecution->context + $context ) ); @@ -69,9 +71,7 @@ public function __invoke( $this->processManager->execute( $httpProcessExecution->code ?? '', $httpProcessExecution->input, - \is_string($httpProcessExecution->context) - ? json_decode($httpProcessExecution->context, true) - : $httpProcessExecution->context + $context ); } catch (\Throwable $e) { // The id of the process execution allows to find its logs in the UI diff --git a/src/DependencyInjection/CleverAgeUiProcessExtension.php b/src/DependencyInjection/CleverAgeUiProcessExtension.php index 1dbb986..1cda6b8 100644 --- a/src/DependencyInjection/CleverAgeUiProcessExtension.php +++ b/src/DependencyInjection/CleverAgeUiProcessExtension.php @@ -35,6 +35,13 @@ public function load(array $configs, ContainerBuilder $container): void /** @var string $env */ $env = $container->getParameter('kernel.environment'); $configuration = new Configuration($env); + /** @var array{ + * security: array{roles: list}, + * logs: array{store_in_database: bool, database_level: string, file_level: string, report_increment_level: string}, + * design: array{logo_path: string}, + * notification: array{enabled: bool, ...}, + * } $config + */ $config = $this->processConfiguration($configuration, $configs); $container->getDefinition(UserCrudController::class) diff --git a/src/Entity/LogRecord.php b/src/Entity/LogRecord.php index ab10f2a..a5df596 100644 --- a/src/Entity/LogRecord.php +++ b/src/Entity/LogRecord.php @@ -36,7 +36,7 @@ class LogRecord #[ORM\Column(type: Types::STRING, length: 512)] public readonly string $message; - /** @var array $context */ + /** @var array $context */ #[ORM\Column(type: Types::JSON)] public readonly array $context; diff --git a/src/Entity/ProcessExecution.php b/src/Entity/ProcessExecution.php index dbadef9..acfc7cd 100644 --- a/src/Entity/ProcessExecution.php +++ b/src/Entity/ProcessExecution.php @@ -90,6 +90,9 @@ public function addReport(string $key, mixed $value): void $this->report[$key] = $value; } + /** + * @return ($key is null ? array : mixed) + */ public function getReport(?string $key = null, mixed $default = null): mixed { if (null === $key) { diff --git a/src/Entity/ProcessSchedule.php b/src/Entity/ProcessSchedule.php index f297de4..a9413e0 100644 --- a/src/Entity/ProcessSchedule.php +++ b/src/Entity/ProcessSchedule.php @@ -76,7 +76,13 @@ public function setProcess(string $process): static */ public function getContext(): array { - return \is_array($this->context) ? $this->context : json_decode($this->context, true); + if (\is_array($this->context)) { + return $this->context; + } + /** @var array $context */ + $context = json_decode($this->context, true); + + return $context; } /** diff --git a/src/Form/Type/LaunchType.php b/src/Form/Type/LaunchType.php index 87f51a1..35551e1 100644 --- a/src/Form/Type/LaunchType.php +++ b/src/Form/Type/LaunchType.php @@ -36,6 +36,7 @@ public function __construct( public function buildForm(FormBuilderInterface $builder, array $options): void { + /** @var string $code */ $code = $options['process_code']; $configuration = $this->registry->getProcessConfiguration($code); $uiOptions = $this->configurationsManager->getUiOptions($code); @@ -62,7 +63,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void static fn ($data) => $data ?? [], // A row without key is left out (it is reported by the NotBlank constraint of ProcessContextType): a null // key is deprecated as array offset, and an empty key breaks the property paths of the process constraints - static fn ($data) => array_column( + static fn (?array $data) => array_column( array_filter($data ?? [], static fn ($row): bool => \is_array($row) && null !== ($row['key'] ?? null) && '' !== $row['key']), 'value', 'key' diff --git a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php index 9abedbd..ec05a78 100644 --- a/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php +++ b/src/Http/ValueResolver/HttpProcessExecuteValueResolver.php @@ -71,6 +71,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable ? $request->request->getBoolean('queue') : $request->query->getBoolean('queue', true); + /** @var string|null $input */ $httpProcessExecution = new HttpProcessExecution( (string) $code, $input, diff --git a/src/Manager/ProcessConfigurationsManager.php b/src/Manager/ProcessConfigurationsManager.php index fa8bfce..4572a4b 100644 --- a/src/Manager/ProcessConfigurationsManager.php +++ b/src/Manager/ProcessConfigurationsManager.php @@ -102,7 +102,12 @@ private function resolveOptions(array $options): array $notificationResolver->setDefaults(['enabled' => null, 'statuses' => null, 'channels' => null, 'recipients' => null]); $notificationResolver->setAllowedTypes('enabled', ['null', 'bool']); $notificationResolver->setAllowedTypes('statuses', ['null', 'string[]']); - $notificationResolver->setAllowedValues('statuses', static fn (?array $statuses): bool => null === $statuses || [] === array_diff($statuses, NotificationTrigger::values())); + $notificationResolver->setAllowedValues('statuses', static function (?array $statuses): bool { + /** @var string[]|null $statusValues */ + $statusValues = $statuses; + + return null === $statusValues || [] === array_diff($statusValues, NotificationTrigger::values()); + }); $notificationResolver->setAllowedTypes('channels', ['null', 'string[]']); $notificationResolver->setAllowedTypes('recipients', ['null', 'array[]']); $notificationResolver->setNormalizer('recipients', static function (Options $options, ?array $recipients): ?array { @@ -122,7 +127,10 @@ private function resolveOptions(array $options): array return $phone; }); - return array_values(array_map($recipientResolver->resolve(...), $recipients)); + /** @var array> $recipientRows */ + $recipientRows = $recipients; + + return array_values(array_map($recipientResolver->resolve(...), $recipientRows)); }); return $notificationResolver->resolve($notification); @@ -154,7 +162,10 @@ private function resolveOptions(array $options): array $contextResolver = new OptionsResolver(); $contextResolver->setRequired(['key', 'value']); - return array_map($contextResolver->resolve(...), $context); + /** @var array> $contextRows */ + $contextRows = $context; + + return array_map($contextResolver->resolve(...), $contextRows); }); return $defaultResolver->resolve($default); diff --git a/src/Manager/ProcessExecutionManager.php b/src/Manager/ProcessExecutionManager.php index 5ae115b..1444940 100644 --- a/src/Manager/ProcessExecutionManager.php +++ b/src/Manager/ProcessExecutionManager.php @@ -81,10 +81,12 @@ public function save(): self public function increment(string $incrementKey, int $step = 1): void { - $this->currentProcessExecution?->addReport( - $incrementKey, - $this->currentProcessExecution->getReport($incrementKey, 0) + $step - ); + if (!$this->currentProcessExecution instanceof ProcessExecution) { + return; + } + /** @var int $count */ + $count = $this->currentProcessExecution->getReport($incrementKey, 0); + $this->currentProcessExecution->addReport($incrementKey, $count + $step); } public function setReport(string $incrementKey, string $value): void diff --git a/src/Message/CronProcessMessageHandler.php b/src/Message/CronProcessMessageHandler.php index 13ab26c..e6a20d5 100644 --- a/src/Message/CronProcessMessageHandler.php +++ b/src/Message/CronProcessMessageHandler.php @@ -26,7 +26,9 @@ public function __construct(private MessageBusInterface $bus) public function __invoke(CronProcessMessage $message): void { $schedule = $message->processSchedule; - $context = array_merge(...array_map(static fn ($ctx) => [$ctx['key'] => $ctx['value']], $schedule->getContext())); + /** @var list $contextRows */ + $contextRows = $schedule->getContext(); + $context = array_merge(...array_map(static fn (array $ctx) => [$ctx['key'] => $ctx['value']], $contextRows)); $this->bus->dispatch( new ProcessExecuteMessage($schedule->getProcess() ?? '', $schedule->getInput(), $context) ); diff --git a/src/Repository/ProcessExecutionRepository.php b/src/Repository/ProcessExecutionRepository.php index d7e0e7d..a29c45c 100644 --- a/src/Repository/ProcessExecutionRepository.php +++ b/src/Repository/ProcessExecutionRepository.php @@ -75,13 +75,15 @@ public function getManaged(ProcessExecution $processExecution): ProcessExecution public function getLastProcessExecution(string $code): ?ProcessExecution { $qb = $this->createQueryBuilder('pe'); - - return $qb->select('pe') + /** @var ProcessExecution|null $processExecution */ + $processExecution = $qb->select('pe') ->where($qb->expr()->eq('pe.code', $qb->expr()->literal($code))) ->orderBy('pe.startDate', 'DESC') ->setMaxResults(1) ->getQuery() ->getOneOrNullResult(); + + return $processExecution; } public function hasLogs(ProcessExecution $processExecution): bool diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 6038b6c..963deca 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -136,6 +136,7 @@ public function testPartialConfigurationKeepsOtherDefaults(): void public function testLastConfigurationWins(): void { $processor = new Processor(); + /** @var array> $config */ $config = $processor->processConfiguration(new Configuration('prod'), [ ['design' => ['logo_path' => 'first.png'], 'logs' => ['store_in_database' => false]], ['design' => ['logo_path' => 'second.png']], @@ -188,6 +189,9 @@ public function testInvalidConfiguration(array $config, string $expectedMessage) */ private function process(string $env, array $config): array { - return (new Processor())->processConfiguration(new Configuration($env), [$config]); + /** @var array $processedConfig */ + $processedConfig = (new Processor())->processConfiguration(new Configuration($env), [$config]); + + return $processedConfig; } } diff --git a/tests/Functional/LaunchActionTest.php b/tests/Functional/LaunchActionTest.php index 85cbb07..be21465 100644 --- a/tests/Functional/LaunchActionTest.php +++ b/tests/Functional/LaunchActionTest.php @@ -102,6 +102,7 @@ public function testLaunchWithForm(): void self::assertSame('key1', $crawler->filter('input[name="launch[context][0][key]"]')->attr('value')); $form = $crawler->selectButton('Launch')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['launch']['input'] = 'my input'; $values['launch']['context'] = [['key' => 'key1', 'value' => 'value1'], ['key' => 'key2', 'value' => 'value2']]; @@ -159,6 +160,7 @@ public function testContextRowWithoutKey(): void $crawler = $this->client->request('GET', '/process?routeName=process_launch&process=test.form_constraints'); self::assertResponseIsSuccessful(); $form = $crawler->selectButton('Launch')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['launch']['context'] = [['key' => 'key1', 'value' => 'value1'], ['key' => '', 'value' => 'value2']]; $this->client->request($form->getMethod(), $form->getUri(), $values); diff --git a/tests/Functional/ProcessScheduleCrudTest.php b/tests/Functional/ProcessScheduleCrudTest.php index df16bab..fe291c6 100644 --- a/tests/Functional/ProcessScheduleCrudTest.php +++ b/tests/Functional/ProcessScheduleCrudTest.php @@ -100,6 +100,7 @@ public function testCreate(): void self::assertNotContains('test.private', $options); $form = $crawler->selectButton('Create')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['ProcessSchedule']['process'] = 'test.process'; $values['ProcessSchedule']['type'] = 'cron'; @@ -123,6 +124,7 @@ public function testInvalidExpressionIsRejected(): void $crawler = $this->client->request('GET', '/process/process-schedule/new'); $form = $crawler->selectButton('Create')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['ProcessSchedule']['process'] = 'test.process'; $values['ProcessSchedule']['type'] = 'cron'; @@ -141,6 +143,7 @@ public function testEdit(): void $crawler = $this->client->request('GET', '/process/process-schedule/'.$schedule->getId().'/edit'); self::assertResponseIsSuccessful(); $form = $crawler->selectButton('Save changes')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['ProcessSchedule']['expression'] = '1 hour'; $this->client->request($form->getMethod(), $form->getUri(), $values); diff --git a/tests/Functional/UserCrudTest.php b/tests/Functional/UserCrudTest.php index 1c993e0..9cc230b 100644 --- a/tests/Functional/UserCrudTest.php +++ b/tests/Functional/UserCrudTest.php @@ -88,6 +88,7 @@ public function testCreate(): void $crawler = $this->client->request('GET', '/process/user/new'); self::assertResponseIsSuccessful(); $form = $crawler->selectButton('Create')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['User']['email'] = 'new@example.com'; $values['User']['password'] = ['first' => 'new password', 'second' => 'new password']; @@ -110,6 +111,7 @@ public function testPasswordsMustMatch(): void $crawler = $this->client->request('GET', '/process/user/new'); $form = $crawler->selectButton('Create')->form(); + /** @var array> $values */ $values = $form->getPhpValues(); $values['User']['email'] = 'new@example.com'; $values['User']['password'] = ['first' => 'password', 'second' => 'other']; diff --git a/tests/Manager/ProcessConfigurationsManagerTest.php b/tests/Manager/ProcessConfigurationsManagerTest.php index e8746c1..027e7e7 100644 --- a/tests/Manager/ProcessConfigurationsManagerTest.php +++ b/tests/Manager/ProcessConfigurationsManagerTest.php @@ -40,9 +40,14 @@ public function testPublicAndPrivateProcesses(): void 'public.two' => $this->rawProcess(), ]); - $codes = static fn (array $configurations): array => array_values( - array_map(static fn (ProcessConfiguration $configuration): string => $configuration->getCode(), $configurations) - ); + $codes = static function (array $configurations): array { + /** @var array $processConfigurations */ + $processConfigurations = $configurations; + + return array_values( + array_map(static fn (ProcessConfiguration $configuration): string => $configuration->getCode(), $processConfigurations) + ); + }; self::assertSame(['public.one', 'public.two'], $codes($manager->getPublicProcesses())); self::assertSame(['private.one'], $codes($manager->getPrivateProcesses())); diff --git a/tests/Manager/ProcessExecutionManagerEntityManagerTest.php b/tests/Manager/ProcessExecutionManagerEntityManagerTest.php index 50f4955..64609be 100644 --- a/tests/Manager/ProcessExecutionManagerEntityManagerTest.php +++ b/tests/Manager/ProcessExecutionManagerEntityManagerTest.php @@ -96,6 +96,7 @@ public function testEntityManagerClearedDuringTheProcess(): void // A single execution, with its final state and all its logs $connection = $this->entityManager->getConnection(); + /** @var list $executions */ $executions = $connection->fetchAllAssociative('SELECT id, status, end_date, report, context FROM process_execution'); self::assertCount(1, $executions); self::assertSame('finish', $executions[0]['status']); @@ -106,7 +107,9 @@ public function testEntityManagerClearedDuringTheProcess(): void ['before the clear', 'after the clear'], $connection->fetchFirstColumn('SELECT message FROM log_record WHERE process_execution_id = ? ORDER BY id', [$executions[0]['id']]) ); - self::assertSame(0, (int) $connection->fetchOne('SELECT COUNT(*) FROM log_record WHERE process_execution_id <> ?', [$executions[0]['id']])); + /** @var int|string $otherLogsCount */ + $otherLogsCount = $connection->fetchOne('SELECT COUNT(*) FROM log_record WHERE process_execution_id <> ?', [$executions[0]['id']]); + self::assertSame(0, (int) $otherLogsCount); } public function testEntityManagerClosedDuringTheProcess(): void @@ -144,6 +147,7 @@ public function testEntityManagerClosedDuringTheProcess(): void // A single execution, with its final state and all its logs $connection = $this->entityManager->getConnection(); + /** @var list $executions */ $executions = $connection->fetchAllAssociative('SELECT id, status, end_date, report, context FROM process_execution'); self::assertCount(1, $executions); self::assertSame('finish', $executions[0]['status']); diff --git a/tests/Notifier/ProcessExecutionNotifierTest.php b/tests/Notifier/ProcessExecutionNotifierTest.php index e1d24e2..f6acba8 100644 --- a/tests/Notifier/ProcessExecutionNotifierTest.php +++ b/tests/Notifier/ProcessExecutionNotifierTest.php @@ -274,7 +274,9 @@ public function __construct(private readonly \ArrayObject $logs) public function log($level, string|\Stringable $message, array $context = []): void { - $this->logs->append([(string) $level, $message, $context]); + /** @var string $levelName */ + $levelName = $level; + $this->logs->append([$levelName, $message, $context]); } }; }