fix: DockerSecretsResolver - don't normalize absolute paths like /var/www/html/...
Some checks failed
Deploy Application / deploy (push) Has been cancelled
Some checks failed
Deploy Application / deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Framework\Attributes\Execution;
|
||||
|
||||
use App\Framework\Attributes\Execution\AttributeExecutionContext;
|
||||
use App\Framework\Attributes\Execution\AttributeRunner;
|
||||
use App\Framework\Attributes\Execution\CallbackExecutor;
|
||||
use App\Framework\Attributes\Execution\CallbackMetadataExtractor;
|
||||
use App\Framework\Attributes\Execution\Handlers\PermissionGuard;
|
||||
use App\Framework\Attributes\Execution\Policies\Policies;
|
||||
use App\Framework\Attributes\Execution\Policies\UserPolicies;
|
||||
use App\Framework\Attributes\Guard;
|
||||
use App\Framework\Core\ValueObjects\ClassName;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\DI\MethodInvoker;
|
||||
use App\Framework\Discovery\Results\AttributeRegistry;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Discovery\ValueObjects\AttributeTarget;
|
||||
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;
|
||||
use App\Framework\Reflection\SimpleReflectionService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class AttributeExecutionIntegrationTest extends TestCase
|
||||
{
|
||||
private Container $container;
|
||||
private DiscoveryRegistry $discoveryRegistry;
|
||||
private AttributeRunner $runner;
|
||||
private CallbackMetadataExtractor $extractor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->container = new DefaultContainer();
|
||||
$this->container->instance(MethodInvoker::class, new MethodInvoker(
|
||||
$this->container,
|
||||
new SimpleReflectionService()
|
||||
));
|
||||
|
||||
$this->discoveryRegistry = new DiscoveryRegistry(
|
||||
attributes: new AttributeRegistry()
|
||||
);
|
||||
|
||||
$callbackExecutor = new CallbackExecutor($this->container);
|
||||
$this->runner = new AttributeRunner(
|
||||
discoveryRegistry: $this->discoveryRegistry,
|
||||
container: $this->container,
|
||||
callbackExecutor: $callbackExecutor
|
||||
);
|
||||
|
||||
$this->extractor = new CallbackMetadataExtractor();
|
||||
}
|
||||
|
||||
public function testPatternAHandlerWorkflow(): void
|
||||
{
|
||||
// Pattern A: Handler-Klasse
|
||||
$metadata = $this->extractor->extract([PermissionGuard::class, [['edit_post']]]);
|
||||
|
||||
$this->assertEquals(\App\Framework\Attributes\Execution\CallbackType::HANDLER, $metadata->callbackType);
|
||||
$this->assertEquals(PermissionGuard::class, $metadata->class);
|
||||
$this->assertTrue($metadata->isCacheable());
|
||||
|
||||
// Test Serialisierung
|
||||
$array = $metadata->toArray();
|
||||
$restored = \App\Framework\Attributes\Execution\CallbackMetadata::fromArray($array);
|
||||
$this->assertEquals($metadata->callbackType, $restored->callbackType);
|
||||
}
|
||||
|
||||
public function testPatternBStaticMethodWorkflow(): void
|
||||
{
|
||||
// Pattern B: First-Class Callable
|
||||
$metadata = $this->extractor->extract([UserPolicies::class, 'isAdmin']);
|
||||
|
||||
$this->assertEquals(\App\Framework\Attributes\Execution\CallbackType::STATIC_METHOD, $metadata->callbackType);
|
||||
$this->assertEquals(UserPolicies::class, $metadata->class);
|
||||
$this->assertEquals('isAdmin', $metadata->method);
|
||||
$this->assertTrue($metadata->isCacheable());
|
||||
|
||||
// Test Ausführung
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$executor = new CallbackExecutor($this->container);
|
||||
$result = $executor->execute($metadata, $context);
|
||||
|
||||
$this->assertIsBool($result);
|
||||
}
|
||||
|
||||
public function testPatternCFactoryWorkflow(): void
|
||||
{
|
||||
// Pattern C: Closure-Factory
|
||||
// Für Factory-Pattern müssen wir die Factory-Methode explizit identifizieren
|
||||
$metadata = $this->extractor->extractFromFactoryCall(
|
||||
Policies::class,
|
||||
'requirePermission',
|
||||
['edit_post']
|
||||
);
|
||||
|
||||
$this->assertEquals(\App\Framework\Attributes\Execution\CallbackType::FACTORY, $metadata->callbackType);
|
||||
$this->assertEquals(Policies::class, $metadata->class);
|
||||
$this->assertEquals('requirePermission', $metadata->method);
|
||||
$this->assertEquals(['edit_post'], $metadata->args);
|
||||
$this->assertTrue($metadata->isCacheable());
|
||||
|
||||
// Test Ausführung
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$executor = new CallbackExecutor($this->container);
|
||||
$closure = $executor->execute($metadata, $context);
|
||||
|
||||
$this->assertInstanceOf(\Closure::class, $closure);
|
||||
|
||||
$result = $closure($context);
|
||||
$this->assertIsBool($result);
|
||||
}
|
||||
|
||||
public function testDiscoveredAttributeCallbackMetadataExtraction(): void
|
||||
{
|
||||
$discovered = new DiscoveredAttribute(
|
||||
className: ClassName::create('TestClass'),
|
||||
attributeClass: Guard::class,
|
||||
target: AttributeTarget::TARGET_CLASS,
|
||||
arguments: [PermissionGuard::class, [['edit_post']]]
|
||||
);
|
||||
|
||||
$metadata = $discovered->getCallbackMetadata();
|
||||
|
||||
$this->assertNotNull($metadata);
|
||||
$this->assertEquals(\App\Framework\Attributes\Execution\CallbackType::HANDLER, $metadata->callbackType);
|
||||
}
|
||||
|
||||
public function testCacheSerializationRoundTrip(): void
|
||||
{
|
||||
$discovered = new DiscoveredAttribute(
|
||||
className: ClassName::create('TestClass'),
|
||||
attributeClass: Guard::class,
|
||||
target: AttributeTarget::TARGET_CLASS,
|
||||
arguments: [PermissionGuard::class, [['edit_post']]]
|
||||
);
|
||||
|
||||
// Serialisiere
|
||||
$array = $discovered->toArray();
|
||||
|
||||
// Deserialisiere
|
||||
$restored = DiscoveredAttribute::fromArray($array);
|
||||
|
||||
// Prüfe dass Callback-Metadata erhalten bleibt
|
||||
$originalMetadata = $discovered->getCallbackMetadata();
|
||||
$restoredMetadata = $restored->getCallbackMetadata();
|
||||
|
||||
$this->assertNotNull($originalMetadata);
|
||||
$this->assertNotNull($restoredMetadata);
|
||||
$this->assertEquals($originalMetadata->callbackType, $restoredMetadata->callbackType);
|
||||
$this->assertEquals($originalMetadata->class, $restoredMetadata->class);
|
||||
}
|
||||
}
|
||||
|
||||
110
tests/Framework/Attributes/Execution/AttributeRunnerTest.php
Normal file
110
tests/Framework/Attributes/Execution/AttributeRunnerTest.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Framework\Attributes\Execution;
|
||||
|
||||
use App\Framework\Attributes\Execution\AttributeExecutionContext;
|
||||
use App\Framework\Attributes\Execution\AttributeRunner;
|
||||
use App\Framework\Attributes\Execution\CallbackExecutor;
|
||||
use App\Framework\Attributes\Guard;
|
||||
use App\Framework\Core\ValueObjects\ClassName;
|
||||
use App\Framework\Core\ValueObjects\MethodName;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\DI\MethodInvoker;
|
||||
use App\Framework\Discovery\Results\AttributeRegistry;
|
||||
use App\Framework\Discovery\Results\DiscoveryRegistry;
|
||||
use App\Framework\Discovery\ValueObjects\AttributeTarget;
|
||||
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;
|
||||
use App\Framework\Reflection\SimpleReflectionService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class AttributeRunnerTest extends TestCase
|
||||
{
|
||||
private Container $container;
|
||||
private DiscoveryRegistry $discoveryRegistry;
|
||||
private AttributeRunner $runner;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->container = new DefaultContainer();
|
||||
$this->container->instance(MethodInvoker::class, new MethodInvoker(
|
||||
$this->container,
|
||||
new SimpleReflectionService()
|
||||
));
|
||||
|
||||
$this->discoveryRegistry = new DiscoveryRegistry(
|
||||
attributes: new AttributeRegistry()
|
||||
);
|
||||
|
||||
$callbackExecutor = new CallbackExecutor($this->container);
|
||||
$this->runner = new AttributeRunner(
|
||||
discoveryRegistry: $this->discoveryRegistry,
|
||||
container: $this->container,
|
||||
callbackExecutor: $callbackExecutor
|
||||
);
|
||||
}
|
||||
|
||||
public function testExecuteAttributesReturnsEmptyArrayWhenNoAttributes(): void
|
||||
{
|
||||
$results = $this->runner->executeAttributes(Guard::class);
|
||||
|
||||
$this->assertIsArray($results);
|
||||
$this->assertEmpty($results);
|
||||
}
|
||||
|
||||
public function testExecuteAttributeReturnsNullForNonExecutable(): void
|
||||
{
|
||||
$discovered = new DiscoveredAttribute(
|
||||
className: ClassName::create('TestClass'),
|
||||
attributeClass: 'NonExecutableAttribute',
|
||||
target: AttributeTarget::TARGET_CLASS
|
||||
);
|
||||
|
||||
$result = $this->runner->executeAttribute($discovered);
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
public function testExecuteForClass(): void
|
||||
{
|
||||
$className = ClassName::create('TestClass');
|
||||
|
||||
// Füge ein Guard-Attribut hinzu
|
||||
$discovered = new DiscoveredAttribute(
|
||||
className: $className,
|
||||
attributeClass: Guard::class,
|
||||
target: AttributeTarget::TARGET_CLASS,
|
||||
arguments: [\App\Framework\Attributes\Execution\Handlers\PermissionGuard::class, [['edit_post']]]
|
||||
);
|
||||
|
||||
$this->discoveryRegistry->attributes->add(Guard::class, $discovered);
|
||||
|
||||
$results = $this->runner->executeForClass($className, Guard::class);
|
||||
|
||||
$this->assertIsArray($results);
|
||||
}
|
||||
|
||||
public function testExecuteForMethod(): void
|
||||
{
|
||||
$className = ClassName::create('TestClass');
|
||||
$methodName = MethodName::create('testMethod');
|
||||
|
||||
// Füge ein Guard-Attribut hinzu
|
||||
$discovered = new DiscoveredAttribute(
|
||||
className: $className,
|
||||
attributeClass: Guard::class,
|
||||
target: AttributeTarget::METHOD,
|
||||
methodName: $methodName,
|
||||
arguments: [\App\Framework\Attributes\Execution\Handlers\PermissionGuard::class, [['edit_post']]]
|
||||
);
|
||||
|
||||
$this->discoveryRegistry->attributes->add(Guard::class, $discovered);
|
||||
|
||||
$results = $this->runner->executeForMethod($className, $methodName, Guard::class);
|
||||
|
||||
$this->assertIsArray($results);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Framework\Attributes\Execution;
|
||||
|
||||
use App\Framework\Attributes\Execution\AttributeExecutionContext;
|
||||
use App\Framework\Attributes\Execution\CallbackExecutor;
|
||||
use App\Framework\Attributes\Execution\CallbackMetadata;
|
||||
use App\Framework\Attributes\Execution\CallbackType;
|
||||
use App\Framework\Attributes\Execution\Handlers\PermissionGuard;
|
||||
use App\Framework\Attributes\Execution\Policies\Policies;
|
||||
use App\Framework\Attributes\Execution\Policies\UserPolicies;
|
||||
use App\Framework\DI\Container;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\DI\MethodInvoker;
|
||||
use App\Framework\Reflection\SimpleReflectionService;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class CallbackExecutorTest extends TestCase
|
||||
{
|
||||
private Container $container;
|
||||
private CallbackExecutor $executor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->container = new DefaultContainer();
|
||||
$this->container->instance(MethodInvoker::class, new MethodInvoker(
|
||||
$this->container,
|
||||
new SimpleReflectionService()
|
||||
));
|
||||
$this->executor = new CallbackExecutor($this->container);
|
||||
}
|
||||
|
||||
public function testExecuteHandler(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromHandler(PermissionGuard::class, [['edit_post']]);
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
\App\Framework\Core\ValueObjects\ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$result = $this->executor->execute($metadata, $context);
|
||||
|
||||
// PermissionGuard gibt true zurück (Placeholder-Implementierung)
|
||||
$this->assertIsBool($result);
|
||||
}
|
||||
|
||||
public function testExecuteStaticMethod(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromCallable([UserPolicies::class, 'isAdmin']);
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
\App\Framework\Core\ValueObjects\ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$result = $this->executor->execute($metadata, $context);
|
||||
|
||||
// UserPolicies::isAdmin gibt bool zurück
|
||||
$this->assertIsBool($result);
|
||||
}
|
||||
|
||||
public function testExecuteFactory(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromFactory(
|
||||
Policies::class,
|
||||
'requirePermission',
|
||||
['edit_post']
|
||||
);
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
\App\Framework\Core\ValueObjects\ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$closure = $this->executor->execute($metadata, $context);
|
||||
|
||||
$this->assertInstanceOf(\Closure::class, $closure);
|
||||
|
||||
// Führe Closure aus
|
||||
$result = $closure($context);
|
||||
$this->assertIsBool($result);
|
||||
}
|
||||
|
||||
public function testExecuteThrowsForClosure(): void
|
||||
{
|
||||
$metadata = new CallbackMetadata(CallbackType::CLOSURE, '');
|
||||
$context = AttributeExecutionContext::forClass(
|
||||
$this->container,
|
||||
\App\Framework\Core\ValueObjects\ClassName::create('TestClass')
|
||||
);
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('Closure execution not supported via metadata');
|
||||
|
||||
$this->executor->execute($metadata, $context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Framework\Attributes\Execution;
|
||||
|
||||
use App\Framework\Attributes\Execution\CallbackMetadata;
|
||||
use App\Framework\Attributes\Execution\CallbackType;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class CallbackMetadataTest extends TestCase
|
||||
{
|
||||
public function testFromHandler(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromHandler('MyHandler', ['arg1', 'arg2']);
|
||||
|
||||
$this->assertEquals(CallbackType::HANDLER, $metadata->callbackType);
|
||||
$this->assertEquals('MyHandler', $metadata->class);
|
||||
$this->assertNull($metadata->method);
|
||||
$this->assertEquals(['arg1', 'arg2'], $metadata->args);
|
||||
}
|
||||
|
||||
public function testFromCallableString(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromCallable('MyClass::myMethod');
|
||||
|
||||
$this->assertEquals(CallbackType::STATIC_METHOD, $metadata->callbackType);
|
||||
$this->assertEquals('MyClass', $metadata->class);
|
||||
$this->assertEquals('myMethod', $metadata->method);
|
||||
$this->assertEquals([], $metadata->args);
|
||||
}
|
||||
|
||||
public function testFromCallableArray(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromCallable(['MyClass', 'myMethod']);
|
||||
|
||||
$this->assertEquals(CallbackType::STATIC_METHOD, $metadata->callbackType);
|
||||
$this->assertEquals('MyClass', $metadata->class);
|
||||
$this->assertEquals('myMethod', $metadata->method);
|
||||
}
|
||||
|
||||
public function testFromFactory(): void
|
||||
{
|
||||
$metadata = CallbackMetadata::fromFactory('MyFactory', 'create', ['param1']);
|
||||
|
||||
$this->assertEquals(CallbackType::FACTORY, $metadata->callbackType);
|
||||
$this->assertEquals('MyFactory', $metadata->class);
|
||||
$this->assertEquals('create', $metadata->method);
|
||||
$this->assertEquals(['param1'], $metadata->args);
|
||||
}
|
||||
|
||||
public function testToArrayAndFromArray(): void
|
||||
{
|
||||
$original = CallbackMetadata::fromHandler('MyHandler', ['arg1']);
|
||||
|
||||
$array = $original->toArray();
|
||||
$restored = CallbackMetadata::fromArray($array);
|
||||
|
||||
$this->assertEquals($original->callbackType, $restored->callbackType);
|
||||
$this->assertEquals($original->class, $restored->class);
|
||||
$this->assertEquals($original->method, $restored->method);
|
||||
$this->assertEquals($original->args, $restored->args);
|
||||
}
|
||||
|
||||
public function testIsCacheable(): void
|
||||
{
|
||||
$handler = CallbackMetadata::fromHandler('MyHandler');
|
||||
$this->assertTrue($handler->isCacheable());
|
||||
|
||||
$callable = CallbackMetadata::fromCallable('MyClass::method');
|
||||
$this->assertTrue($callable->isCacheable());
|
||||
|
||||
$factory = CallbackMetadata::fromFactory('MyFactory', 'create');
|
||||
$this->assertTrue($factory->isCacheable());
|
||||
|
||||
$closure = new CallbackMetadata(CallbackType::CLOSURE, '');
|
||||
$this->assertFalse($closure->isCacheable());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user