Skip to content

Commit

Permalink
Аdded response method support on resource instances (#440)
Browse files Browse the repository at this point in the history
* added response method support on resource instances

* Fix styling

---------

Co-authored-by: romalytvynenko <[email protected]>
  • Loading branch information
romalytvynenko and romalytvynenko authored Jul 2, 2024
1 parent 4d04e49 commit 85502c4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
2 changes: 2 additions & 0 deletions src/ScrambleServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Dedoc\Scramble\Support\InferExtensions\AbortHelpersExceptionInfer;
use Dedoc\Scramble\Support\InferExtensions\JsonResourceCallsTypeInfer;
use Dedoc\Scramble\Support\InferExtensions\JsonResourceCreationInfer;
use Dedoc\Scramble\Support\InferExtensions\JsonResourceExtension;
use Dedoc\Scramble\Support\InferExtensions\JsonResourceTypeInfer;
use Dedoc\Scramble\Support\InferExtensions\JsonResponseMethodReturnTypeExtension;
use Dedoc\Scramble\Support\InferExtensions\ModelExtension;
Expand Down Expand Up @@ -89,6 +90,7 @@ public function configurePackage(Package $package): void

$inferExtensionsClasses = array_merge([
ResponseMethodReturnTypeExtension::class,
JsonResourceExtension::class,
JsonResponseMethodReturnTypeExtension::class,
ModelExtension::class,
], $inferExtensionsClasses);
Expand Down
34 changes: 16 additions & 18 deletions src/Support/InferExtensions/JsonResourceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,28 @@

namespace Dedoc\Scramble\Support\InferExtensions;

use Dedoc\Scramble\Infer\Definition\ClassDefinition;
use Dedoc\Scramble\Infer\Extensions\Event\MethodCallEvent;
use Dedoc\Scramble\Infer\Extensions\MethodReturnTypeExtension;
use Dedoc\Scramble\Support\Type\ArrayType;
use Dedoc\Scramble\Support\Type\Generic;
use Dedoc\Scramble\Support\Type\Literal\LiteralIntegerType;
use Dedoc\Scramble\Support\Type\ObjectType;
use Dedoc\Scramble\Support\Type\Type;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;

class JsonResourceExtension
class JsonResourceExtension implements MethodReturnTypeExtension
{
public function shouldHandle(ClassDefinition $type)
public function shouldHandle(ObjectType $type): bool
{
return $type->isInstanceOf(JsonResource::class)
&& ! $type->isInstanceOf(ResourceCollection::class);
return $type->isInstanceOf(JsonResource::class);
}

public function getPropertyType(PropertyFetchEvent $event)
public function getMethodReturnType(MethodCallEvent $event): ?Type
{
if ($event->getDefinition()->hasProperty($event->getName())) {
return null;
}

$modelType = $event->getInstance()->templateTypes[0];

if ($event->getName() === 'resource') {
return $modelType;
}

return $modelType->getPropertyType($event->getName());
return match ($event->name) {
'response', 'toResponse' => new Generic(JsonResponse::class, [$event->getInstance(), new LiteralIntegerType(200), new ArrayType]),
default => null,
};
}
}
29 changes: 29 additions & 0 deletions tests/ResponseDocumentingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,32 @@ public function toArray(\Illuminate\Http\Request $request)
];
}
}

test('automated response status code inference when using ->response->setStatusCode method', function () {
$openApiDocument = generateForRoute(fn () => \Illuminate\Support\Facades\Route::get('api/test', [Foo_TestSix::class, 'single']));

expect($openApiDocument['paths']['/test']['get']['responses'][201]['content']['application/json']['schema'])
->toBe(['$ref' => '#/components/schemas/Foo_TestFiveResource']);
});

test('automated response status code inference when using collection ->response->setStatusCode method', function () {
$openApiDocument = generateForRoute(fn () => \Illuminate\Support\Facades\Route::get('api/test', [Foo_TestSix::class, 'collection']));

expect($openApiDocument['paths']['/test']['get']['responses'][201]['content']['application/json']['schema'])
->toBe([
'type' => 'array',
'items' => ['$ref' => '#/components/schemas/Foo_TestFiveResource'],
]);
});
class Foo_TestSix
{
public function single()
{
return (new Foo_TestFiveResource())->response()->setStatusCode(201);
}

public function collection()
{
return Foo_TestFiveResource::collection()->response()->setStatusCode(201);
}
}

0 comments on commit 85502c4

Please sign in to comment.