Jelajahi Sumber

Merge pull request #104 from ilgala/master

Issues 56 and 46 fix proposal
Shalvah 4 tahun lalu
induk
melakukan
edde02782e

+ 16 - 7
src/Extracting/Strategies/Responses/UseApiResourceTags.php

@@ -49,11 +49,15 @@ class UseApiResourceTags extends Strategy
         $methodDocBlock = $docBlocks['method'];
 
         try {
-            return $this->getApiResourceResponse($methodDocBlock->getTags());
+            $this->startDbTransaction();
+            return $this->getApiResourceResponse($methodDocBlock->getTags(), $route);
         } catch (Exception $e) {
             c::warn('Exception thrown when fetching Eloquent API resource response for [' . implode(',', $route->methods) . "] {$route->uri}.");
             e::dumpExceptionIfVerbose($e);
+
             return null;
+        } finally {
+            $this->endDbTransaction();
         }
     }
 
@@ -62,9 +66,11 @@ class UseApiResourceTags extends Strategy
      *
      * @param Tag[] $tags
      *
+     * @param \Illuminate\Routing\Route $route
      * @return array|null
+     * @throws \Exception
      */
-    public function getApiResourceResponse(array $tags)
+    public function getApiResourceResponse(array $tags, Route $route)
     {
         if (empty($apiResourceTag = $this->getApiResourceTag($tags))) {
             return null;
@@ -111,8 +117,11 @@ class UseApiResourceTags extends Strategy
                 : $apiResourceClass::collection($list);
         }
 
+
         /** @var Response $response */
-        $response = $resource->toResponse(app(Request::class));
+        $response = $resource->toResponse(app(Request::class)->setRouteResolver(function () use ($route) {
+            return $route;
+        }));
 
         return [
             [
@@ -171,7 +180,6 @@ class UseApiResourceTags extends Strategy
      */
     protected function instantiateApiResourceModel(string $type, array $factoryStates = [], array $relations = [])
     {
-        $this->startDbTransaction();
         try {
             // Try Eloquent model factory
 
@@ -181,7 +189,10 @@ class UseApiResourceTags extends Strategy
 
             $factory = Utils::getModelFactory($type, $factoryStates);
             try {
-                return $factory->create();
+                $model =  $factory->create();
+                $model->load($relations);
+
+                return $model;
             } catch (Exception $e) {
                 // If there was no working database, it would fail.
                 return $factory->make();
@@ -204,8 +215,6 @@ class UseApiResourceTags extends Strategy
                     e::dumpExceptionIfVerbose($e);
                 }
             }
-        } finally {
-            $this->endDbTransaction();
         }
 
         return $instance;

+ 3 - 3
src/Extracting/Strategies/Responses/UseTransformerTags.php

@@ -47,12 +47,15 @@ class UseTransformerTags extends Strategy
         $methodDocBlock = $docBlocks['method'];
 
         try {
+            $this->startDbTransaction();
             return $this->getTransformerResponse($methodDocBlock->getTags());
         } catch (Exception $e) {
             c::warn('Exception thrown when fetching transformer response for [' . implode(',', $route->methods) . "] {$route->uri}.");
             e::dumpExceptionIfVerbose($e);
 
             return null;
+        } finally {
+            $this->endDbTransaction();
         }
     }
 
@@ -160,7 +163,6 @@ class UseTransformerTags extends Strategy
 
     protected function instantiateTransformerModel(string $type, array $factoryStates = [], array $relations = [])
     {
-        $this->startDbTransaction();
         try {
             // try Eloquent model factory
 
@@ -193,8 +195,6 @@ class UseTransformerTags extends Strategy
                     e::dumpExceptionIfVerbose($e);
                 }
             }
-        } finally {
-            $this->endDbTransaction();
         }
 
         return $instance;

+ 1 - 0
tests/Fixtures/TestUser.php

@@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Model;
 
 class TestUser extends Model
 {
+
     public function children()
     {
         return $this->hasMany(TestUser::class, 'parent_id');

+ 4 - 0
tests/Fixtures/TestUserApiResource.php

@@ -24,6 +24,10 @@ class TestUserApiResource extends JsonResource
             }),
         ];
 
