Files
michaelschiemer/tests/Unit/Framework/LiveComponents/Middleware/MiddlewareCollectorTest.php
2025-11-24 21:28:25 +01:00

166 lines
6.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Framework\LiveComponents\Middleware;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Core\ValueObjects\MethodName;
use App\Framework\Discovery\Results\AttributeRegistry;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Discovery\Results\InterfaceRegistry;
use App\Framework\Discovery\Results\TemplateRegistry;
use App\Framework\Discovery\ValueObjects\AttributeTarget;
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;
use App\Framework\LiveComponents\Attributes\Middleware as MiddlewareAttribute;
use App\Framework\LiveComponents\Middleware\MiddlewareCollector;
use App\Framework\LiveComponents\Middleware\LoggingMiddleware;
describe('MiddlewareCollector', function () {
beforeEach(function () {
$this->attributeRegistry = new AttributeRegistry();
$this->discoveryRegistry = new DiscoveryRegistry(
attributes: $this->attributeRegistry,
interfaces: new InterfaceRegistry([]),
templates: new TemplateRegistry([])
);
$this->collector = new MiddlewareCollector($this->discoveryRegistry);
});
it('collects component-level middleware', function () {
$componentClass = ClassName::create('Test\\Component');
// Add component-level middleware attribute
$discovered = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_CLASS,
arguments: [LoggingMiddleware::class, 100]
);
$this->attributeRegistry->add(MiddlewareAttribute::class, $discovered);
$middlewares = $this->collector->collectForAction(
$componentClass,
MethodName::create('testAction')
);
expect($middlewares)->toHaveCount(1);
expect($middlewares[0]->middlewareClass)->toBe(LoggingMiddleware::class);
expect($middlewares[0]->priority)->toBe(100);
});
it('collects action-level middleware', function () {
$componentClass = ClassName::create('Test\\Component');
$actionMethod = MethodName::create('testAction');
// Add action-level middleware attribute
$discovered = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_METHOD,
methodName: $actionMethod,
arguments: [LoggingMiddleware::class, 200]
);
$this->attributeRegistry->add(MiddlewareAttribute::class, $discovered);
$middlewares = $this->collector->collectForAction(
$componentClass,
$actionMethod
);
expect($middlewares)->toHaveCount(1);
expect($middlewares[0]->middlewareClass)->toBe(LoggingMiddleware::class);
expect($middlewares[0]->priority)->toBe(200);
});
it('combines component and action-level middleware', function () {
$componentClass = ClassName::create('Test\\Component');
$actionMethod = MethodName::create('testAction');
// Add component-level middleware
$componentMiddleware = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_CLASS,
arguments: [LoggingMiddleware::class, 100]
);
// Add action-level middleware
$actionMiddleware = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_METHOD,
methodName: $actionMethod,
arguments: [\App\Framework\LiveComponents\Middleware\CachingMiddleware::class, 200]
);
$this->attributeRegistry->add(MiddlewareAttribute::class, $componentMiddleware);
$this->attributeRegistry->add(MiddlewareAttribute::class, $actionMiddleware);
$middlewares = $this->collector->collectForAction(
$componentClass,
$actionMethod
);
expect($middlewares)->toHaveCount(2);
// Should be sorted by priority (higher first)
expect($middlewares[0]->priority)->toBe(200);
expect($middlewares[1]->priority)->toBe(100);
});
it('sorts middleware by priority descending', function () {
$componentClass = ClassName::create('Test\\Component');
// Add multiple middleware with different priorities
$middleware1 = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_CLASS,
arguments: [LoggingMiddleware::class, 50]
);
$middleware2 = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_CLASS,
arguments: [\App\Framework\LiveComponents\Middleware\CachingMiddleware::class, 150]
);
$middleware3 = new DiscoveredAttribute(
className: $componentClass,
attributeClass: MiddlewareAttribute::class,
target: AttributeTarget::TARGET_CLASS,
arguments: [\App\Framework\LiveComponents\Middleware\RateLimitMiddleware::class, 100]
);
$this->attributeRegistry->add(MiddlewareAttribute::class, $middleware1);
$this->attributeRegistry->add(MiddlewareAttribute::class, $middleware2);
$this->attributeRegistry->add(MiddlewareAttribute::class, $middleware3);
$middlewares = $this->collector->collectForAction(
$componentClass,
MethodName::create('testAction')
);
expect($middlewares)->toHaveCount(3);
// Should be sorted by priority descending
expect($middlewares[0]->priority)->toBe(150);
expect($middlewares[1]->priority)->toBe(100);
expect($middlewares[2]->priority)->toBe(50);
});
it('returns empty array when no middleware found', function () {
$componentClass = ClassName::create('Test\\Component');
$middlewares = $this->collector->collectForAction(
$componentClass,
MethodName::create('testAction')
);
expect($middlewares)->toBeEmpty();
});
});