123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- <?php
- namespace Knuckles\Scribe\Tests\Strategies\Responses;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Foundation\Application;
- use Illuminate\Routing\Route;
- use Illuminate\Support\Facades\Schema;
- use Knuckles\Camel\Extraction\ExtractedEndpointData;
- use Knuckles\Scribe\Attributes\Response;
- use Knuckles\Scribe\Attributes\ResponseFromApiResource;
- use Knuckles\Scribe\Attributes\ResponseFromFile;
- use Knuckles\Scribe\Attributes\ResponseFromTransformer;
- use Knuckles\Scribe\Extracting\Strategies\Responses\UseResponseAttributes;
- use Knuckles\Scribe\ScribeServiceProvider;
- use Knuckles\Scribe\Tests\BaseLaravelTest;
- use Knuckles\Scribe\Tests\Fixtures\TestModel;
- use Knuckles\Scribe\Tests\Fixtures\TestPet;
- use Knuckles\Scribe\Tests\Fixtures\TestTransformer;
- use Knuckles\Scribe\Tests\Fixtures\TestUser;
- use Knuckles\Scribe\Tests\Fixtures\TestUserApiResource;
- use Knuckles\Scribe\Tools\DocumentationConfig;
- use Knuckles\Scribe\Tools\Utils;
- use League\Fractal\Pagination\IlluminatePaginatorAdapter;
- use ReflectionClass;
- class UseResponseAttributesTest extends BaseLaravelTest
- {
- protected function getPackageProviders($app)
- {
- $providers = parent::getPackageProviders($app);
- if (class_exists(\Illuminate\Database\Eloquent\LegacyFactoryServiceProvider::class)) {
- $providers[] = \Illuminate\Database\Eloquent\LegacyFactoryServiceProvider ::class;
- }
- return $providers;
- }
- public function setUp(): void
- {
- parent::setUp();
- $this->setConfig(['database_connections_to_transact' => []]);
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->define(TestUser::class, function () {
- return [
- 'id' => 4,
- 'first_name' => 'Tested',
- 'last_name' => 'Again',
- 'email' => 'a@b.com',
- ];
- });
- $factory->state(TestUser::class, 'state1', ["state1" => true]);
- $factory->state(TestUser::class, 'random-state', ["random-state" => true]);
- $factory->define(TestPet::class, function () {
- return [
- 'id' => 1,
- 'name' => 'Mephistopheles',
- 'species' => 'dog',
- ];
- });
- }
- /** @test */
- public function can_parse_plain_response_attributes()
- {
- $results = $this->fetch($this->endpoint("plainResponseAttributes"));
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode(["all" => "good"]),
- "description" => "Success"
- ],
- [
- 'status' => 201,
- 'content' => json_encode(["all" => "good"]),
- ],
- [
- 'status' => 404,
- 'content' => null,
- ]
- ], $results);
- }
- /** @test */
- public function can_parse_responsefile_attributes()
- {
- $results = $this->fetch($this->endpoint("responseFileAttributes"));
- $this->assertArraySubset([
- [
- 'status' => 401,
- 'content' => json_encode(["message" => "Unauthorized", "merge" => "this"]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_apiresource_attributes()
- {
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->afterMaking(TestUser::class, function (TestUser $user, $faker) {
- if ($user->id === 4) {
- $child = Utils::getModelFactory(TestUser::class)->make(['id' => 5, 'parent_id' => 4]);
- $user->setRelation('children', collect([$child]));
- }
- });
- $results = $this->fetch($this->endpoint("apiResourceAttributes"));
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- 'data' => [
- [
- 'id' => 4,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- 'children' => [
- [
- 'id' => 5,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- ],
- ],
- 'state1' => true,
- 'random-state' => true,
- ],
- ],
- 'links' => [
- "first" => '/?page=1',
- "last" => null,
- "prev" => null,
- "next" => '/?page=2',
- ],
- "meta" => [
- "current_page" => 1,
- "from" => 1,
- "path" => '/',
- "per_page" => 1,
- "to" => 1,
- ],
- "a" => "b",
- ]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_apiresource_attributes_with_no_model_specified()
- {
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->afterMaking(TestUser::class, function (TestUser $user, $faker) {
- if ($user->id === 4) {
- $child = Utils::getModelFactory(TestUser::class)->make(['id' => 5, 'parent_id' => 4]);
- $user->setRelation('children', collect([$child]));
- }
- });
- $results = $this->fetch($this->endpoint("apiResourceAttributesWithNoModel"));
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- 'data' => [
- [
- 'id' => 4,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- 'children' => [
- [
- 'id' => 5,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- ],
- ],
- 'state1' => true,
- 'random-state' => true,
- ],
- ],
- 'links' => [
- "first" => '/?page=1',
- "last" => null,
- "prev" => null,
- "next" => '/?page=2',
- ],
- "meta" => [
- "current_page" => 1,
- "from" => 1,
- "path" => '/',
- "per_page" => 1,
- "to" => 1,
- ],
- "a" => "b",
- ]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_transformer_attributes()
- {
- $results = $this->fetch($this->endpoint("transformerAttributes"));
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- "data" => [
- [
- "id" => 1,
- "description" => "Welcome on this test versions",
- "name" => "TestName",
- ],
- ],
- 'meta' => [
- "pagination" => [
- "total" => 2,
- "count" => 1,
- "per_page" => 1,
- "current_page" => 1,
- "total_pages" => 2,
- "links" => ["next" => "/?page=2"],
- ],
- ],
- ]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_apiresource_attributes_with_cursor_pagination()
- {
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->afterMaking(TestUser::class, function (TestUser $user, $faker) {
- if ($user->id === 4) {
- $child = Utils::getModelFactory(TestUser::class)->make(['id' => 5, 'parent_id' => 4]);
- $user->setRelation('children', collect([$child]));
- }
- });
- $results = $this->fetch($this->endpoint("apiResourceAttributesWithCursorPaginate"));
- $nextCursor = base64_encode(json_encode(['_pointsToNextItems' => true]));
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- 'data' => [
- [
- 'id' => 4,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- 'children' => [
- [
- 'id' => 5,
- 'name' => 'Tested Again',
- 'email' => 'a@b.com',
- ],
- ],
- ],
- ],
- 'links' => [
- "first" => null,
- "last" => null,
- "prev" => null,
- "next" => "/?cursor={$nextCursor}",
- ],
- "meta" => match (version_compare(Application::VERSION, '9.0', '>=')) {
- false => [
- "path" => '/',
- 'per_page' => 1,
- ],
- true => [
- "path" => '/',
- 'per_page' => 1,
- 'next_cursor' => $nextCursor,
- 'prev_cursor' => null,
- ]
- },
- ]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_apiresource_attributes_and_load_children_using_factory_create()
- {
- Schema::create('test_users', function (Blueprint $table) {
- $table->id();
- $table->string('first_name');
- $table->string('last_name');
- $table->string('email');
- $table->integer('parent_id')->nullable();
- });
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->afterCreating(TestUser::class, function (TestUser $user, $faker) {
- if ($user->id === 4) {
- Utils::getModelFactory(TestUser::class)->create(['id' => 5, 'parent_id' => 4]);
- }
- });
- $documentationConfig = ['examples' => ['models_source' => ['factoryCreate']]];
- $results = $this->fetch($this->endpoint("apiResourceAttributesIncludeChildren"), $documentationConfig);
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- "data" => [
- "id" => 4,
- "name" => "Tested Again",
- "email" => "a@b.com",
- "children" => [
- [
- "id" => 5,
- "name" => "Tested Again",
- "email" => "a@b.com",
- ]
- ],
- ],
- ]),
- ],
- ], $results);
- }
- /** @test */
- public function can_parse_apiresource_attributes_and_load_children_and_children_count_using_factory_create()
- {
- if (version_compare(Application::VERSION, '9', '<')) {
- $this->markTestSkipped('The whenCounted method in JsonResource requires Laravel 9 or higher.');
- }
- Schema::create('test_users', function (Blueprint $table) {
- $table->id();
- $table->string('first_name');
- $table->string('last_name');
- $table->string('email');
- $table->integer('parent_id')->nullable();
- });
- $factory = app(\Illuminate\Database\Eloquent\Factory::class);
- $factory->afterCreating(TestUser::class, function (TestUser $user, $faker) {
- if ($user->id === 4) {
- Utils::getModelFactory(TestUser::class)->create(['id' => 5, 'parent_id' => 4]);
- }
- });
- $documentationConfig = ['examples' => ['models_source' => ['factoryCreate']]];
- $results = $this->fetch($this->endpoint("apiResourceAttributesIncludeChildrenAndChildrenCount"), $documentationConfig);
- $this->assertArraySubset([
- [
- 'status' => 200,
- 'content' => json_encode([
- "data" => [
- "id" => 4,
- "name" => "Tested Again",
- "email" => "a@b.com",
- "children" => [
- [
- "id" => 5,
- "name" => "Tested Again",
- "email" => "a@b.com",
- ]
- ],
- 'children_count' => 1,
- ],
- ]),
- ],
- ], $results);
- }
- protected function fetch($endpoint, array $documentationConfig = []): array
- {
- $strategy = new UseResponseAttributes(new DocumentationConfig([]));
- return $strategy($endpoint, []);
- }
- protected function endpoint(string $method): ExtractedEndpointData
- {
- $endpoint = new class extends ExtractedEndpointData {
- public function __construct(array $parameters = []) {}
- };
- $endpoint->controller = new ReflectionClass(ResponseAttributesTestController::class);
- $endpoint->method = $endpoint->controller->getMethod($method);
- $endpoint->route = new Route(['POST'], "/somethingRandom", ['uses' => [ResponseAttributesTestController::class, $method]]);
- return $endpoint;
- }
- }
- class ResponseAttributesTestController
- {
- #[Response(["all" => "good"], 200, "Success")]
- #[Response('{"all":"good"}', 201)]
- #[Response(status: 404)]
- public function plainResponseAttributes()
- {
- }
- #[ResponseFromFile("tests/Fixtures/response_error_test.json", 401, ["merge" => "this"])]
- public function responseFileAttributes()
- {
- }
- #[ResponseFromApiResource(TestUserApiResource::class, TestUser::class, collection: true,
- factoryStates: ["state1", "random-state"], simplePaginate: 1, additional: ["a" => "b"])]
- public function apiResourceAttributes()
- {
- }
- #[ResponseFromApiResource(TestUserApiResource::class, collection: true,
- factoryStates: ["state1", "random-state"], simplePaginate: 1, additional: ["a" => "b"])]
- public function apiResourceAttributesWithNoModel()
- {
- }
- #[ResponseFromTransformer(TestTransformer::class, TestModel::class, collection: true,
- paginate: [IlluminatePaginatorAdapter::class, 1])]
- public function transformerAttributes()
- {
- }
- #[ResponseFromApiResource(TestUserApiResource::class, collection: true, cursorPaginate: 1)]
- public function apiResourceAttributesWithCursorPaginate()
- {
- }
- #[ResponseFromApiResource(TestUserApiResource::class, with: ['children'], withCount: ['children'])]
- public function apiResourceAttributesIncludeChildrenAndChildrenCount()
- {
- }
- #[ResponseFromApiResource(TestUserApiResource::class, with: ['children'])]
- public function apiResourceAttributesIncludeChildren()
- {
- }
- }
|