+        if($request->route()->named('test')) {
+            $result['test'] = true;
+        }
+
         if ($this['state1'] && $this['random-state']) {
             $result['state1'] = $this['state1'];
             $result['random-state'] = $this['random-state'];

+ 7 - 1
tests/Fixtures/TestUserApiResourceCollection.php

@@ -15,11 +15,17 @@ class TestUserApiResourceCollection extends ResourceCollection
      */
     public function toArray($request)
     {
-        return [
+        $data = [
             'data' => $this->collection,
             'links' => [
                 'self' => 'link-value',
             ],
         ];
+
+        if($request->route()->named('test')) {
+            $data['test'] = true;
+        }
+
+        return $data;
     }
 }

+ 141 - 43
tests/Strategies/Responses/UseApiResourceTagsTest.php

@@ -2,11 +2,13 @@
 
 namespace Knuckles\Scribe\Tests\Strategies\Responses;
 
+use Illuminate\Routing\Route;
 use Knuckles\Scribe\Extracting\Strategies\Responses\UseApiResourceTags;
 use Knuckles\Scribe\ScribeServiceProvider;
 use Knuckles\Scribe\Tests\Fixtures\TestUser;
 use Knuckles\Scribe\Tools\DocumentationConfig;
 use Knuckles\Scribe\Tools\Utils;
+use Mockery;
 use Mpociot\Reflection\DocBlock\Tag;
 use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
 use Orchestra\Testbench\TestCase;
@@ -29,7 +31,7 @@ use Orchestra\Testbench\TestCase;
         return $providers;
     }
 
-    public function setUp(): void
+        public function setUp(): void
     {
         parent::setUp();
 
@@ -51,12 +53,18 @@ use Orchestra\Testbench\TestCase;
     {
         $config = new DocumentationConfig([]);
 
+        $route = Mockery::mock(Route::class);
+        $route->shouldReceive('named')
+            ->once()
+            ->with('test')
+            ->andReturn(true);
+
         $strategy = new UseApiResourceTags($config);
         $tags = [
             new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
             new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
         ];
-        $results = $strategy->getApiResourceResponse($tags);
+        $results = $strategy->getApiResourceResponse($tags, $route);
 
         $this->assertArraySubset([
             [
@@ -66,6 +74,7 @@ use Orchestra\Testbench\TestCase;
                         'id' => 4,
                         'name' => 'Tested Again',
                         'email' => 'a@b.com',
+                        'test' => true
                     ],
                 ]),
             ],
@@ -77,12 +86,18 @@ use Orchestra\Testbench\TestCase;
     {
         $config = new DocumentationConfig([]);
 
+        $route = Mockery::mock(Route::class);
+        $route->shouldReceive('named')
+            ->once()
+            ->with('test')
+            ->andReturn(true);
+
         $strategy = new UseApiResourceTags($config);
         $tags = [
             new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
             new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser states=state1,random-state'),
         ];
-        $results = $strategy->getApiResourceResponse($tags);
+        $results = $strategy->getApiResourceResponse($tags, $route);
 
         $this->assertArraySubset([
             [
@@ -92,6 +107,7 @@ use Orchestra\Testbench\TestCase;
                         'id' => 4,
                         'name' => 'Tested Again',
                         'email' => 'a@b.com',
+                        'test' => true,
                         'state1' => true,
                         'random-state' => true,
                     ],
@@ -100,58 +116,121 @@ use Orchestra\Testbench\TestCase;
         ], $results);
     }
 
-    /** @test */
-    public function loads_specified_relations_for_model()
-    {
-        $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]));
-            }
-        });
+        /** @test */
+        public function loads_specified_relations_for_model()
+        {
+            $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]));
+                }
+            });
 
-        $config = new DocumentationConfig([]);
+            $config = new DocumentationConfig([]);
 
-        $strategy = new UseApiResourceTags($config);
-        $tags = [
-            new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
-            new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
-        ];
-        $results = $strategy->getApiResourceResponse($tags);
+            $route = Mockery::mock(Route::class);
+            $route->shouldReceive('named')
+                ->times(2)
+                ->with('test')
+                ->andReturn(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',
+            $strategy = new UseApiResourceTags($config);
+            $tags = [
+                new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
+                new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
+            ];
+            $results = $strategy->getApiResourceResponse($tags, $route);
+
+            $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',
+                                    "test" => true
+                                ],
                             ],
+                            "test" => true
                         ],
