diff --git a/src/Extracting/Strategies/PhpAttributeStrategy.php b/src/Extracting/Strategies/PhpAttributeStrategy.php index 510cd575..d92a0847 100644 --- a/src/Extracting/Strategies/PhpAttributeStrategy.php +++ b/src/Extracting/Strategies/PhpAttributeStrategy.php @@ -41,19 +41,19 @@ public function __invoke(ExtractedEndpointData $endpointData, array $routeRules protected function getAttributes(ReflectionFunctionAbstract $method, ?ReflectionClass $class = null): array { $attributesOnMethod = collect(static::$attributeNames) - ->flatMap(fn(string $name) => $method->getAttributes($name)) + ->flatMap(fn(string $name) => $method->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF)) ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all(); // If there's a FormRequest, we check there. if ($formRequestClass = $this->getFormRequestReflectionClass($method)) { $attributesOnFormRequest = collect(static::$attributeNames) - ->flatMap(fn(string $name) => $formRequestClass->getAttributes($name)) + ->flatMap(fn(string $name) => $formRequestClass->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF)) ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all(); } if ($class) { $attributesOnController = collect(static::$attributeNames) - ->flatMap(fn(string $name) => $class->getAttributes($name)) + ->flatMap(fn(string $name) => $class->getAttributes($name, ReflectionAttribute::IS_INSTANCEOF)) ->map(fn(ReflectionAttribute $a) => $a->newInstance())->all(); } diff --git a/tests/Strategies/Headers/GetFromHeaderAttributeTest.php b/tests/Strategies/Headers/GetFromHeaderAttributeTest.php index 29146c40..909adbfa 100644 --- a/tests/Strategies/Headers/GetFromHeaderAttributeTest.php +++ b/tests/Strategies/Headers/GetFromHeaderAttributeTest.php @@ -2,6 +2,7 @@ namespace Knuckles\Scribe\Tests\Strategies\Headers; +use Attribute; use Knuckles\Camel\Extraction\ExtractedEndpointData; use Knuckles\Scribe\Attributes\Header; use Knuckles\Scribe\Extracting\Strategies\Headers\GetFromHeaderAttribute; @@ -16,21 +17,39 @@ class GetFromHeaderAttributeTest extends TestCase /** @test */ public function can_fetch_from_header_attribute() + { + $results = $this->getHeaderFromAttribute('methodWithAttributes'); + + $this->assertArraySubset([ + 'Api-Version' => 'v1', + ], $results); + $this->assertArrayHasKey('Some-Custom', $results); + $this->assertNotEmpty($results['Some-Custom']); + } + + /** @test */ + public function can_fetch_child_of_header_attribute() + { + $results = $this->getHeaderFromAttribute('methodWithCustomHeaderAttribute'); + + $this->assertArraySubset([ + 'Api-Version' => 'v1', + ], $results); + $this->assertArrayHasKey('hello', $results); + $this->assertEquals('world', $results['hello']); + } + + private function getHeaderFromAttribute(string $methodName): array { $endpoint = new class extends ExtractedEndpointData { public function __construct(array $parameters = []) {} }; $endpoint->controller = new ReflectionClass(\Knuckles\Scribe\Tests\Strategies\Headers\HeaderAttributeTestController::class); - $endpoint->method = $endpoint->controller->getMethod('methodWithAttributes'); + $endpoint->method = $endpoint->controller->getMethod($methodName); $strategy = new GetFromHeaderAttribute(new DocumentationConfig([])); - $results = $strategy($endpoint); - $this->assertArraySubset([ - 'Api-Version' => 'v1', - ], $results); - $this->assertArrayHasKey('Some-Custom', $results); - $this->assertNotEmpty($results['Some-Custom']); + return $strategy($endpoint); } } @@ -43,4 +62,19 @@ public function methodWithAttributes() { } + + #[CustomHeaderClass()] + public function methodWithCustomHeaderAttribute() + { + + } +} + +#[Attribute(Attribute::IS_REPEATABLE | Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD | Attribute::TARGET_CLASS)] +class CustomHeaderClass extends Header +{ + public function __construct() + { + parent::__construct('hello', 'world'); + } }