From 088ae482ec25a9a63c27f860c47831f2c0e08a2c Mon Sep 17 00:00:00 2001 From: Plakhotnikov Vladimir <v.plahotnikov@yclients.tech> Date: Fri, 28 Jun 2024 11:49:07 +0300 Subject: [PATCH 1/2] Update rector.php rules and .php-cs-fixer.php dirs --- .php-cs-fixer.php | 2 +- rector.php | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 4d64c2d..c33454c 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -15,6 +15,6 @@ (new PhpCsFixer\Finder()) ->files() ->name('*.php') - ->in([__DIR__ . '/app/src', __DIR__ . '/app/modules']), + ->in([__DIR__ . '/app', __DIR__ . '/tests', __DIR__ . '/utils']), ) ->setCacheFile('.cache/.php-cs-fixer.cache'); diff --git a/rector.php b/rector.php index 8422b30..409a1b0 100644 --- a/rector.php +++ b/rector.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector; use Rector\Config\RectorConfig; use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector; use Rector\Php80\Rector\Catch_\RemoveUnusedVariableInCatchRector; @@ -21,10 +22,15 @@ __DIR__ . '/app', __DIR__ . '/tests', ]) - ->withImportNames(importShortClasses: false, removeUnusedImports: true) ->withCache(cacheDirectory: __DIR__ . '.cache/rector') - // uncomment to reach your current PHP version - // ->withPhpSets() + ->withPhpVersion(PhpVersion::PHP_82) + ->withPhpSets(php82: true) + ->withPreparedSets( + deadCode: true, + codeQuality: true, + codingStyle: true, + ) + ->withImportNames(importShortClasses: false, removeUnusedImports: true) ->withRules([ BootloaderConstantsFixesRule::class, AddVoidReturnTypeWhereNoReturnRector::class, @@ -38,9 +44,6 @@ RemoveUnusedVariableInCatchRector::class, ClosureToArrowFunctionRector::class, ]) - ->withPhpVersion(PhpVersion::PHP_82) - // here we can define, what prepared sets of rules will be applied - ->withPreparedSets( - deadCode: true, - codeQuality: true, - ); + ->withSkip([ + CatchExceptionNameMatchingTypeRector::class, + ]); From 7aea859ad027d0bce9e6ec4d371a11e4e35f01da Mon Sep 17 00:00:00 2001 From: Plakhotnikov Vladimir <v.plahotnikov@yclients.tech> Date: Fri, 28 Jun 2024 11:50:07 +0300 Subject: [PATCH 2/2] Rector checks the entire project --- app/config/events.php | 2 +- app/database/Factory/AttachmentFactory.php | 2 +- app/database/Factory/EventFactory.php | 14 +- .../Factory/Partials/InspectorType.php | 5 +- .../Factory/Partials/ProfilerType.php | 52 ++-- ..._default_change_events_alter_timestamp.php | 5 +- ...0_default_create_http_dump_attachments.php | 6 +- ...12643_2_2_default_create_profile_edges.php | 4 +- app/modules/Events/Domain/Event.php | 8 +- app/modules/HttpDumps/Domain/Attachment.php | 12 +- .../Http/Handler/AnyHttpRequestDump.php | 2 +- .../Console/Command/DeclareCommand.php | 4 +- .../Profiler/Application/CallGraph/Node.php | 2 + .../Application/Handlers/PrepareEdges.php | 2 +- app/modules/Profiler/Domain/Edge.php | 18 +- app/modules/Profiler/Domain/Profile.php | 6 +- .../Interfaces/Events/DeleteEventListener.php | 2 +- .../Interfaces/Jobs/StoreProfileHandler.php | 2 +- .../Queries/FindTopFunctionsByUuidHandler.php | 3 +- app/modules/Projects/Domain/Project.php | 4 +- .../Projects/Domain/ValueObject/Key.php | 2 + .../Commands/CreateProjectHandler.php | 2 +- .../Console/Command/RegisterCommand.php | 2 +- .../Handlers/RemoveSfDumpScriptHandler.php | 3 + .../Interfaces/Http/Handler/EventHandler.php | 2 +- .../Interfaces/Http/JavascriptAction.php | 2 +- app/modules/Smtp/Application/Mail/Parser.php | 5 +- app/modules/Smtp/Domain/Attachment.php | 14 +- .../Smtp/Interfaces/TCP/ResponseMessage.php | 5 + app/modules/Smtp/Interfaces/TCP/Service.php | 2 +- .../VarDumper/Application/Dump/HtmlBody.php | 6 +- .../VarDumper/Application/Dump/HtmlDumper.php | 33 ++- app/modules/Webhooks/Domain/Delivery.php | 12 +- .../Console/Command/RegisterCommand.php | 4 +- .../Webhooks/Interfaces/Job/RetryPolicy.php | 2 +- app/modules/Webhooks/Interfaces/Job/Timer.php | 2 +- app/src/Application/Auth/JWTTokenStorage.php | 2 +- .../Application/Bootloader/AppBootloader.php | 14 +- .../Commands/HandleReceivedEvent.php | 1 + .../Domain/Entity/ExtendedTypecast.php | 3 +- .../Application/Domain/ValueObjects/Json.php | 4 +- .../Application/Domain/ValueObjects/Uuid.php | 2 +- app/src/Application/Event/EventTypeMapper.php | 2 +- .../UuidParametersConverterInterceptor.php | 1 + .../HTTP/Middleware/JsonPayloadMiddleware.php | 2 +- .../HTTP/Response/JsonResource.php | 5 +- .../Service/HttpHandler/HandlerPipeline.php | 4 +- app/src/Integration/Auth0/Auth0Bootloader.php | 2 +- app/src/Integration/Kinde/Client.php | 3 + app/src/Integration/Kinde/SessionStorage.php | 2 +- .../CheckDatabaseConnectionCommand.php | 2 +- app/src/Interfaces/Http/Handler/Content.php | 1 + tests/App/Broadcasting/BroadcastFaker.php | 9 +- tests/App/Console/SpyConsoleInvoker.php | 1 - tests/App/Events/EventExpectation.php | 5 +- tests/App/Events/EventsMocker.php | 13 +- tests/App/Http/HttpFaker.php | 2 +- tests/App/Http/ResponseAssertions.php | 2 +- tests/App/Sentry/FakeTransport.php | 7 +- tests/DatabaseTestCase.php | 8 +- .../Console/RegisterModulesTest.php | 22 +- .../Http/Events/ClearActionTest.php | 14 +- .../Interfaces/Http/Events/ShowActionTest.php | 2 +- .../Http/Inspector/InspectorActionTest.php | 2 +- .../Http/Profiler/ProfilerActionTest.php | 2 +- .../Interfaces/Http/Ray/RayActionTest.php | 2 +- .../Http/Sentry/SentryControllerTestCase.php | 2 +- .../Http/Sentry/SentryVueReplayActionTest.php | 253 +++++++++++------- .../Sentry/SentryVueTransactionActionTest.php | 2 +- .../Smtp/Attachments/DeleteEventAction.php | 5 +- .../Http/Smtp/Attachments/ListActionTest.php | 2 +- .../Jobs/Webhooks/WebhookHandlerTest.php | 2 + .../TCP/Monolog/JsonPayloadTest.php | 2 +- .../Feature/Interfaces/TCP/Smtp/EmailTest.php | 9 +- tests/TestCase.php | 1 + .../Domain/CacheEventRepositoryTest.php | 18 +- .../Modules/Smtp/AttachmentStorageTest.php | 3 + .../Smtp/CycleOrmAttachmentRepositoryTest.php | 2 + .../Unit/Modules/Webhooks/RetryPolicyTest.php | 10 +- .../Webhooks/WebhookFilesFinderTest.php | 4 + .../Webhooks/WebhookYamlParserTest.php | 1 + .../src/BootloaderConstantsFixesRule.php | 7 +- 82 files changed, 406 insertions(+), 311 deletions(-) diff --git a/app/config/events.php b/app/config/events.php index 8a51edf..d13cd3b 100644 --- a/app/config/events.php +++ b/app/config/events.php @@ -9,5 +9,5 @@ 'interceptors' => [ WebhookEventInterceptor::class, BroadcastEventInterceptor::class, - ] + ], ]; diff --git a/app/database/Factory/AttachmentFactory.php b/app/database/Factory/AttachmentFactory.php index a563094..f45aff3 100644 --- a/app/database/Factory/AttachmentFactory.php +++ b/app/database/Factory/AttachmentFactory.php @@ -58,7 +58,7 @@ public function forEvent(Uuid|Event $uuid): self { $uuid = $uuid instanceof Event ? $uuid->getUuid() : $uuid; - return $this->state(fn(Generator $faker, array $definition) => [ + return $this->state(static fn(Generator $faker, array $definition) => [ 'event_uuid' => $uuid, ]); } diff --git a/app/database/Factory/EventFactory.php b/app/database/Factory/EventFactory.php index 246cffb..cad27a7 100644 --- a/app/database/Factory/EventFactory.php +++ b/app/database/Factory/EventFactory.php @@ -24,13 +24,13 @@ */ final class EventFactory extends AbstractFactory { - use SmtpType, - ProfilerType, - SentryType, - MonologType, - InspectorType, - VarDumperType, - RayType; + use SmtpType; + use ProfilerType; + use SentryType; + use MonologType; + use InspectorType; + use VarDumperType; + use RayType; public function entity(): string { diff --git a/app/database/Factory/Partials/InspectorType.php b/app/database/Factory/Partials/InspectorType.php index 5903940..64e0f9b 100644 --- a/app/database/Factory/Partials/InspectorType.php +++ b/app/database/Factory/Partials/InspectorType.php @@ -4,6 +4,7 @@ namespace Database\Factory\Partials; +use Spiral\Http\Pipeline; trait InspectorType { protected static function getInspectorPayload(): array @@ -136,7 +137,7 @@ protected static function getInspectorPayload(): array ], ], [ - 'class' => 'Spiral\\Http\\Pipeline', + 'class' => Pipeline::class, 'function' => 'Spiral\\Http\\{closure}', 'args' => [], 'type' => '->', @@ -190,7 +191,7 @@ protected static function getInspectorPayload(): array ], [ 'line' => 80, - 'code' => ' throw new NotCallableException(\'Unsupported callable.\');', + 'code' => " throw new NotCallableException('Unsupported callable.');", ], ], ], diff --git a/app/database/Factory/Partials/ProfilerType.php b/app/database/Factory/Partials/ProfilerType.php index 0227a8c..537dc24 100644 --- a/app/database/Factory/Partials/ProfilerType.php +++ b/app/database/Factory/Partials/ProfilerType.php @@ -4,6 +4,14 @@ namespace Database\Factory\Partials; +use Spiral\RoadRunnerBridge\Http\Dispatcher; +use Nyholm\Psr7\ServerRequest; +use Spiral\Debug\State; +use Spiral\Bootloader\DebugBootloader; +use Spiral\Telemetry\Span; +use Nyholm\Psr7\Stream; +use Nyholm\Psr7\Response; +use Spiral\Telemetry\Span\Status; trait ProfilerType { public static function getProfilerPayload(): array @@ -11,7 +19,7 @@ public static function getProfilerPayload(): array return [ 'tags' => [ 'php' => '8.2.5', - 'dispatcher' => 'Spiral\\RoadRunnerBridge\\Http\\Dispatcher', + 'dispatcher' => Dispatcher::class, 'method' => 'GET', 'url' => 'http://127.0.0.1:8080/', 'route' => null, @@ -45,7 +53,7 @@ public static function getProfilerPayload(): array ], 'e2' => [ 'caller' => 'main()', - 'callee' => 'Nyholm\\Psr7\\ServerRequest::getAttribute', + 'callee' => ServerRequest::class . '::getAttribute', 'cost' => [ 'd_cpu' => 82950, 'd_wt' => 211997, @@ -64,7 +72,7 @@ public static function getProfilerPayload(): array ], 'e3' => [ 'caller' => 'main()', - 'callee' => 'Spiral\\Debug\\State::getTags', + 'callee' => State::class . '::getTags', 'cost' => [ 'd_cpu' => 82951, 'd_wt' => 211999, @@ -83,7 +91,7 @@ public static function getProfilerPayload(): array ], 'e4' => [ 'caller' => 'main()', - 'callee' => 'Spiral\\Bootloader\\DebugBootloader::state', + 'callee' => DebugBootloader::class . '::state', 'cost' => [ 'd_cpu' => 82855, 'd_wt' => 211903, @@ -102,7 +110,7 @@ public static function getProfilerPayload(): array ], 'e5' => [ 'caller' => 'main()', - 'callee' => 'Spiral\\Telemetry\\Span::setStatus', + 'callee' => Span::class . '::setStatus', 'cost' => [ 'd_cpu' => 82949, 'd_wt' => 211997, @@ -121,7 +129,7 @@ public static function getProfilerPayload(): array ], 'e6' => [ 'caller' => 'main()', - 'callee' => 'Nyholm\\Psr7\\Stream::getSize', + 'callee' => Stream::class . '::getSize', 'cost' => [ 'd_cpu' => 82951, 'd_wt' => 211999, @@ -140,7 +148,7 @@ public static function getProfilerPayload(): array ], 'e7' => [ 'caller' => 'main()', - 'callee' => 'Nyholm\\Psr7\\Response::getBody', + 'callee' => Response::class . '::getBody', 'cost' => [ 'd_cpu' => 82951, @@ -160,7 +168,7 @@ public static function getProfilerPayload(): array ], 'e8' => [ 'caller' => 'main()', - 'callee' => 'Nyholm\\Psr7\\Response::getHeaderLine', + 'callee' => Response::class . '::getHeaderLine', 'cost' => [ 'd_cpu' => 82948, 'd_wt' => 211996, @@ -179,7 +187,7 @@ public static function getProfilerPayload(): array ], 'e9' => [ 'caller' => 'main()', - 'callee' => 'Spiral\\Telemetry\\Span::setAttribute', + 'callee' => Span::class . '::setAttribute', 'cost' => [ 'd_cpu' => 82949, 'd_wt' => 211997, @@ -198,7 +206,7 @@ public static function getProfilerPayload(): array ], 'e10' => [ 'caller' => 'main()', - 'callee' => 'Nyholm\\Psr7\\Response::getStatusCode', + 'callee' => Response::class . '::getStatusCode', 'cost' => [ 'd_cpu' => 82951, 'd_wt' => 211998, @@ -236,7 +244,7 @@ public static function getProfilerPayload(): array ], 'e12' => [ 'caller' => 'App\\Middleware\\LocaleSelector::process', - 'callee' => 'Spiral\\Telemetry\\Span::setStatus', + 'callee' => Span::class . '::setStatus', 'cost' => [ 'd_cpu' => 82701, 'd_wt' => 211747, @@ -254,8 +262,8 @@ public static function getProfilerPayload(): array ], ], 'e13' => [ - 'caller' => 'Spiral\\Telemetry\\Span::setStatus', - 'callee' => 'Spiral\\Telemetry\\Span\\Status::__construct', + 'caller' => Span::class . '::setStatus', + 'callee' => Status::class . '::__construct', 'cost' => [ 'd_cpu' => 3, 'd_wt' => 2, @@ -274,7 +282,7 @@ public static function getProfilerPayload(): array ], 'e14' => [ 'caller' => 'App\\Middleware\\LocaleSelector::process', - 'callee' => 'Nyholm\\Psr7\\Stream::getSize', + 'callee' => Stream::class . '::getSize', 'cost' => [ 'd_cpu' => 82691, 'd_wt' => 211737, @@ -292,8 +300,8 @@ public static function getProfilerPayload(): array ], ], 'e15' => [ - 'caller' => 'Nyholm\\Psr7\\Stream::getSize', - 'callee' => 'Nyholm\\Psr7\\Stream::getUri', + 'caller' => Stream::class . '::getSize', + 'callee' => Stream::class . '::getUri', 'cost' => [ 'd_cpu' => 8, 'd_wt' => 7, @@ -311,8 +319,8 @@ public static function getProfilerPayload(): array ], ], 'e16' => [ - 'caller' => 'Nyholm\\Psr7\\Stream::getUri', - 'callee' => 'Nyholm\\Psr7\\Stream::getMetadata', + 'caller' => Stream::class . '::getUri', + 'callee' => Stream::class . '::getMetadata', 'cost' => [ 'd_cpu' => 3, @@ -332,7 +340,7 @@ public static function getProfilerPayload(): array ], 'e17' => [ 'caller' => 'App\\Middleware\\LocaleSelector::process', - 'callee' => 'Nyholm\\Psr7\\Response::getBody', + 'callee' => Response::class . '::getBody', 'cost' => [ 'd_cpu' => 82706, 'd_wt' => 211751, @@ -351,7 +359,7 @@ public static function getProfilerPayload(): array ], 'e18' => [ 'caller' => 'App\\Middleware\\LocaleSelector::process', - 'callee' => 'Nyholm\\Psr7\\Response::getHeaderLine', + 'callee' => Response::class . '::getHeaderLine', 'cost' => [ 'd_cpu' => 82701, 'd_wt' => 211746, @@ -369,8 +377,8 @@ public static function getProfilerPayload(): array ], ], 'e19' => [ - 'caller' => 'Nyholm\\Psr7\\Response::getHeaderLine', - 'callee' => 'Nyholm\\Psr7\\Response::getHeader', + 'caller' => Response::class . '::getHeaderLine', + 'callee' => Response::class . '::getHeader', 'cost' => [ 'd_cpu' => 2, 'd_wt' => 2, diff --git a/app/database/Migrations/20240428.211841_0_0_default_change_events_alter_timestamp.php b/app/database/Migrations/20240428.211841_0_0_default_change_events_alter_timestamp.php index c810781..00a9486 100644 --- a/app/database/Migrations/20240428.211841_0_0_default_change_events_alter_timestamp.php +++ b/app/database/Migrations/20240428.211841_0_0_default_change_events_alter_timestamp.php @@ -17,8 +17,5 @@ public function up(): void ->update(); } - public function down(): void - { - - } + public function down(): void {} } diff --git a/app/database/Migrations/20240517.184321_0_0_default_create_http_dump_attachments.php b/app/database/Migrations/20240517.184321_0_0_default_create_http_dump_attachments.php index 97985c4..4cfefd0 100644 --- a/app/database/Migrations/20240517.184321_0_0_default_create_http_dump_attachments.php +++ b/app/database/Migrations/20240517.184321_0_0_default_create_http_dump_attachments.php @@ -19,8 +19,10 @@ public function up(): void ->addColumn('path', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 255]) ->addColumn('size', 'integer', ['nullable' => false, 'defaultValue' => 0]) ->addColumn('mime', 'string', ['nullable' => false, 'defaultValue' => null, 'size' => 32]) - ->addIndex(['event_uuid'], - ['name' => 'http_dump_attachments_index_event_uuid_6647a54986782', 'unique' => false]) + ->addIndex( + ['event_uuid'], + ['name' => 'http_dump_attachments_index_event_uuid_6647a54986782', 'unique' => false], + ) ->setPrimaryKeys(['uuid']) ->create(); } diff --git a/app/database/Migrations/20240608.112643_2_2_default_create_profile_edges.php b/app/database/Migrations/20240608.112643_2_2_default_create_profile_edges.php index 113d512..6661950 100644 --- a/app/database/Migrations/20240608.112643_2_2_default_create_profile_edges.php +++ b/app/database/Migrations/20240608.112643_2_2_default_create_profile_edges.php @@ -34,7 +34,9 @@ public function up(): void ->addColumn('p_ct', 'float', ['nullable' => false, 'defaultValue' => null]) ->addColumn('p_mu', 'float', ['nullable' => false, 'defaultValue' => null]) ->addColumn('p_pmu', 'float', ['nullable' => false, 'defaultValue' => null]) - ->addIndex(['profile_uuid'], ['name' => 'profile_edges_index_profile_uuid_66643ff3139b6', 'unique' => false], + ->addIndex( + ['profile_uuid'], + ['name' => 'profile_edges_index_profile_uuid_66643ff3139b6', 'unique' => false], ) ->addIndex(['parent_uuid'], ['name' => 'profile_edges_index_parent_uuid_66643ff3139e7', 'unique' => false]) ->addForeignKey(['profile_uuid'], 'profiles', ['uuid'], [ diff --git a/app/modules/Events/Domain/Event.php b/app/modules/Events/Domain/Event.php index a07e4f3..38d55d6 100644 --- a/app/modules/Events/Domain/Event.php +++ b/app/modules/Events/Domain/Event.php @@ -22,15 +22,15 @@ class Event /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string(50)')] - private string $type, + private readonly string $type, #[Column(type: 'json', typecast: Json::class)] private Json $payload, #[Column(type: 'string(25)', typecast: Timestamp::class)] - private Timestamp $timestamp, + private readonly Timestamp $timestamp, #[Column(type: 'string', nullable: true, typecast: Key::class)] - private ?Key $project = null, + private readonly ?Key $project = null, ) {} public function getUuid(): Uuid diff --git a/app/modules/HttpDumps/Domain/Attachment.php b/app/modules/HttpDumps/Domain/Attachment.php index 2bf99a1..4a8cf97 100644 --- a/app/modules/HttpDumps/Domain/Attachment.php +++ b/app/modules/HttpDumps/Domain/Attachment.php @@ -20,17 +20,17 @@ class Attachment /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string(36)', typecast: 'uuid')] - private Uuid $eventUuid, + private readonly Uuid $eventUuid, #[Column(type: 'string')] - private string $name, + private readonly string $name, #[Column(type: 'string')] - private string $path, + private readonly string $path, #[Column(type: 'integer', default: 0)] - private int $size, + private readonly int $size, #[Column(type: 'string(32)')] - private string $mime, + private readonly string $mime, ) {} public function getUuid(): Uuid diff --git a/app/modules/HttpDumps/Interfaces/Http/Handler/AnyHttpRequestDump.php b/app/modules/HttpDumps/Interfaces/Http/Handler/AnyHttpRequestDump.php index 119ec79..b5da3d6 100644 --- a/app/modules/HttpDumps/Interfaces/Http/Handler/AnyHttpRequestDump.php +++ b/app/modules/HttpDumps/Interfaces/Http/Handler/AnyHttpRequestDump.php @@ -71,7 +71,7 @@ private function createPayload(ServerRequestInterface $request): array 'post' => $request->getParsedBody() ?? [], 'cookies' => $request->getCookieParams(), 'files' => \array_map( - fn(Attachment $attachment) => [ + static fn(Attachment $attachment) => [ 'uuid' => (string) $attachment->getUuid(), 'name' => $attachment->getFilename(), 'size' => $attachment->getSize(), diff --git a/app/modules/Metrics/Interfaces/Console/Command/DeclareCommand.php b/app/modules/Metrics/Interfaces/Console/Command/DeclareCommand.php index bdeb3e4..84dad59 100644 --- a/app/modules/Metrics/Interfaces/Console/Command/DeclareCommand.php +++ b/app/modules/Metrics/Interfaces/Console/Command/DeclareCommand.php @@ -27,12 +27,12 @@ public function __invoke( } foreach ($repository->findAll() as $name => $collector) { - $this->info("Declaring metric: {$name}"); + $this->info('Declaring metric: ' . $name); try { $metrics->declare($name, $collector); } catch (\Throwable $e) { - $this->error("Failed to declare metric: {$name}. Reason: {$e->getMessage()}"); + $this->error(sprintf('Failed to declare metric: %s. Reason: %s', $name, $e->getMessage())); } } diff --git a/app/modules/Profiler/Application/CallGraph/Node.php b/app/modules/Profiler/Application/CallGraph/Node.php index 038fa71..aa777ce 100644 --- a/app/modules/Profiler/Application/CallGraph/Node.php +++ b/app/modules/Profiler/Application/CallGraph/Node.php @@ -27,7 +27,9 @@ public static function fromEdge( } public string $color; + public string $textColor; + public string $label; public function __construct( diff --git a/app/modules/Profiler/Application/Handlers/PrepareEdges.php b/app/modules/Profiler/Application/Handlers/PrepareEdges.php index c883c6d..ea03623 100644 --- a/app/modules/Profiler/Application/Handlers/PrepareEdges.php +++ b/app/modules/Profiler/Application/Handlers/PrepareEdges.php @@ -41,7 +41,7 @@ public function handle(array $event): array $parents[$func] = 'e' . $id; $prev = 'e' . $id; - $id++; + ++$id; } $event['total_edges'] = \count($event['edges']); diff --git a/app/modules/Profiler/Domain/Edge.php b/app/modules/Profiler/Domain/Edge.php index 2d595ae..c4bd616 100644 --- a/app/modules/Profiler/Domain/Edge.php +++ b/app/modules/Profiler/Domain/Edge.php @@ -25,23 +25,23 @@ class Edge public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string(36)', name: 'profile_uuid', typecast: 'uuid')] - private Uuid $profileUuid, + private readonly Uuid $profileUuid, #[Column(type: 'integer')] - private int $order, + private readonly int $order, #[Embedded(target: Cost::class)] - private Cost $cost, + private readonly Cost $cost, #[Embedded(target: Diff::class)] - private Diff $diff, + private readonly Diff $diff, #[Embedded(target: Percents::class)] - private Percents $percents, + private readonly Percents $percents, #[Column(type: 'text')] - private string $callee, + private readonly string $callee, #[Column(type: 'text', nullable: true, default: null)] - private ?string $caller = null, + private readonly ?string $caller = null, #[Column(type: 'string(36)', name: 'parent_uuid', nullable: true, default: null, typecast: 'uuid')] - private ?Uuid $parentUuid = null, + private readonly ?Uuid $parentUuid = null, ) {} public function getUuid(): Uuid diff --git a/app/modules/Profiler/Domain/Profile.php b/app/modules/Profiler/Domain/Profile.php index a1904bb..90c1ba5 100644 --- a/app/modules/Profiler/Domain/Profile.php +++ b/app/modules/Profiler/Domain/Profile.php @@ -31,11 +31,11 @@ class Profile /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string')] - private string $name, + private readonly string $name, #[Embedded(target: Peaks::class)] - private Peaks $peaks, + private readonly Peaks $peaks, ) { $this->edges = new ArrayCollection(); } diff --git a/app/modules/Profiler/Interfaces/Events/DeleteEventListener.php b/app/modules/Profiler/Interfaces/Events/DeleteEventListener.php index c46d8e8..e2e2847 100644 --- a/app/modules/Profiler/Interfaces/Events/DeleteEventListener.php +++ b/app/modules/Profiler/Interfaces/Events/DeleteEventListener.php @@ -21,7 +21,7 @@ public function __construct( public function __invoke(EventWasDeleted $event): void { $profile = $this->orm->getRepository(Profile::class)->findByPK($event->uuid); - if (!$profile) { + if ($profile === null) { return; } diff --git a/app/modules/Profiler/Interfaces/Jobs/StoreProfileHandler.php b/app/modules/Profiler/Interfaces/Jobs/StoreProfileHandler.php index c8729ee..f5403e3 100644 --- a/app/modules/Profiler/Interfaces/Jobs/StoreProfileHandler.php +++ b/app/modules/Profiler/Interfaces/Jobs/StoreProfileHandler.php @@ -79,7 +79,7 @@ public function invoke(array $payload): void $batchSize = 0; } - $batchSize++; + ++$batchSize; } $profile = $this->orm->getRepository(Profile::class)->findByPK($profileUuid); diff --git a/app/modules/Profiler/Interfaces/Queries/FindTopFunctionsByUuidHandler.php b/app/modules/Profiler/Interfaces/Queries/FindTopFunctionsByUuidHandler.php index 60998c5..bc6a677 100644 --- a/app/modules/Profiler/Interfaces/Queries/FindTopFunctionsByUuidHandler.php +++ b/app/modules/Profiler/Interfaces/Queries/FindTopFunctionsByUuidHandler.php @@ -11,7 +11,7 @@ use Spiral\Cqrs\Attribute\QueryHandler; // TODO: refactor this, use repository -final class FindTopFunctionsByUuidHandler +final readonly class FindTopFunctionsByUuidHandler { public function __construct( private ORMInterface $orm, @@ -44,6 +44,7 @@ public function __invoke(FindTopFunctionsByUuid $query): array foreach ($metrics as $metric) { $functions[$edge->getCallee()][$metric] = $edge->getCost()->{$metric}; } + continue; } diff --git a/app/modules/Projects/Domain/Project.php b/app/modules/Projects/Domain/Project.php index b4caff4..16944a3 100644 --- a/app/modules/Projects/Domain/Project.php +++ b/app/modules/Projects/Domain/Project.php @@ -16,9 +16,9 @@ class Project /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: Key::class)] - private Key $key, + private readonly Key $key, #[Column(type: 'string')] - private string $name, + private readonly string $name, ) {} public function getKey(): Key diff --git a/app/modules/Projects/Domain/ValueObject/Key.php b/app/modules/Projects/Domain/ValueObject/Key.php index 19f8fcb..2369b53 100644 --- a/app/modules/Projects/Domain/ValueObject/Key.php +++ b/app/modules/Projects/Domain/ValueObject/Key.php @@ -9,7 +9,9 @@ final readonly class Key implements \JsonSerializable, \Stringable { public const MIN_LENGTH = 3; + public const MAX_LENGTH = 36; + public const ALLOWED_CHARACTERS = 'a-z0-9-_'; public static function create(string $key): self diff --git a/app/modules/Projects/Interfaces/Commands/CreateProjectHandler.php b/app/modules/Projects/Interfaces/Commands/CreateProjectHandler.php index e3165b2..1b83b33 100644 --- a/app/modules/Projects/Interfaces/Commands/CreateProjectHandler.php +++ b/app/modules/Projects/Interfaces/Commands/CreateProjectHandler.php @@ -23,7 +23,7 @@ public function __construct( public function __invoke(CreateProject $command): Project { if ($this->projects->findByPK($command->key) !== null) { - throw new UniqueKeyException("Project with key {$command->key} already exists"); + throw new UniqueKeyException(sprintf('Project with key %s already exists', $command->key)); } $project = $this->factory->create( diff --git a/app/modules/Projects/Interfaces/Console/Command/RegisterCommand.php b/app/modules/Projects/Interfaces/Console/Command/RegisterCommand.php index e0cc9da..6c71f7f 100644 --- a/app/modules/Projects/Interfaces/Console/Command/RegisterCommand.php +++ b/app/modules/Projects/Interfaces/Console/Command/RegisterCommand.php @@ -22,7 +22,7 @@ public function __invoke( ): int { foreach ($locator->findAll() as $project) { try { - $this->writeln("Registering project: {$project->getName()}"); + $this->writeln('Registering project: ' . $project->getName()); $bus->dispatch( new CreateProject( key: (string) $project->getKey(), diff --git a/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php b/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php index b67c5fc..6806169 100644 --- a/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php +++ b/app/modules/Ray/Application/Handlers/RemoveSfDumpScriptHandler.php @@ -23,14 +23,17 @@ public function handle(array $event): array if (!\is_string($val) || !\str_contains($val, 'Sfdump')) { continue; } + $event['payloads'][$i]['content'][$k][$j] = $this->cleanHtml($val); } + continue; } if (\is_array($value) || !\is_string($value) || !\str_contains($value, 'Sfdump')) { continue; } + $event['payloads'][$i]['content'][$k] = $this->cleanHtml($value); } } diff --git a/app/modules/Ray/Interfaces/Http/Handler/EventHandler.php b/app/modules/Ray/Interfaces/Http/Handler/EventHandler.php index d77f78a..294961a 100644 --- a/app/modules/Ray/Interfaces/Http/Handler/EventHandler.php +++ b/app/modules/Ray/Interfaces/Http/Handler/EventHandler.php @@ -101,7 +101,7 @@ private function listenEvent(ServerRequestInterface $request): ?EventType $userAgent = $request->getServerParams()['HTTP_USER_AGENT'] ?? ''; - if (\str_starts_with(\strtolower($userAgent), 'ray')) { + if (\str_starts_with(\strtolower((string) $userAgent), 'ray')) { return new EventType(type: 'ray'); } diff --git a/app/modules/Sentry/Interfaces/Http/JavascriptAction.php b/app/modules/Sentry/Interfaces/Http/JavascriptAction.php index 1b36b0a..6ed8ea3 100644 --- a/app/modules/Sentry/Interfaces/Http/JavascriptAction.php +++ b/app/modules/Sentry/Interfaces/Http/JavascriptAction.php @@ -24,7 +24,7 @@ public function __invoke(EnvironmentInterface $env, string|int $project): Respon 'http://sentry@127.0.0.1:8000', ); - $url = \rtrim($host, '/') . '/' . $project; + $url = \rtrim((string) $host, '/') . '/' . $project; return new Response( status: 200, diff --git a/app/modules/Smtp/Application/Mail/Parser.php b/app/modules/Smtp/Application/Mail/Parser.php index b64343f..ca3da0b 100644 --- a/app/modules/Smtp/Application/Mail/Parser.php +++ b/app/modules/Smtp/Application/Mail/Parser.php @@ -62,7 +62,7 @@ public function parse(string $body, array $allRecipients = []): Message */ private function buildAttachmentFrom(array $attachments): array { - return \array_map(fn(ParseMessage\IMessagePart $part) => new Attachment( + return \array_map(static fn(ParseMessage\IMessagePart $part) => new Attachment( $part->getFilename(), $part->getContent(), $part->getContentType(), @@ -76,10 +76,9 @@ private function buildAttachmentFrom(array $attachments): array */ private function joinNameAndEmail(array $addresses): array { - return \array_map(function (AddressPart $addressPart) { + return \array_map(static function (AddressPart $addressPart) { $name = $addressPart->getName(); $email = $addressPart->getValue(); - return ['name' => $name, 'email' => $email]; }, $addresses); } diff --git a/app/modules/Smtp/Domain/Attachment.php b/app/modules/Smtp/Domain/Attachment.php index 23d8b7e..391599b 100644 --- a/app/modules/Smtp/Domain/Attachment.php +++ b/app/modules/Smtp/Domain/Attachment.php @@ -20,19 +20,19 @@ class Attachment /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string(36)', typecast: 'uuid')] - private Uuid $eventUuid, + private readonly Uuid $eventUuid, #[Column(type: 'string')] - private string $name, + private readonly string $name, #[Column(type: 'string')] - private string $path, + private readonly string $path, #[Column(type: 'integer', default: 0)] - private int $size, + private readonly int $size, #[Column(type: 'string(32)')] - private string $mime, + private readonly string $mime, #[Column(type: 'string(255)')] - private string $id, + private readonly string $id, ) {} public function getUuid(): Uuid diff --git a/app/modules/Smtp/Interfaces/TCP/ResponseMessage.php b/app/modules/Smtp/Interfaces/TCP/ResponseMessage.php index c16260e..316b84c 100644 --- a/app/modules/Smtp/Interfaces/TCP/ResponseMessage.php +++ b/app/modules/Smtp/Interfaces/TCP/ResponseMessage.php @@ -7,10 +7,15 @@ final readonly class ResponseMessage implements \Stringable { private const READY = 220; + public const OK = 250; + public const CLOSING = 221; + public const AUTHENTICATED = 235; + public const START_MAIL_INPUT = 354; + public const USERNAME = 334; public static function ready(string $message = 'mailamie'): self diff --git a/app/modules/Smtp/Interfaces/TCP/Service.php b/app/modules/Smtp/Interfaces/TCP/Service.php index ae47c4d..d174add 100644 --- a/app/modules/Smtp/Interfaces/TCP/Service.php +++ b/app/modules/Smtp/Interfaces/TCP/Service.php @@ -98,7 +98,7 @@ private function dispatchMessage(Message $message, ?string $project = null): voi $result = $this->attachments->store(eventUuid: $uuid, attachments: $message->attachments); // TODO: Refactor this foreach ($result as $cid => $url) { - $data['html'] = \str_replace("cid:$cid", $url, $data['html']); + $data['html'] = \str_replace('cid:' . $cid, $url, $data['html']); } $this->bus->dispatch( diff --git a/app/modules/VarDumper/Application/Dump/HtmlBody.php b/app/modules/VarDumper/Application/Dump/HtmlBody.php index 4e4f5ea..08a9ee2 100644 --- a/app/modules/VarDumper/Application/Dump/HtmlBody.php +++ b/app/modules/VarDumper/Application/Dump/HtmlBody.php @@ -7,13 +7,11 @@ final readonly class HtmlBody implements BodyInterface { private string $id; - private string $html; public function __construct( - string $value, + private string $html, ) { - $this->html = $value; - \preg_match_all('/sf-dump-\d+/', $value, $matches); + \preg_match_all('/sf-dump-\d+/', $this->html, $matches); $this->id = $matches[0][0]; } diff --git a/app/modules/VarDumper/Application/Dump/HtmlDumper.php b/app/modules/VarDumper/Application/Dump/HtmlDumper.php index 2902713..810015f 100644 --- a/app/modules/VarDumper/Application/Dump/HtmlDumper.php +++ b/app/modules/VarDumper/Application/Dump/HtmlDumper.php @@ -15,9 +15,13 @@ final class HtmlDumper extends CliDumper public static $defaultOutput = 'php://output'; protected string $dumpPrefix = '<pre class=sf-dump id=%s data-indent-pad="%s">'; + protected string $dumpSuffix = '</pre><script>Sfdump(%s)</script>'; + protected string $dumpId = 'sf-dump'; + protected $colors = true; + protected int $lastDepth = -1; private array $displayOptions = [ @@ -25,6 +29,7 @@ final class HtmlDumper extends CliDumper 'maxStringLength' => 160, 'fileLinkFormat' => null, ]; + private array $extraDisplayOptions = []; public function __construct(DumpIdGeneratorInterface $generator) @@ -71,7 +76,7 @@ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut): vo $this->line .= sprintf( '<img src="data:%s;base64,%s" /></samp>', $cursor->attr['content-type'], - base64_encode($cursor->attr['img-data']), + base64_encode((string) $cursor->attr['img-data']), ); $this->endValue($cursor); } else { @@ -84,6 +89,7 @@ public function enterHash(Cursor $cursor, int $type, string|int|null $class, boo if (Cursor::HASH_OBJECT === $type) { $cursor->attr['depth'] = $cursor->depth; } + parent::enterHash($cursor, $type, $class, false); if ($cursor->skipChildren || $cursor->depth >= $this->displayOptions['maxDepth']) { @@ -102,6 +108,7 @@ public function enterHash(Cursor $cursor, int $type, string|int|null $class, boo $this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r); } + $this->line .= $eol; $this->dumpLine($cursor->depth); } @@ -113,6 +120,7 @@ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, boo if ($hasChild) { $this->line .= '</samp>'; } + parent::leaveHash($cursor, $type, $class, $hasChild, 0); } @@ -128,6 +136,7 @@ protected function style(string $style, string $value, array $attr = []): string if (empty($attr['count'])) { return sprintf('<a class=sf-dump-ref>%s</a>', $v); } + $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2) . substr($value, 1); return sprintf( @@ -158,8 +167,9 @@ protected function style(string $style, string $value, array $attr = []): string if (isset($attr['ellipsis-type'])) { $class = sprintf('"%s sf-dump-ellipsis-%s"', $class, $attr['ellipsis-type']); } + $label = esc(substr($value, -$attr['ellipsis'])); - $style = str_replace(' title="', " title=\"$v\n", $style); + $style = str_replace(' title="', sprintf(' title="%s%s', $v, PHP_EOL), $style); $v = sprintf('<span class=%s>%s</span>', $class, substr($v, 0, -\strlen($label))); if (!empty($attr['ellipsis-tail'])) { @@ -171,12 +181,14 @@ protected function style(string $style, string $value, array $attr = []): string } $map = static::$controlCharsMap; - $v = "<span class=sf-dump-{$style}>" . preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { - $s = $b = '<span class="sf-dump-default'; + $v = sprintf('<span class=sf-dump-%s>', $style) . preg_replace_callback(static::$controlCharsRx, static function ($c) use ($map) { + $s = '<span class="sf-dump-default'; + $b = '<span class="sf-dump-default'; $c = $c[$i = 0]; if ($ns = "\r" === $c[$i] || "\n" === $c[$i]) { $s .= ' sf-dump-ns'; } + $s .= '">'; do { if (("\r" === $c[$i] || "\n" === $c[$i]) !== $ns) { @@ -184,26 +196,28 @@ protected function style(string $style, string $value, array $attr = []): string if ($ns = !$ns) { $s .= ' sf-dump-ns'; } + $s .= '">'; } $s .= $map[$c[$i]] ?? sprintf('\x%02X', \ord($c[$i])); } while (isset($c[++$i])); - return $s . '</span>'; }, $v) . '</span>'; if (!($attr['binary'] ?? false)) { - $v = preg_replace_callback(static::$unicodeCharsRx, fn($c) => '<span class=sf-dump-default>\u{' . strtoupper(dechex(mb_ord($c[0]))) . '}</span>', $v); + $v = preg_replace_callback(static::$unicodeCharsRx, static fn($c) => '<span class=sf-dump-default>\u{' . strtoupper(dechex(mb_ord($c[0]))) . '}</span>', $v); } if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], $attr['line'] ?? 0)) { $attr['href'] = $href; } + if (isset($attr['href'])) { if ('label' === $style) { $v .= '^'; } + $target = isset($attr['file']) ? '' : ' target="_blank"'; $v = sprintf( '<a href="%s"%s rel="noopener noreferrer">%s</a>', @@ -212,9 +226,11 @@ protected function style(string $style, string $value, array $attr = []): string $v, ); } + if (isset($attr['lang'])) { $v = sprintf('<code class="%s">%s</code>', esc($attr['lang']), $v); } + if ('label' === $style) { $v .= ' '; } @@ -233,16 +249,19 @@ protected function dumpLine(int $depth, bool $endOfValue = false): void if ($this->extraDisplayOptions) { $args[] = json_encode($this->extraDisplayOptions, \JSON_FORCE_OBJECT); } + // Replace is for BC $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args)); } + $this->lastDepth = $depth; - $this->line = mb_encode_numericentity($this->line, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'); + $this->line = mb_encode_numericentity((string) $this->line, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'); if (-1 === $depth) { AbstractDumper::dumpLine(0); } + AbstractDumper::dumpLine($depth); } diff --git a/app/modules/Webhooks/Domain/Delivery.php b/app/modules/Webhooks/Domain/Delivery.php index db8b68e..2157399 100644 --- a/app/modules/Webhooks/Domain/Delivery.php +++ b/app/modules/Webhooks/Domain/Delivery.php @@ -17,20 +17,20 @@ class Delivery { #[Column(type: 'datetime')] - private \DateTimeInterface $createdAt; + private readonly \DateTimeInterface $createdAt; /** @internal */ public function __construct( #[Column(type: 'string(36)', primary: true, typecast: 'uuid')] - private Uuid $uuid, + private readonly Uuid $uuid, #[Column(type: 'string(36)', typecast: 'uuid')] - private Uuid $webhookUuid, + private readonly Uuid $webhookUuid, #[Column(type: 'text')] - private string $payload, + private readonly string $payload, #[Column(type: 'text')] - private string $response, + private readonly string $response, #[Column(type: 'integer')] - private int $status, + private readonly int $status, ) { $this->createdAt = new \DateTimeImmutable(); } diff --git a/app/modules/Webhooks/Interfaces/Console/Command/RegisterCommand.php b/app/modules/Webhooks/Interfaces/Console/Command/RegisterCommand.php index bd776ad..10c6c47 100644 --- a/app/modules/Webhooks/Interfaces/Console/Command/RegisterCommand.php +++ b/app/modules/Webhooks/Interfaces/Console/Command/RegisterCommand.php @@ -22,10 +22,10 @@ public function __invoke( ): int { foreach ($locator->findAll() as $webhook) { try { - $this->writeln("Registering webhook: {$webhook->key} for event: {$webhook->event} at {$webhook->url}"); + $this->writeln(sprintf('Registering webhook: %s for event: %s at %s', $webhook->key, $webhook->event, $webhook->url)); $registry->register($webhook); } catch (WebhooksAlreadyExistsException) { - $this->warning("Webhook with key {$webhook->key} already exists"); + $this->warning(sprintf('Webhook with key %s already exists', $webhook->key)); } } diff --git a/app/modules/Webhooks/Interfaces/Job/RetryPolicy.php b/app/modules/Webhooks/Interfaces/Job/RetryPolicy.php index 4794f01..4d6c723 100644 --- a/app/modules/Webhooks/Interfaces/Job/RetryPolicy.php +++ b/app/modules/Webhooks/Interfaces/Job/RetryPolicy.php @@ -33,7 +33,7 @@ public function nextRetry(): void } $this->timer->sleep($this->getDelay()); - $this->currentRetry++; + ++$this->currentRetry; } private function getDelay(): int diff --git a/app/modules/Webhooks/Interfaces/Job/Timer.php b/app/modules/Webhooks/Interfaces/Job/Timer.php index e9d80d2..c904e2b 100644 --- a/app/modules/Webhooks/Interfaces/Job/Timer.php +++ b/app/modules/Webhooks/Interfaces/Job/Timer.php @@ -10,7 +10,7 @@ public function __construct(?\Closure $timer = null) { - $this->timer = $timer ?? function (int $seconds): void { + $this->timer = $timer ?? static function (int $seconds) : void { \sleep($seconds); }; } diff --git a/app/src/Application/Auth/JWTTokenStorage.php b/app/src/Application/Auth/JWTTokenStorage.php index e85d7c0..6327057 100644 --- a/app/src/Application/Auth/JWTTokenStorage.php +++ b/app/src/Application/Auth/JWTTokenStorage.php @@ -54,7 +54,7 @@ public function load(string $id): ?TokenInterface public function create(array|\JsonSerializable $payload, \DateTimeInterface $expiresAt = null): TokenInterface { $issuedAt = ($this->time)('now'); - $expiresAt = $expiresAt ?? ($this->time)($this->expiresAt); + $expiresAt ??= ($this->time)($this->expiresAt); $token = [ 'iat' => $issuedAt->getTimestamp(), 'exp' => $expiresAt->getTimestamp(), diff --git a/app/src/Application/Bootloader/AppBootloader.php b/app/src/Application/Bootloader/AppBootloader.php index cdc8c72..3ce1c3e 100644 --- a/app/src/Application/Bootloader/AppBootloader.php +++ b/app/src/Application/Bootloader/AppBootloader.php @@ -24,21 +24,13 @@ final class AppBootloader extends DomainBootloader public function defineSingletons(): array { return [ - CoreInterface::class => fn( - Core $core, - ContainerInterface $container, - ?EventDispatcherInterface $dispatcher = null, - ): InterceptableCore => self::domainCore($core, $container, $dispatcher), + CoreInterface::class => static fn(Core $core, ContainerInterface $container, ?EventDispatcherInterface $dispatcher = null): InterceptableCore => self::domainCore($core, $container, $dispatcher), - UrlTemplate::class => fn( - EnvironmentInterface $env, - ): UrlTemplate => new UrlTemplate( + UrlTemplate::class => static fn(EnvironmentInterface $env): UrlTemplate => new UrlTemplate( template: $env->get('IDE_URL_TEMPLATE', 'phpstorm://open?url=file://%s&line=%d'), ), - AppVersion::class => fn( - EnvironmentInterface $env, - ): AppVersion => new AppVersion( + AppVersion::class => static fn(EnvironmentInterface $env): AppVersion => new AppVersion( version: $env->get('APP_VERSION', 'dev'), ), ]; diff --git a/app/src/Application/Commands/HandleReceivedEvent.php b/app/src/Application/Commands/HandleReceivedEvent.php index 636952e..93bdd7e 100644 --- a/app/src/Application/Commands/HandleReceivedEvent.php +++ b/app/src/Application/Commands/HandleReceivedEvent.php @@ -10,6 +10,7 @@ final readonly class HandleReceivedEvent implements CommandInterface, \JsonSerializable { public Uuid $uuid; + public float $timestamp; public function __construct( diff --git a/app/src/Application/Domain/Entity/ExtendedTypecast.php b/app/src/Application/Domain/Entity/ExtendedTypecast.php index 3e0d528..f6b062d 100644 --- a/app/src/Application/Domain/Entity/ExtendedTypecast.php +++ b/app/src/Application/Domain/Entity/ExtendedTypecast.php @@ -13,6 +13,7 @@ final class ExtendedTypecast implements CastableInterface, UncastableInterface { private array $rules = []; + private array $availableRules = ['uuid', 'json']; public function setRules(array $rules): array @@ -36,7 +37,7 @@ public function cast(array $data): array $data[$column] = match ($rule) { 'uuid' => Uuid::fromString($data[$column]), - 'json' => new Json(\json_decode($data[$column], true)), + 'json' => new Json(\json_decode((string) $data[$column], true)), default => $data[$column], }; } diff --git a/app/src/Application/Domain/ValueObjects/Json.php b/app/src/Application/Domain/ValueObjects/Json.php index 56fd598..33aeec4 100644 --- a/app/src/Application/Domain/ValueObjects/Json.php +++ b/app/src/Application/Domain/ValueObjects/Json.php @@ -21,7 +21,7 @@ final public static function typecast(mixed $value): self try { return new self( - (array) \json_decode($value, true), + (array) \json_decode((string) $value, true), ); } catch (\JsonException $e) { throw new \InvalidArgumentException($e->getMessage(), $e->getCode(), $e); @@ -37,6 +37,6 @@ public function jsonSerialize(): array public function __toString(): string { - return \json_encode($this); + return (string) \json_encode($this); } } diff --git a/app/src/Application/Domain/ValueObjects/Uuid.php b/app/src/Application/Domain/ValueObjects/Uuid.php index 5d5b1e1..e6e0b8e 100644 --- a/app/src/Application/Domain/ValueObjects/Uuid.php +++ b/app/src/Application/Domain/ValueObjects/Uuid.php @@ -8,7 +8,7 @@ final class Uuid implements \Stringable { - private UuidInterface $uuid; + private readonly UuidInterface $uuid; public static function generate(): self { diff --git a/app/src/Application/Event/EventTypeMapper.php b/app/src/Application/Event/EventTypeMapper.php index def7aa5..c96a146 100644 --- a/app/src/Application/Event/EventTypeMapper.php +++ b/app/src/Application/Event/EventTypeMapper.php @@ -24,7 +24,7 @@ public function toPreview(string $type, array|\JsonSerializable $payload): array public function register(string $type, EventTypeMapperInterface $mapper): void { if (isset($this->mappers[$type])) { - throw new \RuntimeException("Mapper for type [$type] already registered"); + throw new \RuntimeException(sprintf('Mapper for type [%s] already registered', $type)); } $this->mappers[$type] = $mapper; diff --git a/app/src/Application/HTTP/Interceptor/UuidParametersConverterInterceptor.php b/app/src/Application/HTTP/Interceptor/UuidParametersConverterInterceptor.php index fff211c..1e0a950 100644 --- a/app/src/Application/HTTP/Interceptor/UuidParametersConverterInterceptor.php +++ b/app/src/Application/HTTP/Interceptor/UuidParametersConverterInterceptor.php @@ -18,6 +18,7 @@ public function process(string $controller, string $action, array $parameters, C if ($parameter->getType() instanceof \ReflectionUnionType) { continue; } + if ($parameter->getType()->getName() === Uuid::class) { $parameters[$parameter->getName()] = Uuid::fromString($parameters[$parameter->getName()]); } diff --git a/app/src/Application/HTTP/Middleware/JsonPayloadMiddleware.php b/app/src/Application/HTTP/Middleware/JsonPayloadMiddleware.php index 73461be..0762fe5 100644 --- a/app/src/Application/HTTP/Middleware/JsonPayloadMiddleware.php +++ b/app/src/Application/HTTP/Middleware/JsonPayloadMiddleware.php @@ -40,7 +40,7 @@ private function isJsonPayload(ServerRequestInterface $request): bool $contentType = $request->getHeaderLine('Content-Type'); foreach ($this->config->getContentTypes() as $allowedType) { - if (\stripos($contentType, $allowedType) === 0) { + if (\stripos($contentType, (string) $allowedType) === 0) { return true; } } diff --git a/app/src/Application/HTTP/Response/JsonResource.php b/app/src/Application/HTTP/Response/JsonResource.php index 847c207..4827584 100644 --- a/app/src/Application/HTTP/Response/JsonResource.php +++ b/app/src/Application/HTTP/Response/JsonResource.php @@ -12,11 +12,8 @@ class JsonResource implements ResourceInterface { use JsonTrait; - protected readonly mixed $data; - - public function __construct(mixed $data = []) + public function __construct(protected readonly mixed $data = []) { - $this->data = $data; } protected function mapData(): array|JsonSerializable diff --git a/app/src/Application/Service/HttpHandler/HandlerPipeline.php b/app/src/Application/Service/HttpHandler/HandlerPipeline.php index f070ad0..64c83cc 100644 --- a/app/src/Application/Service/HttpHandler/HandlerPipeline.php +++ b/app/src/Application/Service/HttpHandler/HandlerPipeline.php @@ -16,7 +16,9 @@ final class HandlerPipeline implements HandlerRegistryInterface, CoreHandlerInte { /** @var HandlerInterface[] */ private array $handlers = []; + private int $position = 0; + private bool $isHandled = false; public function __construct( @@ -56,7 +58,7 @@ private function handlePipeline(ServerRequestInterface $request): ResponseInterf { $handler = $this->handlers[$this->position] ?? null; - $this->position++; + ++$this->position; if ($handler === null) { return new Response(404); diff --git a/app/src/Integration/Auth0/Auth0Bootloader.php b/app/src/Integration/Auth0/Auth0Bootloader.php index 1346e9e..cde1496 100644 --- a/app/src/Integration/Auth0/Auth0Bootloader.php +++ b/app/src/Integration/Auth0/Auth0Bootloader.php @@ -41,7 +41,7 @@ public function defineBindings(): array clientId: $env->get('AUTH_CLIENT_ID'), redirectUri: $env->get('AUTH_CALLBACK_URL'), clientSecret: $env->get('AUTH_CLIENT_SECRET'), - scope: \explode(',', $env->get('AUTH_SCOPES', 'openid,profile,email')), + scope: \explode(',', (string) $env->get('AUTH_SCOPES', 'openid,profile,email')), cookieSecret: $env->get('AUTH_COOKIE_SECRET', $env->get('ENCRYPTER_KEY') ?? 'secret'), ), ]; diff --git a/app/src/Integration/Kinde/Client.php b/app/src/Integration/Kinde/Client.php index 94fe899..70c978e 100644 --- a/app/src/Integration/Kinde/Client.php +++ b/app/src/Integration/Kinde/Client.php @@ -15,8 +15,11 @@ final readonly class Client { private string $authorizationEndpoint; + private string $tokenEndpoint; + private string $logoutEndpoint; + private JwtTokenParser $tokenParser; public function __construct( diff --git a/app/src/Integration/Kinde/SessionStorage.php b/app/src/Integration/Kinde/SessionStorage.php index 896aaca..02e4e46 100644 --- a/app/src/Integration/Kinde/SessionStorage.php +++ b/app/src/Integration/Kinde/SessionStorage.php @@ -17,7 +17,7 @@ public function getToken($associative = true): array|object|null { $token = $this->get(StorageEnums::TOKEN); - return empty($token) ? null : \json_decode($token, $associative); + return empty($token) ? null : \json_decode((string) $token, $associative); } public function setToken(string $token): void diff --git a/app/src/Interfaces/Console/CheckDatabaseConnectionCommand.php b/app/src/Interfaces/Console/CheckDatabaseConnectionCommand.php index d152bb4..410960b 100644 --- a/app/src/Interfaces/Console/CheckDatabaseConnectionCommand.php +++ b/app/src/Interfaces/Console/CheckDatabaseConnectionCommand.php @@ -25,7 +25,7 @@ public function __invoke(DatabaseInterface $db): int $this->info('Database connection is OK'); break; } catch (\Throwable $e) { - $tries++; + ++$tries; $this->error($e->getMessage()); $delay = (int) ($multiplier * $tries); $this->error('Cannot connect to the database. Retrying in ' . $delay . ' second...'); diff --git a/app/src/Interfaces/Http/Handler/Content.php b/app/src/Interfaces/Http/Handler/Content.php index 166e40b..108980a 100644 --- a/app/src/Interfaces/Http/Handler/Content.php +++ b/app/src/Interfaces/Http/Handler/Content.php @@ -7,6 +7,7 @@ final readonly class Content implements \Stringable { public int $len; + public string $contentType; public function __construct( diff --git a/tests/App/Broadcasting/BroadcastFaker.php b/tests/App/Broadcasting/BroadcastFaker.php index 138fb34..5490644 100644 --- a/tests/App/Broadcasting/BroadcastFaker.php +++ b/tests/App/Broadcasting/BroadcastFaker.php @@ -12,8 +12,7 @@ { public function __construct( private Container $container, - ) { - } + ) {} public function dump(): self { @@ -31,7 +30,7 @@ public function reset(): self public function assertPushedTimes(string|\Stringable $topic, int $times = 1): array { - $messages = $this->filterMessages((string)$topic); + $messages = $this->filterMessages((string) $topic); TestCase::assertCount( $times, @@ -50,7 +49,7 @@ public function assertPushedTimes(string|\Stringable $topic, int $times = 1): ar public function assertPushed(string|\Stringable $topic, \Closure $callback = null): self { - $messages = $this->filterMessages((string)$topic, $callback); + $messages = $this->filterMessages((string) $topic, $callback); TestCase::assertTrue( $messages !== [], @@ -62,7 +61,7 @@ public function assertPushed(string|\Stringable $topic, \Closure $callback = nul public function assertNotPushed(string|\Stringable $topic, \Closure $callback = null): self { - $messages = $this->filterMessages((string)$topic, $callback); + $messages = $this->filterMessages((string) $topic, $callback); TestCase::assertCount( 0, diff --git a/tests/App/Console/SpyConsoleInvoker.php b/tests/App/Console/SpyConsoleInvoker.php index a897dee..6fca374 100644 --- a/tests/App/Console/SpyConsoleInvoker.php +++ b/tests/App/Console/SpyConsoleInvoker.php @@ -4,7 +4,6 @@ namespace Tests\App\Console; - use PHPUnit\Framework\TestCase; use Spiral\Console\Command; use Spiral\Core\InvokerInterface; diff --git a/tests/App/Events/EventExpectation.php b/tests/App/Events/EventExpectation.php index 2b73b04..334c00f 100644 --- a/tests/App/Events/EventExpectation.php +++ b/tests/App/Events/EventExpectation.php @@ -8,12 +8,11 @@ use Mockery\CompositeExpectation; use Modules\Events\Domain\Event; -final class EventExpectation +final readonly class EventExpectation { public function __construct( private CompositeExpectation $expectation, - ) { - } + ) {} public function andReturnEvent(Event $event): void { diff --git a/tests/App/Events/EventsMocker.php b/tests/App/Events/EventsMocker.php index 49f9e5c..86eebef 100644 --- a/tests/App/Events/EventsMocker.php +++ b/tests/App/Events/EventsMocker.php @@ -14,14 +14,13 @@ { public function __construct( private MockInterface&EventRepositoryInterface $events, - ) { - } + ) {} public function eventShouldBeFound(Uuid|string $uuid, ?Event $result): self { $this->events ->shouldReceive('findByPK') - ->with((string)$uuid) + ->with((string) $uuid) ->once() ->andReturn($result); @@ -33,7 +32,7 @@ public function shouldRequestEventByUuid(Uuid $uuid): EventExpectation return new EventExpectation( $this->events ->shouldReceive('findByPK') - ->with((string)$uuid) + ->with((string) $uuid) ->once(), ); } @@ -42,7 +41,7 @@ public function eventShouldBeDeleted(Uuid $uuid, bool $status = true): void { $this->events ->shouldReceive('deleteByPK') - ->with((string)$uuid) + ->with((string) $uuid) ->once() ->andReturn($status); } @@ -51,7 +50,7 @@ public function eventShouldNotBeDeleted(Uuid $uuid): void { $this->events ->shouldNotReceive('deleteByPK') - ->with((string)$uuid); + ->with((string) $uuid); } public function eventShouldBeClear(?string $type = null, ?string $project = null, ?array $uuids = null): void @@ -68,7 +67,7 @@ public function eventShouldBeClear(?string $type = null, ?string $project = null $this->events ->shouldReceive('deleteAll') - ->withArgs(function (array $data) use ($args): bool { + ->withArgs(static function (array $data) use ($args) : bool { TestCase::assertSame($args, $data); return true; }) diff --git a/tests/App/Http/HttpFaker.php b/tests/App/Http/HttpFaker.php index 784bca5..114f47a 100644 --- a/tests/App/Http/HttpFaker.php +++ b/tests/App/Http/HttpFaker.php @@ -116,7 +116,7 @@ public function clearEvents(?string $type = null, ?string $project = null, ?arra public function __call(string $name, array $arguments): ResponseAssertions|self { if (!method_exists($this->http, $name)) { - throw new \Exception("Method $name does not exist"); + throw new \Exception(sprintf('Method %s does not exist', $name)); } if (\str_starts_with($name, 'with')) { diff --git a/tests/App/Http/ResponseAssertions.php b/tests/App/Http/ResponseAssertions.php index e1e18d3..337a4df 100644 --- a/tests/App/Http/ResponseAssertions.php +++ b/tests/App/Http/ResponseAssertions.php @@ -211,7 +211,7 @@ public function getCookies(): array public function __call(string $name, array $arguments): self { if (!method_exists($this->response, $name)) { - throw new \Exception("Method $name does not exist"); + throw new \Exception(sprintf('Method %s does not exist', $name)); } $this->response->$name(...$arguments); diff --git a/tests/App/Sentry/FakeTransport.php b/tests/App/Sentry/FakeTransport.php index 4d30ba0..9e785f5 100644 --- a/tests/App/Sentry/FakeTransport.php +++ b/tests/App/Sentry/FakeTransport.php @@ -18,12 +18,11 @@ final class FakeTransport implements TransportInterface public function __construct( private readonly PayloadSerializerInterface $payloadSerializer, - ) { - } + ) {} public function send(Event $event): Result { - $this->events[(string)$event->getId()] = $this->payloadSerializer->serialize($event); + $this->events[(string) $event->getId()] = $this->payloadSerializer->serialize($event); return new Result(ResultStatus::success(), $event); } @@ -35,6 +34,6 @@ public function close(?int $timeout = null): Result public function findEvent(EventId $id): string { - return $this->events[(string)$id] ?? throw new \InvalidArgumentException('Event not found'); + return $this->events[(string) $id] ?? throw new \InvalidArgumentException('Event not found'); } } diff --git a/tests/DatabaseTestCase.php b/tests/DatabaseTestCase.php index c1d8fca..089c6be 100644 --- a/tests/DatabaseTestCase.php +++ b/tests/DatabaseTestCase.php @@ -20,7 +20,10 @@ abstract class DatabaseTestCase extends TestCase { - use Transactions, Helper, DatabaseAsserts, ShowQueries; + use Transactions; + use Helper; + use DatabaseAsserts; + use ShowQueries; private DriverEnum $dbDriver; @@ -29,7 +32,7 @@ protected function setUp(): void parent::setUp(); $this->dbDriver = $this->get(DriverEnum::class); -// $this->getRefreshStrategy()->enableRefreshAttribute(); + // $this->getRefreshStrategy()->enableRefreshAttribute(); } protected function tearDown(): void @@ -48,6 +51,7 @@ public function persist(object ...$entity): void foreach ($entity as $e) { $em->persist($e); } + $em->run(); } diff --git a/tests/Feature/Interfaces/Console/RegisterModulesTest.php b/tests/Feature/Interfaces/Console/RegisterModulesTest.php index c77d78e..4bf76ef 100644 --- a/tests/Feature/Interfaces/Console/RegisterModulesTest.php +++ b/tests/Feature/Interfaces/Console/RegisterModulesTest.php @@ -9,17 +9,17 @@ final class RegisterModulesTest extends TestCase { -// #[Env('PERSISTENCE_DRIVER', 'mongodb')] -// public function testCommandWithMongoDriver(): void -// { -// $this->spyConsole(function () { -// $this->getConsole()->run('register:modules'); -// }, ['register:modules']) -// ->assertCommandNotRun('migrate') -// ->assertCommandRun('webhooks:register') -// ->assertCommandRun('metrics:declare') -// ->assertCommandRun('projects:register'); -// } + // #[Env('PERSISTENCE_DRIVER', 'mongodb')] + // public function testCommandWithMongoDriver(): void + // { + // $this->spyConsole(function () { + // $this->getConsole()->run('register:modules'); + // }, ['register:modules']) + // ->assertCommandNotRun('migrate') + // ->assertCommandRun('webhooks:register') + // ->assertCommandRun('metrics:declare') + // ->assertCommandRun('projects:register'); + // } #[Env('PERSISTENCE_DRIVER', 'database')] public function testCommandWithDatabaseDriver(): void diff --git a/tests/Feature/Interfaces/Http/Events/ClearActionTest.php b/tests/Feature/Interfaces/Http/Events/ClearActionTest.php index f16150a..99f151a 100644 --- a/tests/Feature/Interfaces/Http/Events/ClearActionTest.php +++ b/tests/Feature/Interfaces/Http/Events/ClearActionTest.php @@ -65,10 +65,10 @@ public function testClearEventsByUuids(): void $this->http ->clearEvents(uuids: [ - (string)$event1->getUuid(), - (string)$event2->getUuid(), - (string)$event3->getUuid(), - (string)$event4->getUuid(), + (string) $event1->getUuid(), + (string) $event2->getUuid(), + (string) $event3->getUuid(), + (string) $event4->getUuid(), ]) ->assertSuccessResource(); @@ -87,9 +87,9 @@ public function testClearEventsByTypeAndUuids(): void $this->http ->clearEvents(type: 'foo', uuids: [ - (string)$event1->getUuid(), - (string)$event2->getUuid(), - (string)$event3->getUuid(), + (string) $event1->getUuid(), + (string) $event2->getUuid(), + (string) $event3->getUuid(), ]) ->assertSuccessResource(); diff --git a/tests/Feature/Interfaces/Http/Events/ShowActionTest.php b/tests/Feature/Interfaces/Http/Events/ShowActionTest.php index 7e2883d..2c4a5d0 100644 --- a/tests/Feature/Interfaces/Http/Events/ShowActionTest.php +++ b/tests/Feature/Interfaces/Http/Events/ShowActionTest.php @@ -29,7 +29,7 @@ public function testNotFoundShowEvent(): void ->showEvent($uuid) ->assertNotFound() ->assertJsonResponseSame([ - 'message' => 'Event with given uuid ['.$uuid.'] was not found.', + 'message' => 'Event with given uuid [' . $uuid . '] was not found.', 'code' => 404, ]); } diff --git a/tests/Feature/Interfaces/Http/Inspector/InspectorActionTest.php b/tests/Feature/Interfaces/Http/Inspector/InspectorActionTest.php index e3df98f..e4c7a33 100644 --- a/tests/Feature/Interfaces/Http/Inspector/InspectorActionTest.php +++ b/tests/Feature/Interfaces/Http/Inspector/InspectorActionTest.php @@ -104,7 +104,7 @@ public function testSendDataWithWrongSecretKey(): void public function assertEvent(?string $project = null): void { - $this->broadcastig->assertPushed((string) new EventsChannel($project), function (array $data) use($project) { + $this->broadcastig->assertPushed((string) new EventsChannel($project), function (array $data) use ($project) { $this->assertSame('event.received', $data['event']); $this->assertSame('inspector', $data['data']['type']); $this->assertSame($project, $data['data']['project']); diff --git a/tests/Feature/Interfaces/Http/Profiler/ProfilerActionTest.php b/tests/Feature/Interfaces/Http/Profiler/ProfilerActionTest.php index 73cb59a..f46debf 100644 --- a/tests/Feature/Interfaces/Http/Profiler/ProfilerActionTest.php +++ b/tests/Feature/Interfaces/Http/Profiler/ProfilerActionTest.php @@ -47,7 +47,7 @@ public function testSendDataWithProject(): void public function assertEvent(?string $project = null): void { - $this->broadcastig->assertPushed((string)new EventsChannel($project), function (array $data) use ($project) { + $this->broadcastig->assertPushed((string) new EventsChannel($project), function (array $data) use ($project) { $this->assertSame('event.received', $data['event']); $this->assertSame('profiler', $data['data']['type']); $this->assertSame($project, $data['data']['project']); diff --git a/tests/Feature/Interfaces/Http/Ray/RayActionTest.php b/tests/Feature/Interfaces/Http/Ray/RayActionTest.php index 6013ba3..15b23cd 100644 --- a/tests/Feature/Interfaces/Http/Ray/RayActionTest.php +++ b/tests/Feature/Interfaces/Http/Ray/RayActionTest.php @@ -236,7 +236,7 @@ public function testSendObject(): void $this->dump($object); $id = \spl_object_id($object); - $this->broadcastig->assertPushed((string) new EventsChannel(), function (array $data) use($id) { + $this->broadcastig->assertPushed((string) new EventsChannel(), function (array $data) use ($id) { $this->assertSame('event.received', $data['event']); $this->assertSame('ray', $data['data']['type']); diff --git a/tests/Feature/Interfaces/Http/Sentry/SentryControllerTestCase.php b/tests/Feature/Interfaces/Http/Sentry/SentryControllerTestCase.php index aafb8fe..c8fa00b 100644 --- a/tests/Feature/Interfaces/Http/Sentry/SentryControllerTestCase.php +++ b/tests/Feature/Interfaces/Http/Sentry/SentryControllerTestCase.php @@ -24,7 +24,7 @@ public function makeEventPayload(string $message, ?Severity $level = null): stri { $client = $this->getClient(); - $level = $level ?? Severity::info(); + $level ??= Severity::info(); $scope = new Scope(); diff --git a/tests/Feature/Interfaces/Http/Sentry/SentryVueReplayActionTest.php b/tests/Feature/Interfaces/Http/Sentry/SentryVueReplayActionTest.php index 99424e3..7209b6c 100644 --- a/tests/Feature/Interfaces/Http/Sentry/SentryVueReplayActionTest.php +++ b/tests/Feature/Interfaces/Http/Sentry/SentryVueReplayActionTest.php @@ -1,100 +1,153 @@ -<?php - -declare(strict_types=1); - -namespace Interfaces\Http\Sentry; - -use Modules\Projects\Domain\Project; -use Modules\Projects\Domain\ValueObject\Key; -use Nyholm\Psr7\Stream; -use Tests\App\Http\ResponseAssertions; -use Tests\Feature\Interfaces\Http\ControllerTestCase; - -final class SentryVueReplayActionTest extends ControllerTestCase -{ - protected const JSON = <<<'BODY' -{"event_id":"53cbfd0ae9fd4ea783cec45310432a3c","sent_at":"2024-06-14T08:10:06.632Z","sdk":{"name":"sentry.javascript.vue","version":"8.9.2"}} -{"type":"replay_event"} -{"type":"replay_event","replay_start_timestamp":1718352515.3176,"timestamp":1718352606.631,"error_ids":["800d6a6ef3174aa5ba3f619204f9d1a9"],"trace_ids":[],"urls":["http://localhost:5173/"],"replay_id":"53cbfd0ae9fd4ea783cec45310432a3c","segment_id":0,"replay_type":"buffer","request":{"url":"http://localhost:5173/","headers":{"Referer":"http://localhost:5173/","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"}},"event_id":"53cbfd0ae9fd4ea783cec45310432a3c","environment":"production","sdk":{"integrations":["InboundFilters","FunctionToString","BrowserApiErrors","Breadcrumbs","GlobalHandlers","LinkedErrors","Dedupe","HttpContext","Vue","BrowserTracing","Replay","ReplayCanvas"],"name":"sentry.javascript.vue","version":"8.9.2"},"transaction":"home","platform":"javascript"} -{"type":"replay_recording","length":5315} -{"segment_id":0} -xÜ\ërÛ6~:ͤ]Q)ëÉì¶étmffû£ît S¤d{3~÷ý xE9VÛT¶eÎýà@úõc'½ßÓÎüªÛYtæ;Û®;óÎ6M÷ó~?dKnYÎGÞdØït;·Á*Ývæ7t;[l¶)îÞô¡ÛIMR²Û£eâM#<¼«®hdï£ -0`û4`Q)÷ä>ddÅ%[vWoéÅ«W$:¤3Oãív$èÿCú¤lÐóºÇ,6[ÑvHè+¶ÛÇÙ7b"go¾ Ãé*6Yã$¼ígzbM¯£ý!ÕH«Ö¦·,¾ù¦$ Éû8Ä5 üá+²O1ýªÁÉgoé`Fþ@ÉÆÕçÉ¢å9ãý½[¡A=Û \ýVÓ*6Ed¨Â.äR8,Â`ùbèà.¹ORºSwþû É Ã -ÃIÆÁâòI>vBqÓ¨µ©¿da´¸Ï+/·$N($Ùyÿó÷î´ÂoA#AaÝT`ÆñïÒ2:ý£AYh±L2¶LR¸È1 ·{§x¾dQJ#>ýå%uÅM× ¢ -Hè&0búÒë -lXL,X¤AÒ¶b$äFék¼üI=ÈÙà*jgKÒûêl²£Ý_&ÜpEvAJ]ër~ÌXÚé%}²ß'ýãºû} Ë´ÄË>I ñ¤¿#AÔãPZ1çëSwéÞn1ïÜùb-^/ -ÍnÂÖ)6å?¥g;ÐÃùüG?[dyfoÊÍ -/^¥g?å?úY -ãíË! -tû*8ðnÈÒõæN¼YçãA×Q?ûÊÒ߯íïùÕþ+ßhðÓ«®£þ½ñÈÒ]A/v¿æݹ@rÔ$~^ ·¶c=Îãq©³BØ*ÄU×Mô£®¿êº?ä²d!ÝÄ´Ù!ZYÀ»IyûæúTðfsb%ýJòtv·ìØ8Ä3pçDBoSdFWÞÜÜ/Á"tº²;Þ¬ý×cç9ëÑMK[ºý\8_9¯#Çi)aB-ebKäöÙNn#LiÛH Ò³^ ëèáë®3/èÅ_uJc°tÁîÜ$øFb¦ÎÄ ;BRk¸M÷V½¹±xGB]°Õ= ìfϼÁà¸}á¤>9À¤*¹2çÑ)I Ä1Ì/ÃGCIBAÒ5d£_8ä4Ǩ7ø¯É.ïçÎk¸ë¸'!¬P$<]ç[þ$Ëwâþ{è:×wtèóþõu§ë¼e²®óæî~C£®ó~qÒC×A¾!ð}çÐç#®;ßÅ,X÷?ÐðHÓ`Ièò¶Ï`q #Ð0 xÞó]H1¦¤"Äsçt,0Hï¡·tq<1xCÙ¾À -9B¦¬ «/@-¹ËÌàO l -A;ä²Î¬2µócº³ tÞ&¦4ÔLÙxòN2¡E,¢Zà\ÃK{ÓÞ|î©Mù0äaÁ~XpÒnÄ?éÈ\Üq-.itéÆ´"JSP ¹æ*nü«ý+{$û@cÖ!&¸F -G¼K È"h,À9d®î¿ð¿Cí±BÁú£uØEécþgÐÉ9±#dzªäHärgB§²,oð'¤YK¬~ Ó©T8d¿°8\õÐëø{Æçx)¦ÐMï^%K¶§«ÔP2xÏøÂà¼mëýaê* ¿Çe - -Fã÷Æ CjÌ*y2¦Çõ²À³ZaKóëIO!¦Ä©AHÚ|^TØìpÃ}RS -ø¤³t6ªÖP«mwIÕúf¿o¡H2!ÃÉâQ$ÖÎK -çR)P¸3¼+Dz^È6¬n¸¶w±·Põ¤Ê¨#r¬®?ø²èú}íúKzMà -UÎa;¤ÏH¸¢Þ%F"Ý:Òºií±ù\` -ÞWxø=¢bÄUOÀmä` YHF<£'© ×epÍ Y)è¢é¨¢»â$uÙÚå"R,y+&£6´«Q8!IrãL·°p_>Ï72㯾#c|MíL5ãZ .2r<Þms;aÞäb/àÄ53wø»À¢ÎU#Õ5ÉÑÔóÌW+YóÛSͳN -Îk¤±ùgÄÅ_h;úlláÏ«Ùb¸áÏz\RJ -N®¦{(º&.>ôVbÿ2©ÈAøá>ª O) nX+r+o7>Pyâì®ÁqåA°}5WÓIRûí`T½+ѱf2¹ãóßmD$t=wubbgÙAÿPËyX -¾t\ÇÇ2¤ úc1¥Ö² A(÷zÒ³¶Z½IW[|ÊçL X³»ÌÙÕ2LWEÔrÝÁïyñ àl @@^³ím -Ñ*CVKëâ\ó'"\ϵg˹&!1!(TؼøD{ñ±º2ÜyÅrLäî3/PÕº}¾{ô7@OáÛV\ظ©Ä7+t@áû¼Òzn5«µð"|eâRHn².ØmªÈd5Uñ¸>Ê Y¥áÛÂrójhTLhÚQÕ]2èSêeVËr×nN¼½RVWwáe£ôâOµø¶RÏvاÖ8ðÉ%ú¥nã¿I$6ó©Âj¹eT®®yö!AÖräek$ªQòûû³¢~Ô·C5hKmUKaì+¶½/zÕáÓxà²xóä:D7mN¡ö˾®÷ù¶"'MQ&ÿU+©^ -#ûCîc¥òdnÒ*É¢ç8uÌB¾¹ÈÎ×mÝÍ'â.1_Ocðlè£ûJï"^mgÐI Å öL1+dõ¾ÔUn¹òiömÆÇÂOª -1Û £R¥bàÉTË(ÝðÙX+öÇjN`$~õ(7±¤É»ÿüÛLõ®f -îFâ5hÉÛLûlVËUnË@n -Âõ¯^j@kV}´ÑÚÛpÙØ®<þÈÆúªøÃÂW5÷ЬÒad(µ-}É©ü¢æAáâËØð66µå×-?7¯1¶n´Õx -3ÃÁúÞÿ]w·âÈNÛ'%§"Ú8±áhëfl£S7ùÓ¢LZhîDëë¸ÉTï&£ÍË°¦ÁÖ öI´}I°9à(EM ?uôä!Ŭ&ÚóNShLQÀlÞá$ñK Ü;ÉçNÓÃ*`=lC_Âó*LuÞ=1"DÃâhbhèy¤mt{Xz>°m°»½éYHøÈ(j6YL!B(ý.(½!lCùe̶Ís;···½å½8ÜØEbÂñJ3¤) )eËOÅp3§JX.A^.'u¥°×ûÓ¦)§Öº YÙ§³lMÜxY©ÊYáGf¶u·O:ñkòg¦d³¦ -«&µQ}´5÷Ç6ãøÜr¦->±ÒòP=)'E¶Sçå¤hÖ"ÏtÚ<{²ôô/¡×f©¥{·POo õiÓ¿)'-®,êMºKtÁcðèTa^¾ØòLã¨oÐ%T=:KÈöÍ.HÂÔ8gÅk Íz®ê$mhMÝC -sº4} ½U)4»fÌ÷pãÓ3=Ag¹|ʼÈh-×Q|lîÓ¼ÂÆd-78)ä&8bââîRéÂ5OÍæÔ¤L¯ßÆ9¢¸©ýiöwÙWEAôÉ6V[{qnÃø\ÛSýëF|³Êx:â7Öõt§\IQôjÑÿäâÈÛ -û1ëqgîlIzé0¡±Ô»iJmw?J>²H÷£÷qZqyâ®C%1Ü¥ø\-ÿq`6tÅýgïÃü¥Ðù´úd;¶bÉ3ªt%Dôöâ)CY'ò2Bãy¦P!¨ü=6_º -Rêy¹}0e@MnÓ`ÒE_Þ%ÒS´qé¨i7§ÝÖªègLQ -üã)ê6§9ÖÛò峦(*¦f¶ØXVÔr=mSØôNò¤ÝcKɾª{|%c«ßªð5.^æ>X|/U-mazy -·mµL5wÛ¬RAñLK1¿4OØêEe£¿ÔÝóMÆX8ªé¡Ê×Üõ:ºæB²Î¹Fê¸ÓÈ/Zx³^ïÀ÷[à®øn -ÀÅ|í{O&ÿgïwÛ8þ*Ó>oUq~éSìÖH*mª*Óöö;¸8#æÿ:Ñ/i)8ÃÝ/¡-£ãýí°ßIP8Z_Þ?îÐyóåó_oD´J©ô¶ú¯+=ݼ«ÏkïE:Átóªí y¥ß}ÞUsåµ'¹b}jÞGùôyåó<¯8Ǽõ1¯ÈrjK^³Yãòn[}»m3'¹fm[mZºyô^ÆËÕ>[=¶mòªg¤Ëk5ocz ç³j74îS]̺êÊ[+ü&\Þçεòó¼ÏÞÝþðëYÐÃËk²e¼|?üôWjúãm/ª>¼Þ½¼í²¸ð(ºåÌÿïØ+®©¾ì{ï×r<ÚÈ -¯Ø83k´{³^IhE\ÒùJD%ÉDüÊp£c#µiä9ÿÈHy¡Ú ÇíRþÝy÷©ÿú§'ñ¡ÿíÃÚÀ.ÔFwÉ_'gËä>®WZ&Ðé}4S~ç·Eþ§×¸È/çãÒ[ö^]¤Ï7?>0Á:~IÕ6´.Ù *Åj¹+Äç~pK¦nüÌ[$Ô*n_èsƨºáN¼J±Ã´ÑX N4Òé¡påcU>VåcU>VåcU>VåcU>Våc -âcSËßtêWÙY5?^r,;öºY¹Z«U¹Z«5/®XØüE7HNü+s«2·*s«2·*skþÌ-°{ßîý!IsÉGã4*pX¨p?Âo?EwèeÓb@^q£Â¸¿õëºÚûAtv·u]äP´¿g÷`@ïÒÓ°3»,ôǯ&Éúl.ÓÙóÅc@w<+VÙðIf4b¤^<&Å -KL(n^Eóâ¼sÓÿKàÎ@ón!$4k¼½^(4 AÆðîË ýVû⦠(ÞlD(ê%ÈvÅrÑÄ|24Nsv 6 ;^ÜL ;6¤ -ÔBàd7GR~ÑVq³Â0Ù ÞPÛR¿hJ¬nD(8xÞ(¤g} Do Òq -è,ü}ÔGÕNÚ)rËWÐ6Ì -,ÂIô&of ]Ò Å°+Àëúd>\Ýí@ ÅÓ`îbÜ -ÒS&(ïλ, h¾,0iÀ1éz%Ðäe ÇÑAfÄ^RÙ)ÄhX=P'90HÆEýsÐbP<þ'Áýhð³²ÁG÷ -NJ:é·Â=MëAA&Ó,GE%ÈÔȤ?¹CÎV+ÀµrÂÄËp±¬bnB® PnIæ2ëbÛë -øÁX}Å1ôtG9qù:Bв'éÌüBPÃxÇi` äÔ<Iz>òW~q -Á{Ñî&HÈq³äkR¶Ð Ãþ%Èì+qYyzp4¯rjPLPÝK -}-@$ä¹ÐÊøÄÛ¦Ù}¸@fñ]Õ< EøeÊ&ñÞñíºbþåĬG :±V|:Ê(±¨´=K$$PÔ[á -ÝÖ¬"¿Á²K^ƨʢ-Û®bØÞSg2ÿBÛ²HløíÈC_lÒÀÃv(±9Ïãïî¼cS-bÅ%×@\ýñM:°¾êÝcÅ}×NÒC³5cäv%±h¾ÔÂÃ,l{07AIuÂJÿ¿À¶ó9·rUõ¯³3ÊmÁð]z --iaÚ{Ý목SÕ¤íüûÿØI!!h§ª±ìÄ¡!ö×|NÓ(ò -®'|sJ \aB6 òö?gÜ<ï¯B ÊaF¬,Éê¹eî<3;3'³qC![qóPö h@%6mKk@ -GPçË>ÒJÃbnÒYUã[D·n)Ìútð²Ûõº[AZ¹nM+Ýã´'¹n¦°kìr¯dÌ5_Vå¦Öä4ÝO¶Tb¤H¶|»ü`±Àþ»\翽2Ò&*P7ô_ÇSwí¹L:Å{|¼+{¦ßàIrü>+1q'5vg2Q^¢8Hø -ìóɬ5Þýö¼·|®ÕËáx¢Æeñëbá/$ø1Þ83®f!ZnïlõÎpÔ5ñë?¢½Ewd½QuøôIÈãµAâÁ·x_VWp gï0=uA«¸³ØIã¶ò}Öb+8{^¯Ù1® -BODY; - - private Project $project; - - protected function setUp(): void - { - parent::setUp(); - - $this->project = $this->createProject('default'); - } - - public function testSend(): void - { - $this->makeRequest(project: $this->project->getKey())->assertOk(); - - $this->markTestIncomplete('This test has not been implemented yet.'); - } - - private function makeRequest(string $secret = 'secret', string|Key $project = 'default'): ResponseAssertions - { - return $this->http - ->postJson( - uri: '/api/' . $project . '/envelope/?sentry_key=' . $secret . '&sentry_version=7&sentry_client=sentry.javascript.vue%2F8.9.2', - data: Stream::create(self::JSON), - headers: [ - 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', - ], - ); - } -} +<?php + +declare(strict_types=1); + +namespace Interfaces\Http\Sentry; + +use Modules\Projects\Domain\Project; +use Modules\Projects\Domain\ValueObject\Key; +use Nyholm\Psr7\Stream; +use Tests\App\Http\ResponseAssertions; +use Tests\Feature\Interfaces\Http\ControllerTestCase; + +final class SentryVueReplayActionTest extends ControllerTestCase +{ + protected const JSON = <<<'BODY' +{"event_id":"53cbfd0ae9fd4ea783cec45310432a3c","sent_at":"2024-06-14T08:10:06.632Z","sdk":{"name":"sentry.javascript.vue","version":"8.9.2"}} +{"type":"replay_event"} +{"type":"replay_event","replay_start_timestamp":1718352515.3176,"timestamp":1718352606.631,"error_ids":["800d6a6ef3174aa5ba3f619204f9d1a9"],"trace_ids":[],"urls":["http://localhost:5173/"],"replay_id":"53cbfd0ae9fd4ea783cec45310432a3c","segment_id":0,"replay_type":"buffer","request":{"url":"http://localhost:5173/","headers":{"Referer":"http://localhost:5173/","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"}},"event_id":"53cbfd0ae9fd4ea783cec45310432a3c","environment":"production","sdk":{"integrations":["InboundFilters","FunctionToString","BrowserApiErrors","Breadcrumbs","GlobalHandlers","LinkedErrors","Dedupe","HttpContext","Vue","BrowserTracing","Replay","ReplayCanvas"],"name":"sentry.javascript.vue","version":"8.9.2"},"transaction":"home","platform":"javascript"} +{"type":"replay_recording","length":5315} +{"segment_id":0} +xÜ\ërÛ6~:ͤ]Q)ëÉì¶étmffû£ît S¤d{3~÷ý xE9VÛT¶eÎýà@úõc'½ßÓÎüªÛYtæ;Û®;óÎ6M÷ó~?dKnYÎGÞdØït;·Á*Ývæ7t;[l¶)îÞô¡ÛIMR²Û£eâM#< +¼«®hdï£ +0`û4`Q)÷ä>ddÅ%[vWoéÅ«W$:¤3Oãív$èÿCú¤lÐóºÇ,6[ÑvHè+¶ÛÇÙ7b"go¾ Ãé*6Yã$¼ígzb +M¯£ý!ÕH«Ö¦·,¾ù¦$ Éû8Ä5 üá+²O1ýªÁÉgoé`Fþ@ÉÆÕçÉ¢å9ãý½[¡A=Û \ýVÓ*6Ed +¨Â.äR8,Â`ùbèà.¹ORºSwþû +É Ã +ÃIÆÁâòI>vBqÓ¨µ©¿da´¸Ï+/·$N($Ùyÿó÷î´ÂoA# +AaÝT`ÆñïÒ2:ý£AYh±L2¶LR¸È1 ·{§x¾dQJ#>ýå%uÅM× ¢ +Hè&0búÒë +lXL,X¤AÒ¶b$ +äFék¼üI=ÈÙà*jgKÒûêl²£Ý_&ÜpEvAJ]ër~ÌXÚé%}²ß'ýãºû} Ë´ÄË>I ñ¤¿#AÔãPZ1çëSwéÞn1ïÜùb-^/ +ÍnÂÖ)6å?¥g;ÐÃùüG?[dyfoÊÍ +/^¥g?å?úY +ãíË! +tû*8ð +nÈÒõæN¼YçãA×Q?ûÊÒ߯íïùÕþ+ßhðÓ«®£þ½ñÈÒ]A/v¿æݹ@rÔ$~^ ·¶c=Îãq©³BØ*ÄU×Mô£®¿êº?ä²d!ÝÄ´Ù!ZYÀ»IyûæúTðfsb% +ýJòtv·ìØ8Ä3pçDBoSdFWÞÜÜ/Á"tº²;Þ¬ý×cç9ëÑMK[ºý\8_9¯#Çi)aB-ebKäöÙNn#LiÛH Ò³^ +ëèáë®3/èÅ_uJc°tÁîÜ$øFb¦ÎÄ ;BRk¸M÷V½¹±xGB]°Õ= ìfϼÁà¸}á¤>9À¤*¹2çÑ)I Ä1Ì/ÃGCIBAÒ5d£ +_8ä4Ǩ7ø¯É.ïçÎk¸ë¸'!¬P$<]ç[þ$Ëwâþ{ +è:×wtèóþõu§ë¼e +²®óæî~C£®ó~qÒC×A¾!ð}çÐç#®;ßÅ,X÷?ÐðHÓ`Ièò¶Ï`q #Ð0 xÞó]H1¦¤"Äsçt,0Hï¡·tq<1xCÙ¾À +9B¦¬ «/@-¹ËÌàO +l +A;ä²Î¬2µócº³ tÞ&¦4ÔLÙxòN2¡E,¢Z +à\ÃK{ÓÞ|î©Mù0äaÁ~XpÒnÄ?éÈ\Üq-.itéÆ´"JSP ¹æ*n +ü«ý+{$û@cÖ!&¸F +G¼K È"h,À9d®î¿ð¿Cí±BÁú£uØEécþgÐÉ9±#dzªäHärgB§²,oð'¤YK¬~ Ó©T8d¿°8\õÐëø{Æçx)¦ÐMï^%K¶§«ÔP2xÏøÂà¼mëýaê* ¿Çe + +Fã÷Æ CjÌ*y2¦ +Çõ²À³ZaKóëIO!¦Ä©AHÚ|^ +TØìpÃ}RS +ø¤³t6ªÖP«mwIÕúf¿o¡H2!ÃÉâQ$ÖÎK +çR)P¸3¼+Dz^È6¬n¸¶w±·Põ¤Ê¨#r¬®?ø²èú}íúKzMà +UÎa;¤ÏH¸¢Þ%F"Ý:Òºií±ù\` +ÞWxø=¢bÄUOÀmä` YHF<£'© ×epÍ +Y +)è¢é¨¢»â$uÙÚå"R,y+&£6´«Q8!IrãL·°p_>Ï72㯾#c|MíL5ãZ .2r<Þm +s;aÞäb/àÄ53wø»À¢ÎU#Õ5ÉÑÔóÌW+YóÛ +SͳN +Îk¤±ùgÄÅ_h;úlláÏ«Ùb¸áÏz\RJ +N®¦{( +º&.>ôVbÿ2©ÈAøá>ª O) nX+r+o7>Pyâì®ÁqåA°}5WÓIRûí`T½+ѱf2¹ãóßmD$t=wubbgÙA +ÿPËyX + +¾t\ÇÇ2¤ úc1¥Ö² +A(÷zÒ³¶Z½IW[|ÊçL X³»ÌÙÕ2LWEÔrÝÁïyñ àl @@^³ím +Ñ*CVKë +â\ó'"\ϵg˹&!1!(TؼøD{ñ±º2ÜyÅrLäî3/PÕº}¾{ô7@OáÛV\ظ©Ä7+t@áû +¼Òzn5«µð"|eâRHn².ØmªÈd5Uñ¸>Ê Y¥áÛÂrójhTLhÚQÕ]2èSêeVËr×nN¼½RVWwáe£ôâOµø¶RÏvاÖ8ðÉ%ú¥nã¿I$6ó©Âj¹eT®®yö!AÖräek$ªQòûû³¢~Ô·C5hKmUKaì+¶½/zÕáÓxà²xóä:D7mN¡ö˾®÷ù¶"'MQ&ÿU+©^ +#ûCîc¥òdnÒ*É¢ç8uÌB¾¹ÈÎ×mÝÍ'â.1_Ocðlè£ûJï"^mgÐI Å öL1+dõ¾ÔUn¹òiömÆÇÂOª +1Û £R¥bàÉTË(ÝðÙX+öÇjN`$~õ(7±¤É»ÿüÛLõ®f +îFâ5hÉÛLûlVËUnË@n +Âõ¯^j@kV}´ÑÚÛpÙØ®<þÈÆúªøÃÂW5÷ЬÒad(µ-}É©ü¢æAáâËØð66µå×-?7¯1¶n´Õx +3ÃÁúÞÿ]w·âÈNÛ'%§"Ú8±áhë +fl +£S7ùÓ¢LZhîDëë¸ÉTï&£ÍË°¦ÁÖ öI´}I°9à(EM ?uôä!Ŭ&ÚóNShLQÀlÞá$ñK Ü;ÉçNÓÃ*`=lC_Âó*LuÞ=1"DÃâhbhèy¤mt{Xz>°m°»½éYHøÈ(j6YL!B(ý.(½!lCùe̶Ís;···½å½8Ü +ØEbÂñJ3¤) +)eËOÅp3§JX.A^.'u¥°×ûÓ¦)§Öº YÙ§³lMÜxY©ÊYáGf¶u·O:ñkòg¦d³¦ +«&µQ}´5÷Ç6ãøÜr¦->±ÒòP=)'E¶Sçå¤hÖ"ÏtÚ<{²ôô/¡×f©¥{·POo õiÓ¿)'-®,êMºKtÁcðèTa^¾ØòLã¨oÐ%T=:KÈöÍ.HÂÔ8gÅk Íz®ê$mhMÝC +sº4} +½U)4»fÌ÷pãÓ3=Ag¹|ʼÈh-×Q|lîÓ¼ÂÆd-78)ä&8bââîRéÂ5OÍæÔ¤L¯ßÆ9¢¸©ýiöwÙWEAôÉ6V[{qnÃø\ÛSýëF|³Êx:â7Öõt§\IQôjÑÿäâÈÛ +û1ëqgîlIzé0¡±Ô»iJmw?J>²H÷£÷qZqyâ®C%1Ü¥ø\-ÿq`6tÅýgïÃü¥Ðù´úd;¶bÉ3ªt%Dôöâ)CY'ò2Bãy¦P!¨ü=6_º +R +êy¹}0e@MnÓ`ÒE_Þ%ÒS´qé¨i7§ÝÖªègLQ +üã)ê6§9ÖÛòå³ +¦(* +¦f¶ØXVÔr=mSØôNò¤ÝcKɾª{|%c«ßªð5.^æ>X|/U-mazy +·mµL5wÛ¬RAñLK1¿4OØêEe£¿ÔÝóMÆX8ªé¡Ê×Üõ:ºæB²Î¹Fê¸ÓÈ/Zx³^ïÀ÷[à®øn +ÀÅ|í{O&ÿgï +wÛ8þ*Ó>oU +q~éSìÖH*mª*Óöö;¸8#æÿ:Ñ/i)8ÃÝ/¡-£ãýí°ßIP8Z_Þ?îÐyóåó_oD´J©ô¶ú¯+=ݼ«ÏkïE:Átóªí y¥ß}ÞUsåµ'¹b}jÞGùôyåó<¯8Ǽõ1¯ÈrjK^³Yãòn[}»m3'¹fm[mZºyô^ÆËÕ>[=¶mòªg¤Ëk5ocz ç³j74îS]̺êÊ[+ü&\Þçεòó¼ÏÞÝþðëYÐÃËk²e¼|?üôWjúãm/ª>¼Þ½¼í²¸ð(ºåÌÿïØ+®©¾ +ì{ï×r<ÚÈ +¯Ø83k´{³^IhE\ÒùJD%ÉDüÊp£c#µiä9ÿÈHy¡Ú ÇíRþÝy÷©ÿú§'ñ¡ÿíÃÚÀ.ÔFwÉ_'gËä>®WZ&Ðé}4S~ç·Eþ§×¸È/çãÒ[ö^]¤Ï7?>0Á:~IÕ6´.Ù *Åj¹+Äç~pK¦nüÌ[$Ô*n_èsƨºáN¼J±Ã´ÑX N4Òé¡påcU>VåcU>VåcU>VåcU>Våc +âcSËßtêWÙY5?^r,;öºY¹Z«U¹Z«5/®XØüE7HNü+s«2·*s«2·*skþÌ-°{ß +îý!IsÉGã4*pX¨p?Âo?EwèeÓb@^q£Â¸¿õëºÚûAtv·u]äP´¿g÷ +`@ïÒÓ°3»,ôǯ&Éúl.ÓÙóÅc@w<+VÙðIf4b¤^<&Å +KL(n^Eóâ¼sÓÿKàÎ@ón!$4k¼½^(4 AÆðîË ýVû⦠+(ÞlD(ê%Èv +ÅrÑÄ|24Nsv 6 ;^ÜL ;6¤ +ÔBàd7GR~ +ÑVq³Â0Ù ÞPÛR¿hJ¬nD(8xÞ(¤g} Do Òq +è,ü}ÔGÕNÚ)rËWÐ6Ì +,ÂIô&of ]Ò Å°+Àëúd>\Ý +í@ +ÅÓ`îbÜ +ÒS&(ïλ, h +¾,0iÀ1éz%Ðäe ÇÑAfÄ^RÙ)ÄhX=P'90HÆEýsÐbP<þ'Áýhð³²ÁG÷ +NJ:é·Â=MëAA&Ó,GE%ÈÔȤ?¹CÎV+ÀµrÂÄËp±¬bnB® PnIæ2ëbÛë +øÁX}Å1ôtG9qù:Bв'éÌüBPÃxÇi` äÔ<Iz>òW~q +Á{Ñî&HÈq³äkR¶Ð Ãþ%Èì+qYyzp +4¯rjPLPÝK +}-@$ä¹ÐÊøÄÛ¦Ù}¸@fñ]Õ< EøeÊ&ñÞñíºbþåĬG :±V|:Ê(±¨´=K$$PÔ[á + +ÝÖ¬"¿Á²K^ƨʢ-Û®bØÞSg2ÿBÛ²HløíÈC_lÒÀÃv(±9Ïãïî¼cS-bÅ%×@\ýñM:°¾êÝcÅ}×NÒC³5cäv%±h¾ÔÂÃ,l{07AIuÂJÿ¿À¶ó9·rUõ¯³3ÊmÁð]z +-iaÚ{Ý목SÕ¤íüûÿØI!!h§ª±ìÄ¡!ö×|NÓ(ò +®'|sJ +\aB6 òö?gÜ<ï¯B ÊaF¬,Éê¹eî<3;3'³q +C![qóPö h@%6mKk@ +GPç +Ë>ÒJÃbnÒYUã[D·n)Ìútð²Ûõº[AZ¹nM+Ýã´'¹n¦°kìr¯dÌ5_Vå¦Öä4ÝO¶Tb¤H¶|»ü`±Àþ»\翽2Ò&*P7ô_ÇSwí¹L:Å{|¼ ++{¦ßàIrü>+1q'5vg2Q^¢8Hø +ìóɬ5Þýö¼·|®ÕËáx¢Æeñëbá/$ø1Þ83®f!Znï +lõÎpÔ5ñë?¢½Ewd½QuøôIÈãµAâÁ·x_VWp gï0=uA«¸³ØIã¶ò}Öb+8{^¯Ù1® +BODY; + + private Project $project; + + protected function setUp(): void + { + parent::setUp(); + + $this->project = $this->createProject('default'); + } + + public function testSend(): never + { + $this->makeRequest(project: $this->project->getKey())->assertOk(); + + $this->markTestIncomplete('This test has not been implemented yet.'); + } + + private function makeRequest(string $secret = 'secret', string|Key $project = 'default'): ResponseAssertions + { + return $this->http + ->postJson( + uri: '/api/' . $project . '/envelope/?sentry_key=' . $secret . '&sentry_version=7&sentry_client=sentry.javascript.vue%2F8.9.2', + data: Stream::create(self::JSON), + headers: [ + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', + ], + ); + } +} diff --git a/tests/Feature/Interfaces/Http/Sentry/SentryVueTransactionActionTest.php b/tests/Feature/Interfaces/Http/Sentry/SentryVueTransactionActionTest.php index 75a54dc..a9f9f3f 100644 --- a/tests/Feature/Interfaces/Http/Sentry/SentryVueTransactionActionTest.php +++ b/tests/Feature/Interfaces/Http/Sentry/SentryVueTransactionActionTest.php @@ -27,7 +27,7 @@ protected function setUp(): void $this->project = $this->createProject('default'); } - public function testSend(): void + public function testSend(): never { $this->makeRequest(project: $this->project->getKey())->assertOk(); diff --git a/tests/Feature/Interfaces/Http/Smtp/Attachments/DeleteEventAction.php b/tests/Feature/Interfaces/Http/Smtp/Attachments/DeleteEventAction.php index 24418a6..f000b96 100644 --- a/tests/Feature/Interfaces/Http/Smtp/Attachments/DeleteEventAction.php +++ b/tests/Feature/Interfaces/Http/Smtp/Attachments/DeleteEventAction.php @@ -13,6 +13,7 @@ final class DeleteEventAction extends ControllerTestCase { private MockInterface|AttachmentRepositoryInterface $attachements; + private MockInterface|AttachmentStorageInterface $storage; protected function setUp(): void @@ -29,11 +30,11 @@ public function testDeleteEvent(): void $this->attachements->shouldReceive('deleteByEvent') ->once() - ->with(\Mockery::on(fn(Uuid $uuid) => $uuid->equals($event->getUuid()))); + ->with(\Mockery::on(static fn(Uuid $uuid) => $uuid->equals($event->getUuid()))); $this->storage->shouldReceive('deleteByEvent') ->once() - ->with(\Mockery::on(fn(Uuid $uuid) => $uuid->equals($event->getUuid()))); + ->with(\Mockery::on(static fn(Uuid $uuid) => $uuid->equals($event->getUuid()))); $this->http ->deleteEvent($event->getUuid()) diff --git a/tests/Feature/Interfaces/Http/Smtp/Attachments/ListActionTest.php b/tests/Feature/Interfaces/Http/Smtp/Attachments/ListActionTest.php index 8e1b06d..2643057 100644 --- a/tests/Feature/Interfaces/Http/Smtp/Attachments/ListActionTest.php +++ b/tests/Feature/Interfaces/Http/Smtp/Attachments/ListActionTest.php @@ -22,7 +22,7 @@ public function testFindAttachments(): void ->assertOk() ->assertCollectionContainResources( \array_map( - fn(Attachment $attachment) => new AttachmentResource($attachment), + static fn(Attachment $attachment) => new AttachmentResource($attachment), $attachments, ), ) diff --git a/tests/Feature/Interfaces/Jobs/Webhooks/WebhookHandlerTest.php b/tests/Feature/Interfaces/Jobs/Webhooks/WebhookHandlerTest.php index 7416dc0..62ef110 100644 --- a/tests/Feature/Interfaces/Jobs/Webhooks/WebhookHandlerTest.php +++ b/tests/Feature/Interfaces/Jobs/Webhooks/WebhookHandlerTest.php @@ -20,7 +20,9 @@ final class WebhookHandlerTest extends DatabaseTestCase { private MockInterface|ClientInterface $httpClient; + private EntityAssertion $assertion; + private WebhookServiceInterface $service; protected function setUp(): void diff --git a/tests/Feature/Interfaces/TCP/Monolog/JsonPayloadTest.php b/tests/Feature/Interfaces/TCP/Monolog/JsonPayloadTest.php index 5f74ea4..2a9116a 100644 --- a/tests/Feature/Interfaces/TCP/Monolog/JsonPayloadTest.php +++ b/tests/Feature/Interfaces/TCP/Monolog/JsonPayloadTest.php @@ -64,7 +64,7 @@ private function buildMessage(Key|string|null $project = null): array ]; if ($project !== null) { - $payload['context']['project'] = (string)$project; + $payload['context']['project'] = (string) $project; } return $payload; diff --git a/tests/Feature/Interfaces/TCP/Smtp/EmailTest.php b/tests/Feature/Interfaces/TCP/Smtp/EmailTest.php index b3ff87d..e2457ea 100644 --- a/tests/Feature/Interfaces/TCP/Smtp/EmailTest.php +++ b/tests/Feature/Interfaces/TCP/Smtp/EmailTest.php @@ -23,6 +23,7 @@ final class EmailTest extends TCPTestCase { private BucketInterface $bucket; + private MockInterface|AttachmentRepositoryInterface $attachments; protected function setUp(): void @@ -176,7 +177,7 @@ private function validateMessage(string $messageId, string $uuid): void <john@example.com>\r Cc: Customer <customer@example.com>, theboss@example.com\r From: Bob Example <no-reply@site.com>\r -Message-ID: <$messageId>\r", +Message-ID: <{$messageId}>\r", $parsedMessage->raw, ); } @@ -221,7 +222,7 @@ private function assertEventPushed(?string $project = null): void public function buildEmail(): Email { - return (new Email) + return (new Email()) ->subject('Test message') ->date(new \DateTimeImmutable('2024-05-02 16:01:33')) ->addTo( @@ -233,8 +234,8 @@ public function buildEmail(): Email new Address('customer@example.com', 'Customer'), 'theboss@example.com', ) - ->addFrom(new Address('no-reply@site.com', 'Bob Example'),) - ->attachFromPath(path: __DIR__ . '/hello.txt',) + ->addFrom(new Address('no-reply@site.com', 'Bob Example'), ) + ->attachFromPath(path: __DIR__ . '/hello.txt', ) ->attachFromPath(path: __DIR__ . '/logo.svg') ->addPart( (new DataPart(new File(__DIR__ . '/logo.svg'), 'logo-embeddable'))->asInline()->setContentId( diff --git a/tests/TestCase.php b/tests/TestCase.php index 01dfd7c..30e27ba 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -26,6 +26,7 @@ class TestCase extends BaseTestCase { protected BroadcastFaker $broadcastig; + private ?EventsMocker $events = null; protected function setUp(): void diff --git a/tests/Unit/Modules/Events/Domain/CacheEventRepositoryTest.php b/tests/Unit/Modules/Events/Domain/CacheEventRepositoryTest.php index f5f260e..7b85a9e 100644 --- a/tests/Unit/Modules/Events/Domain/CacheEventRepositoryTest.php +++ b/tests/Unit/Modules/Events/Domain/CacheEventRepositoryTest.php @@ -49,15 +49,15 @@ public function testDeleteByUuids(): void $this->repository->deleteAll([ 'uuid' => [ - (string)$event1->getUuid(), - (string)$event3->getUuid(), + (string) $event1->getUuid(), + (string) $event3->getUuid(), ], ]); $this->assertCount(1, \iterator_to_array($this->repository->findAll())); $result = \iterator_to_array($this->repository->findAll()); - $this->assertSame((string)$event2->getUuid(), (string)$result[0]->getUuid()); + $this->assertSame((string) $event2->getUuid(), (string) $result[0]->getUuid()); } public function testDeleteByTypeAndUuids(): void @@ -73,9 +73,9 @@ public function testDeleteByTypeAndUuids(): void $this->repository->deleteAll([ 'type' => 'foo', 'uuid' => [ - (string)$event3->getUuid(), - (string)$event5->getUuid(), - (string)$event4->getUuid(), + (string) $event3->getUuid(), + (string) $event5->getUuid(), + (string) $event4->getUuid(), ], ]); @@ -83,8 +83,8 @@ public function testDeleteByTypeAndUuids(): void $result = \iterator_to_array($this->repository->findAll()); - $this->assertSame((string)$event1->getUuid(), (string)$result[0]->getUuid()); - $this->assertSame((string)$event2->getUuid(), (string)$result[1]->getUuid()); - $this->assertSame((string)$event3->getUuid(), (string)$result[2]->getUuid()); + $this->assertSame((string) $event1->getUuid(), (string) $result[0]->getUuid()); + $this->assertSame((string) $event2->getUuid(), (string) $result[1]->getUuid()); + $this->assertSame((string) $event3->getUuid(), (string) $result[2]->getUuid()); } } diff --git a/tests/Unit/Modules/Smtp/AttachmentStorageTest.php b/tests/Unit/Modules/Smtp/AttachmentStorageTest.php index 906ca51..ea82996 100644 --- a/tests/Unit/Modules/Smtp/AttachmentStorageTest.php +++ b/tests/Unit/Modules/Smtp/AttachmentStorageTest.php @@ -18,8 +18,11 @@ final class AttachmentStorageTest extends TestCase { private AttachmentStorage $storage; + private MockInterface|BucketInterface $bucket; + private MockInterface|AttachmentRepositoryInterface $attachments; + private MockInterface|AttachmentFactoryInterface $factory; protected function setUp(): void diff --git a/tests/Unit/Modules/Smtp/CycleOrmAttachmentRepositoryTest.php b/tests/Unit/Modules/Smtp/CycleOrmAttachmentRepositoryTest.php index 46edf15..4d8e678 100644 --- a/tests/Unit/Modules/Smtp/CycleOrmAttachmentRepositoryTest.php +++ b/tests/Unit/Modules/Smtp/CycleOrmAttachmentRepositoryTest.php @@ -14,6 +14,7 @@ final class CycleOrmAttachmentRepositoryTest extends DatabaseTestCase { private EntityAssertion $assertion; + private AttachmentRepository $repository; protected function setUp(): void @@ -31,6 +32,7 @@ public function testStore(): void $record = $this->assertion->where(['uuid' => $attachment->getUuid()]); $record->assertMissing(); + $this->assertion->assertCount(0); $this->repository->store($attachment); diff --git a/tests/Unit/Modules/Webhooks/RetryPolicyTest.php b/tests/Unit/Modules/Webhooks/RetryPolicyTest.php index b298268..845317c 100644 --- a/tests/Unit/Modules/Webhooks/RetryPolicyTest.php +++ b/tests/Unit/Modules/Webhooks/RetryPolicyTest.php @@ -23,9 +23,8 @@ public function testCanTry(): void }; $this->assertSame($expected, $seconds); - $i++; + ++$i; }), - maxRetries: 3, delay: 5, retryMultiplier: 2, @@ -43,10 +42,9 @@ public function testCanTry(): void public function testCanTryWithZeroRetries(): void { $policy = new RetryPolicy( - timer: new Timer(function (int $seconds): void { + timer: new Timer(function (int $seconds): never { $this->fail('No retries should be made'); }), - maxRetries: 0, delay: 5, retryMultiplier: 2, @@ -58,10 +56,8 @@ public function testCanTryWithZeroRetries(): void public function testCanTryWithOneRetry(): void { $policy = new RetryPolicy( - timer: new Timer(function (int $seconds): void { - + timer: new Timer(static function (int $seconds) : void { }), - maxRetries: 1, delay: 5, retryMultiplier: 2, diff --git a/tests/Unit/Modules/Webhooks/WebhookFilesFinderTest.php b/tests/Unit/Modules/Webhooks/WebhookFilesFinderTest.php index f61d219..20c38ed 100644 --- a/tests/Unit/Modules/Webhooks/WebhookFilesFinderTest.php +++ b/tests/Unit/Modules/Webhooks/WebhookFilesFinderTest.php @@ -16,9 +16,13 @@ final class WebhookFilesFinderTest extends TestCase { private FinderInterface|m\MockInterface $initialFinder; + private LoggerInterface|m\MockInterface $logger; + private WebhookYamlParser|m\MockInterface $parser; + private FilesInterface|m\MockInterface $files; + private WebhookFilesFinder $finder; diff --git a/tests/Unit/Modules/Webhooks/WebhookYamlParserTest.php b/tests/Unit/Modules/Webhooks/WebhookYamlParserTest.php index 43d1b77..2a3caa6 100644 --- a/tests/Unit/Modules/Webhooks/WebhookYamlParserTest.php +++ b/tests/Unit/Modules/Webhooks/WebhookYamlParserTest.php @@ -21,6 +21,7 @@ final class WebhookYamlParserTest extends TestCase YAML; private MockInterface|Parser $yamlParser; + private WebhookYamlParser $parser; protected function setUp(): void diff --git a/utils/rector/src/BootloaderConstantsFixesRule.php b/utils/rector/src/BootloaderConstantsFixesRule.php index ac144de..00c4989 100644 --- a/utils/rector/src/BootloaderConstantsFixesRule.php +++ b/utils/rector/src/BootloaderConstantsFixesRule.php @@ -16,7 +16,6 @@ final class BootloaderConstantsFixesRule extends AbstractRector { - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -32,7 +31,6 @@ final class AttributesBootloader extends Bootloader } PHP , - <<<PHP final class AttributesBootloader extends Bootloader { @@ -55,7 +53,6 @@ final class AttributesBootloader extends Bootloader } PHP , - <<<PHP final class AttributesBootloader extends Bootloader { @@ -78,7 +75,6 @@ final class AttributesBootloader extends Bootloader } PHP , - <<<PHP final class AttributesBootloader extends Bootloader { @@ -92,7 +88,6 @@ public function defineBindings(): array PHP, ), ], - ); } @@ -122,7 +117,7 @@ public function refactor(Node $node): ?Node 'DEPENDENCIES' => 'defineDependencies', 'SINGLETONS' => 'defineSingletons', 'BINDINGS' => 'defineBindings', - default => null + default => null, }; if ($methodName === null) {