-                    ],
-                ]),
-            ],
-        ], $results);
-    }
+                    ]),
+                ],
+            ], $results);
+        }
+
+        /** @test */
+        public function loads_specified_relations_for_generated_model()
+        {
+            $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]));
+                }
+            });
+            $config = new DocumentationConfig([]);
+
+            // Creating a mock route so we can test that the route is set properly during resolution
+            $route = Mockery::mock(Route::class);
+            $route->shouldReceive('named')
+                ->times(2)
+                ->with('test')
+                ->andReturn(true);
+
+            $strategy = new UseApiResourceTags($config);
+            $tags = [
+                new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
+                new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser with=children')
+            ];
+            $results = $strategy->getApiResourceResponse($tags, $route);
+
+            $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',
+                                    'test' => true
+                                ],
+                            ],
+                            'test' => true
+                        ],
+                    ]),
+                ],
+            ], $results);
+        }
 
     /** @test */
     public function can_parse_apiresourcecollection_tags()
     {
         $config = new DocumentationConfig([]);
 
+        $route = Mockery::mock(Route::class);
+        $route->shouldReceive('named')
+            ->times(2)
+            ->with('test')
+            ->andReturn(true);
+
         $strategy = new UseApiResourceTags($config);
         $tags = [
             new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResource'),
             new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
         ];
-        $results = $strategy->getApiResourceResponse($tags);
+        $results = $strategy->getApiResourceResponse($tags, $route);
 
         $this->assertArraySubset([
             [
@@ -162,11 +241,13 @@ use Orchestra\Testbench\TestCase;
                             'id' => 4,
                             'name' => 'Tested Again',
                             'email' => 'a@b.com',
+                            'test' => true,
                         ],
                         [
                             'id' => 4,
                             'name' => 'Tested Again',
                             'email' => 'a@b.com',
+                            'test' => true,
                         ],
                     ],
                 ]),
@@ -179,12 +260,18 @@ use Orchestra\Testbench\TestCase;
     {
         $config = new DocumentationConfig([]);
 
+        $route = Mockery::mock(Route::class);
+        $route->shouldReceive('named')
+            ->times(3)
+            ->with('test')
+            ->andReturn(true);
+
         $strategy = new UseApiResourceTags($config);
         $tags = [
-            new Tag('apiResourceCollection', 'Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
+            new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
             new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser'),
         ];
-        $results = $strategy->getApiResourceResponse($tags);
+        $results = $strategy->getApiResourceResponse($tags, $route);
 
         $this->assertArraySubset([
             [
@@ -195,16 +282,19 @@ use Orchestra\Testbench\TestCase;
                             'id' => 4,
                             'name' => 'Tested Again',
                             'email' => 'a@b.com',
+                            'test' => true
                         ],
                         [
                             'id' => 4,
                             'name' => 'Tested Again',
                             'email' => 'a@b.com',
+                            'test' => true
                         ],
                     ],
                     'links' => [
                         'self' => 'link-value',
                     ],
+                    'test' => true,
                 ]),
             ],
         ], $results);
@@ -215,12 +305,18 @@ use Orchestra\Testbench\TestCase;
     {
         $config = new DocumentationConfig([]);
 
+        $route = Mockery::mock(Route::class);
+        $route->shouldReceive('named')
+            ->times(2)
+            ->with('test')
+            ->andReturn(true);
+
         $strategy = new UseApiResourceTags($config);
         $tags = [
-            new Tag('apiResourceCollection', 'Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
+            new Tag('apiResourceCollection', '\Knuckles\Scribe\Tests\Fixtures\TestUserApiResourceCollection'),
             new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestUser paginate=1,simple'),
         ];
-        $results = $strategy->getApiResourceResponse($tags);
+        $results = $strategy->getApiResourceResponse($tags, $route);
 
         $this->assertArraySubset([
             [
@@ -231,6 +327,7 @@ use Orchestra\Testbench\TestCase;
                             'id' => 4,
                             'name' => 'Tested Again',
                             'email' => 'a@b.com',
+                            'test' => true,
                         ],
                     ],
                     'links' => [
@@ -240,6 +337,7 @@ use Orchestra\Testbench\TestCase;
                         "prev" => null,
                         "next" => '/?page=2',
                     ],
+                    'test' => true,
                     "meta" => [
                         "current_page" => 1,
                         "from" => 1,