Ver código fonte

Merge remote-tracking branch 'origin/master'

shalvah 2 anos atrás
pai
commit
0cff5a818a

+ 4 - 3
src/Tools/Utils.php

@@ -269,14 +269,15 @@ class Utils
                 $relationChain = explode('.', $relation);
                 $relationVector = array_shift($relationChain);
 
-                $relationModel = get_class((new $modelName())->{$relationVector}()->getModel());
-                $relationType = get_class((new $modelName())->{$relationVector}());
+                $relation = (new $modelName())->{$relationVector}();
+                $relationType = get_class($relation);
+                $relationModel = get_class($relation->getModel());
 
                 $factoryChain = empty($relationChain)
                     ? call_user_func_array([$relationModel, 'factory'], [])
                     : Utils::getModelFactory($relationModel, $states, [implode('.', $relationChain)]);
 
-                if ($relationType === BelongsToMany::class) {
+                if ($relation instanceof BelongsToMany) {
                     $pivot = method_exists($factory, 'pivot' . $relationVector)
                         ? $factory->{'pivot' . $relationVector}()
                         : [];

+ 14 - 0
tests/Fixtures/TestPost.php

@@ -2,12 +2,26 @@
 
 namespace Knuckles\Scribe\Tests\Fixtures;
 
+use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\MorphToMany;
 
 class TestPost extends Model
 {
+    use HasFactory;
+
     public function getRouteKeyName()
     {
         return 'slug';
     }
+
+    protected static function newFactory()
+    {
+        return TestPostFactory::new();
+    }
+
+    public function tags(): MorphToMany
+    {
+        return $this->morphToMany(TestTag::class, 'taggable')->withPivot('priority');
+    }
 }

+ 27 - 0
tests/Fixtures/TestPostApiResource.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class TestPostApiResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     *
+     * @return array
+     */
+    public function toArray($request)
+    {
+        return [
+            'id' => $this->id,
+            'title' => $this->title ,
+            'body' => $this->body,
+            'tags' => $this->whenLoaded('tags', function () {
+                return TestTagApiResource::collection($this->tags);
+            }),
+        ];
+    }
+}

+ 26 - 0
tests/Fixtures/TestPostFactory.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+class TestPostFactory extends Factory
+{
+    protected $model = TestPost::class;
+
+    public function definition(): array
+    {
+        return [
+            'id' => 1,
+            'title' => 'Test title',
+            'body' => 'random body',
+        ];
+    }
+
+    public function pivotTags(): array
+    {
+        return [
+            'priority' => "high"
+        ];
+    }
+}

+ 22 - 0
tests/Fixtures/TestTag.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\MorphToMany;
+
+class TestTag extends Model
+{
+    use HasFactory;
+
+    protected static function newFactory()
+    {
+        return TestTagFactory::new();
+    }
+
+    public function posts(): MorphToMany
+    {
+        return $this->morphedByMany(TestPost::class, 'taggable')->withPivot('priority');
+    }
+}

+ 26 - 0
tests/Fixtures/TestTagApiResource.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class TestTagApiResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     *
+     * @return array
+     */
+    public function toArray($request)
+    {
+        return [
+            'id' => $this->id,
+            'name' => $this->name ,
+            'priority' => $this->whenPivotLoaded('taggables', function () {
+                return $this->pivot->priority;
+            }),
+        ];
+    }
+}

+ 18 - 0
tests/Fixtures/TestTagFactory.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+class TestTagFactory extends Factory
+{
+    protected $model = TestTag::class;
+
+    public function definition(): array
+    {
+        return [
+            'id' => 1,
+            'name' => 'tag 1',
+        ];
+    }
+}

+ 56 - 0
tests/Strategies/Responses/UseApiResourceTagsTest.php

@@ -501,6 +501,62 @@ class UseApiResourceTagsTest extends BaseLaravelTest
         ], $results);
     }
 
+    /** @test */
+    public function loads_specified_morph_to_many_relations_for_generated_model_with_pivot()
+    {
+        Schema::create('test_posts', function (Blueprint $table) {
+            $table->id();
+            $table->string('title');
+            $table->string('body');
+            $table->timestamps();
+        });
+
+        Schema::create('test_tags', function (Blueprint $table) {
+            $table->id();
+            $table->string('name');
+            $table->timestamps();
+        });
+
+        Schema::create('taggables', function (Blueprint $table) {
+            $table->id();
+            $table->string('test_tag_id');
+            $table->string('taggable_type');
+            $table->string('taggable_id');
+            $table->string('priority');
+        });
+
+        $config = new DocumentationConfig([]);
+
+        $route = new Route(['POST'], "/somethingRandom", ['uses' => [TestController::class, 'dummy']]);
+
+        $strategy = new UseApiResourceTags($config);
+        $tags = [
+            new Tag('apiResource', '\Knuckles\Scribe\Tests\Fixtures\TestPostApiResource'),
+            new Tag('apiResourceModel', '\Knuckles\Scribe\Tests\Fixtures\TestPost with=tags'),
+        ];
+        $results = $strategy->getApiResourceResponseFromTags($strategy->getApiResourceTag($tags), $tags, ExtractedEndpointData::fromRoute($route));
+
+        $this->assertArraySubset([
+            [
+                'status' => 200,
+                'content' => json_encode([
+                    'data' => [
+                        'id' => 1,
+                        'title' => 'Test title',
+                        'body' => 'random body',
+                        'tags' => [
+                            [
+                                'id' => 1,
+                                'name' => 'tag 1',
+                                'priority' => "high"
+                            ],
+                        ],
+                    ],
+                ]),
+            ],
+        ], $results);
+    }
+
     /** @test */
     public function can_parse_apiresourcecollection_tags()
     {