Browse Source

Add tests for morphToMany & morphOne relationships

Peter Ragheb 2 years ago
parent
commit
98c323bcfa

+ 21 - 0
tests/Fixtures/TestImage.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class TestImage extends Model
+{
+    use HasFactory;
+
+    protected static function newFactory()
+    {
+        return TestImageFactory::new();
+    }
+
+    public function imageable()
+    {
+        return $this->morphTo();
+    }
+}

+ 23 - 0
tests/Fixtures/TestImageApiResource.php

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

+ 18 - 0
tests/Fixtures/TestImageFactory.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Knuckles\Scribe\Tests\Fixtures;
+
+use Illuminate\Database\Eloquent\Factories\Factory;
+
+class TestImageFactory extends Factory
+{
+    protected $model = TestImage::class;
+
+    public function definition(): array
+    {
+        return [
+            'id' => 1,
+            'url' => 'https://test.com',
+        ];
+    }
+}

+ 19 - 0
tests/Fixtures/TestPost.php

@@ -2,12 +2,31 @@
 
 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('order');
+    }
+
+    public function image()
+    {
+        return $this->morphOne(TestImage::class, 'imageable');
+    }
 }

+ 30 - 0
tests/Fixtures/TestPostApiResource.php

@@ -0,0 +1,30 @@
+<?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);
+            }),
+            'image' => $this->whenLoaded('image', function () {
+                return TestImageApiResource::make($this->image);
+            }),
+        ];
+    }
+}

+ 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 [
+            'order' => 1
+        ];
+    }
+}

+ 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('order');
+    }
+}

+ 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 ,
+            'order' => $this->whenPivotLoaded('taggables', function () {
+                return $this->pivot->order;
+            }),
+        ];
+    }
+}

+ 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',
+        ];
+    }
+}

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

@@ -501,6 +501,109 @@ 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->integer('order');
+        });
+
+        $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',
+                                'order' => 1
+                            ],
+                        ],
+                    ],
+                ]),
+            ],
+        ], $results);
+    }
+
+    /** @test */
+    public function loads_specified_morph_one_relations_for_generated_model()
+    {
+        Schema::create('test_posts', function (Blueprint $table) {
+            $table->id();
+            $table->string('title');
+            $table->string('body');
+            $table->timestamps();
+        });
+
+        Schema::create('test_images', function (Blueprint $table) {
+            $table->id();
+            $table->string('imageable_type');
+            $table->string('imageable_id');
+            $table->string('url');
+            $table->timestamps();
+        });
+
+        $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=image'),
+        ];
+        $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',
+                        'image' => [
+                            'id' => 1,
+                            'url' => 'https://test.com',
+                        ],
+                    ]
+                ]),
+            ],
+        ], $results);
+    }
+
     /** @test */
     public function can_parse_apiresourcecollection_tags()
     {