From 4ee830327ee8b0783ffc0524c561ff71c34f5e2a Mon Sep 17 00:00:00 2001 From: Ron Rise Date: Thu, 29 Jan 2026 19:28:57 -0500 Subject: [PATCH] tests and linting --- .allowed-licenses.php | 1 + composer.json | 19 ++++++-- composer.lock | 44 ++++++++++++++++- src/Cli/Commands/Command.php | 10 ++-- src/Cli/Commands/CommandInterface.php | 7 ++- src/Cli/Commands/Crypt/GenerateKey.php | 1 + src/Cli/Commands/OAuth/AddRedirectUri.php | 1 + src/Cli/Commands/OAuth/AddScope.php | 3 +- src/Cli/Commands/OAuth/ClientCapabilities.php | 4 +- src/Cli/Commands/OAuth/ListClients.php | 4 +- src/Cli/Commands/Queue/Start.php | 5 +- src/Cli/Commands/User/Add.php | 5 +- src/Cli/Commands/User/ResetPassword.php | 9 ++-- src/CommandBus/Commands/CreateClient.php | 2 +- src/EventListeners/LoginFailed.php | 2 +- src/Events/Dispatcher.php | 2 +- src/Mailer/Drivers/Log.php | 22 +++++---- src/Mailer/Drivers/Smtp.php | 8 ++-- src/OAuth/Entities/Client.php | 2 +- tests/Events/Listeners/ConnectedTest.php | 47 ------------------- 20 files changed, 112 insertions(+), 86 deletions(-) delete mode 100644 tests/Events/Listeners/ConnectedTest.php diff --git a/.allowed-licenses.php b/.allowed-licenses.php index 5b60aa3..9234cec 100644 --- a/.allowed-licenses.php +++ b/.allowed-licenses.php @@ -10,5 +10,6 @@ return new LicenseConfigurationBuilder() 'BSD-2-Clause', 'BSD-3-Clause', 'Apache-2.0', + 'LGPL-2.1-only' ) ->build(); diff --git a/composer.json b/composer.json index 82e0dcf..4f63fe9 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,16 @@ { "name": "siteworxpro/app", "type": "project", + "config": { + "optimize-autoloader": true, + "sort-packages": true, + "audit": { + "ignore": { + "PKSA-rkkf-636k-qjb3": "Dev only package", + "PKSA-z3gr-8qht-p93v": "Dev only package" + } + } + }, "autoload": { "psr-4": { "Siteworxpro\\App\\": "src/", @@ -37,12 +47,13 @@ "phpmailer/phpmailer": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^12.4", - "mockery/mockery": "^1.6", - "squizlabs/php_codesniffer": "^4.0", + "jetbrains/phpstorm-attributes": "^1.2", + "kwn/php-rdkafka-stubs": "^2.2", "lendable/composer-license-checker": "^1.3.0", + "mockery/mockery": "^1.6", "phpstan/phpstan": "^2.1.31", - "kwn/php-rdkafka-stubs": "^2.2" + "phpunit/phpunit": "^12.4", + "squizlabs/php_codesniffer": "^4.0" }, "scripts": { "tests:all": [ diff --git a/composer.lock b/composer.lock index 005d3c0..26b1b31 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4c2ae64539e4f6a700912cdc7d863493", + "content-hash": "3063e521174c3d0c51a4b8143aee7e85", "packages": [ { "name": "brick/math", @@ -5739,6 +5739,48 @@ }, "time": "2025-04-30T06:54:44+00:00" }, + { + "name": "jetbrains/phpstorm-attributes", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/JetBrains/phpstorm-attributes.git", + "reference": "64de815a4509c29e00d5e3474087fd24c171afc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/JetBrains/phpstorm-attributes/zipball/64de815a4509c29e00d5e3474087fd24c171afc2", + "reference": "64de815a4509c29e00d5e3474087fd24c171afc2", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "JetBrains\\PhpStorm\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "JetBrains", + "homepage": "https://www.jetbrains.com" + } + ], + "description": "PhpStorm specific attributes", + "keywords": [ + "attributes", + "jetbrains", + "phpstorm" + ], + "support": { + "issues": "https://youtrack.jetbrains.com/newIssue?project=WI", + "source": "https://github.com/JetBrains/phpstorm-attributes/tree/1.2" + }, + "time": "2024-10-11T10:46:19+00:00" + }, { "name": "kwn/php-rdkafka-stubs", "version": "v2.2.1", diff --git a/src/Cli/Commands/Command.php b/src/Cli/Commands/Command.php index c46a4bc..6921ead 100644 --- a/src/Cli/Commands/Command.php +++ b/src/Cli/Commands/Command.php @@ -28,11 +28,11 @@ abstract class Command extends \Symfony\Component\Console\Command\Command implem } /** - * @param ClimateOutput|OutputInterface $output - * @param ArgvInput|InputInterface $input + * @param ClimateOutput $output + * @param ClimateOutput|ArgvInput $input * @return Client | null */ - protected function askForClient(ClimateOutput|OutputInterface $output, ArgvInput|InputInterface $input): ?Client + protected function askForClient(ClimateOutput $output, ClimateOutput|ArgvInput $input): ?Client { /** @var Collection $clients */ $clients = Client::whereJsonContains('grant_types', 'authorization_code') @@ -60,8 +60,8 @@ abstract class Command extends \Symfony\Component\Console\Command\Command implem protected function askForUser( Client $client, - ClimateOutput|OutputInterface $output, - ArgvInput|InputInterface $input + ClimateOutput $output, + ClimateOutput|ArgvInput $input ): ?User { $users = $client->users; diff --git a/src/Cli/Commands/CommandInterface.php b/src/Cli/Commands/CommandInterface.php index 0653e56..e855f72 100644 --- a/src/Cli/Commands/CommandInterface.php +++ b/src/Cli/Commands/CommandInterface.php @@ -14,7 +14,12 @@ interface CommandInterface /** * Execute the command. * + * @param ArgvInput|ClimateOutput $input + * @param ClimateOutput $output * @return int */ - public function __invoke(InputInterface | ArgvInput $input, OutputInterface | ClimateOutput $output): int; + public function __invoke( + ClimateOutput|ArgvInput $input, + ClimateOutput $output + ): int; } diff --git a/src/Cli/Commands/Crypt/GenerateKey.php b/src/Cli/Commands/Crypt/GenerateKey.php index c797563..90e92f8 100644 --- a/src/Cli/Commands/Crypt/GenerateKey.php +++ b/src/Cli/Commands/Crypt/GenerateKey.php @@ -9,6 +9,7 @@ use Siteworxpro\App\Cli\ClimateOutput; use Siteworxpro\App\Cli\Commands\Command; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\InputInterface; #[AsCommand('crypt:generate-key', 'Generate a new encryption key for the application')] class GenerateKey extends Command diff --git a/src/Cli/Commands/OAuth/AddRedirectUri.php b/src/Cli/Commands/OAuth/AddRedirectUri.php index 0be6645..b541271 100644 --- a/src/Cli/Commands/OAuth/AddRedirectUri.php +++ b/src/Cli/Commands/OAuth/AddRedirectUri.php @@ -11,6 +11,7 @@ use Siteworxpro\App\OAuth\Entities\Client; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Question\Question; #[AsCommand(name: 'oauth:redirect-uri:create', description: 'Add a redirect URI to an existing OAuth client.')] diff --git a/src/Cli/Commands/OAuth/AddScope.php b/src/Cli/Commands/OAuth/AddScope.php index 4b48488..fe60fb3 100644 --- a/src/Cli/Commands/OAuth/AddScope.php +++ b/src/Cli/Commands/OAuth/AddScope.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Siteworxpro\App\Cli\Commands\OAuth; +use Siteworxpro\App\Cli\ClimateOutput; use Siteworxpro\App\Cli\Commands\Command; use Siteworxpro\App\OAuth\Entities\Scope; use Symfony\Component\Console\Attribute\AsCommand; @@ -22,7 +23,7 @@ class AddScope extends Command ->addArgument('description', InputArgument::OPTIONAL, 'The description of the scope'); } - public function __invoke(ArgvInput | InputInterface $input, $output): int + public function __invoke($input, $output): int { $name = $input->getArgument('name'); $description = $input->getArgument('description') ?? ''; diff --git a/src/Cli/Commands/OAuth/ClientCapabilities.php b/src/Cli/Commands/OAuth/ClientCapabilities.php index f3dbbf5..9273842 100644 --- a/src/Cli/Commands/OAuth/ClientCapabilities.php +++ b/src/Cli/Commands/OAuth/ClientCapabilities.php @@ -7,15 +7,13 @@ namespace Siteworxpro\App\Cli\Commands\OAuth; use Siteworxpro\App\Cli\ClimateOutput; use Siteworxpro\App\Cli\Commands\Command; use Symfony\Component\Console\Attribute\AsCommand; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question; #[AsCommand(name: 'oauth:client:edit', description: 'Edit an OAuth client.')] class ClientCapabilities extends Command { - public function __invoke(ArgvInput|InputInterface $input, ClimateOutput|OutputInterface $output): int + public function __invoke($input, ClimateOutput|OutputInterface $output): int { $client = $this->askForClient($output, $input); diff --git a/src/Cli/Commands/OAuth/ListClients.php b/src/Cli/Commands/OAuth/ListClients.php index d876f64..e6eb46f 100644 --- a/src/Cli/Commands/OAuth/ListClients.php +++ b/src/Cli/Commands/OAuth/ListClients.php @@ -22,11 +22,11 @@ class ListClients extends Command } /** - * @param ArgvInput|InputInterface $input + * @param ArgvInput|ClimateOutput|InputInterface $input * @param ClimateOutput $output * @return int */ - public function __invoke(ArgvInput|InputInterface $input, $output): int + public function __invoke(ClimateOutput|ArgvInput|InputInterface $input, $output): int { if ($input->getArgument('client-id')) { $client = Client::find($input->getArgument('client-id')); diff --git a/src/Cli/Commands/Queue/Start.php b/src/Cli/Commands/Queue/Start.php index e1dd87a..fb53b97 100644 --- a/src/Cli/Commands/Queue/Start.php +++ b/src/Cli/Commands/Queue/Start.php @@ -5,10 +5,13 @@ declare(strict_types=1); namespace Siteworxpro\App\Cli\Commands\Queue; use Siteworxpro\App\Async\Consumer; +use Siteworxpro\App\Cli\ClimateOutput; use Siteworxpro\App\Cli\Commands\Command; use Siteworxpro\App\Cli\Commands\CommandInterface; use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; #[AsCommand('queue:start', 'Start the queue consumer')] class Start extends Command implements CommandInterface @@ -23,7 +26,7 @@ class Start extends Command implements CommandInterface ); } - public function __invoke($input, $output): int + public function __invoke(ClimateOutput|ArgvInput|InputInterface $input, $output): int { $queues = $input->getArgument('queues'); diff --git a/src/Cli/Commands/User/Add.php b/src/Cli/Commands/User/Add.php index 8c66e3e..133aee2 100644 --- a/src/Cli/Commands/User/Add.php +++ b/src/Cli/Commands/User/Add.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Siteworxpro\App\Cli\Commands\User; +use Siteworxpro\App\Cli\ClimateOutput; use Siteworxpro\App\Cli\Commands\Command; use Siteworxpro\App\CommandBus\Commands\CreateUser; use Siteworxpro\App\Models\ClientUser; @@ -12,12 +13,14 @@ use Siteworxpro\App\Services\Facades\CommandBus; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command as SCommand; use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Question\Question as QuestionInput; #[AsCommand('user:add', 'Add a new user associated with an OAuth client')] class Add extends Command { - public function __invoke($input, $output): int + public function __invoke(ClimateOutput|ArgvInput|InputInterface $input, ClimateOutput $output): int { $client = $this->askForClient($output, $input); if (!$client) { diff --git a/src/Cli/Commands/User/ResetPassword.php b/src/Cli/Commands/User/ResetPassword.php index 2cfaf50..e2b9254 100644 --- a/src/Cli/Commands/User/ResetPassword.php +++ b/src/Cli/Commands/User/ResetPassword.php @@ -11,9 +11,7 @@ use Siteworxpro\App\Services\Facades\CommandBus; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\Question as QuestionInput; #[AsCommand('user:reset-password', 'Reset a user\'s password')] @@ -29,7 +27,12 @@ class ResetPassword extends Command ); } - public function __invoke(ArgvInput|InputInterface $input, ClimateOutput|OutputInterface $output): int + /** + * @param ArgvInput|ClimateOutput $input + * @param ClimateOutput $output + * @return int + */ + public function __invoke(ClimateOutput|ArgvInput $input, ClimateOutput $output): int { $client = $this->askForClient($output, $input); diff --git a/src/CommandBus/Commands/CreateClient.php b/src/CommandBus/Commands/CreateClient.php index ab7a5b1..7c62803 100644 --- a/src/CommandBus/Commands/CreateClient.php +++ b/src/CommandBus/Commands/CreateClient.php @@ -8,7 +8,7 @@ readonly class CreateClient extends Command { /** * @param string $clientName - * @param array $clientGrants + * @param array $clientGrants * @param string $clientDescription */ public function __construct( diff --git a/src/EventListeners/LoginFailed.php b/src/EventListeners/LoginFailed.php index c0afa4f..b03e1f7 100644 --- a/src/EventListeners/LoginFailed.php +++ b/src/EventListeners/LoginFailed.php @@ -14,7 +14,7 @@ class LoginFailed extends Listener /** * Handle the event. * - * @param \Siteworxpro\App\Events\Login\LoginFailed $event + * @param string | \Siteworxpro\App\Events\Login\LoginFailed $event * @param array $payload * @return AuditLog|null */ diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index e8c576c..0bd9476 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -193,7 +193,7 @@ class Dispatcher implements DispatcherContract, Arrayable /** * Push an event to be dispatched later. * - * @param $event + * @param mixed $event * @param array $payload * @return void */ diff --git a/src/Mailer/Drivers/Log.php b/src/Mailer/Drivers/Log.php index c869b9f..52d2191 100644 --- a/src/Mailer/Drivers/Log.php +++ b/src/Mailer/Drivers/Log.php @@ -13,15 +13,19 @@ class Log implements DriverInterface public function send(Message $message): bool { - $logMessage = <<<'MSG' - =============================================== - From: {$this->fromAddress} - To: {$message->getTo()} - Subject: {$message->getSubject()} - Body: - {$this->formatBodyForLog($message->getBody())} - =============================================== - MSG; + $logMessage = sprintf( + "=================================" . PHP_EOL . + "Email sent via Log Driver" . PHP_EOL . + "From: %s" . PHP_EOL . + "To: %s" . PHP_EOL . + "Subject: %s" . PHP_EOL . + "Body: " . PHP_EOL . "%s" . PHP_EOL . + "=================================", + $this->fromAddress, + $message->getTo(), + $message->getSubject(), + $this->formatBodyForLog($message->getBody()) + ); Logger::info($logMessage); diff --git a/src/Mailer/Drivers/Smtp.php b/src/Mailer/Drivers/Smtp.php index f17e577..bc3ce28 100644 --- a/src/Mailer/Drivers/Smtp.php +++ b/src/Mailer/Drivers/Smtp.php @@ -13,12 +13,9 @@ class Smtp implements DriverInterface { private PHPMailer $mailer; - /** - * @throws Exception - */ public function __construct() { - $config = Config::get('mailer.smtp', []); + $config = Config::get('mailer.smtp'); if (empty($config['host']) || empty($config['port'])) { throw new \InvalidArgumentException( @@ -46,6 +43,9 @@ class Smtp implements DriverInterface return true; } + /** + * @throws Exception + */ public function setFrom(string $address, string $name): void { $this->mailer->setFrom($address, $name, false); diff --git a/src/OAuth/Entities/Client.php b/src/OAuth/Entities/Client.php index 30f9ddb..cf36d7c 100644 --- a/src/OAuth/Entities/Client.php +++ b/src/OAuth/Entities/Client.php @@ -38,7 +38,7 @@ use Siteworxpro\App\OAuth\ScopeRepository; * @property Collection $grant_types * @property bool $confidential * - * @property ClientCapabilities $capabilities + * @property ClientCapabilities | array $capabilities * @property-read Collection $clientRedirectUris * @property-read Scope[]|Collection $scopes * @property-read Collection $users diff --git a/tests/Events/Listeners/ConnectedTest.php b/tests/Events/Listeners/ConnectedTest.php deleted file mode 100644 index af3945e..0000000 --- a/tests/Events/Listeners/ConnectedTest.php +++ /dev/null @@ -1,47 +0,0 @@ -bind(Logger::class, fn() => $logger); - } - - public function testHandlesEvent() - { - $this->expectNotToPerformAssertions(); - - $connectedEvent = $this->createMock(ConnectionEstablished::class); - $listener = new Connected(); - - $listener->__invoke($connectedEvent); - } - - public function testThrowsException() - { - $this->expectException(\TypeError::class); - $listener = new Connected(); - $listener->__invoke(new \stdClass()); - } -}