From a37b3ba7d5cd46cbf870f688170a4a0a001d9e56 Mon Sep 17 00:00:00 2001 From: Tobias Oitzinger Date: Mon, 13 Jan 2025 11:33:09 +0100 Subject: [PATCH] feat(laravel): add support for backed enum normalizers Closes: #6906 Signed-off-by: Tobias Oitzinger --- src/Laravel/ApiPlatformProvider.php | 2 ++ src/Laravel/Tests/EloquentTest.php | 14 +++++++++++++ src/Laravel/Tests/GraphQlTest.php | 2 ++ .../workbench/app/Enums/BookStatus.php | 20 +++++++++++++++++++ src/Laravel/workbench/app/Models/Book.php | 6 ++++-- .../database/factories/BookFactory.php | 2 ++ .../2023_07_15_231244_create_book_table.php | 1 + 7 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/Laravel/workbench/app/Enums/BookStatus.php diff --git a/src/Laravel/ApiPlatformProvider.php b/src/Laravel/ApiPlatformProvider.php index d0f064f508b..039412fdf2c 100644 --- a/src/Laravel/ApiPlatformProvider.php +++ b/src/Laravel/ApiPlatformProvider.php @@ -221,6 +221,7 @@ use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\NameConverter\NameConverterInterface; use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer; +use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer; use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; use Symfony\Component\Serializer\Normalizer\DateTimeZoneNormalizer; @@ -1016,6 +1017,7 @@ public function register(): void $list->insert($app->make(DateTimeZoneNormalizer::class), -915); $list->insert($app->make(DateIntervalNormalizer::class), -915); $list->insert($app->make(DateTimeNormalizer::class), -910); + $list->insert($app->make(BackedEnumNormalizer::class), -910); $list->insert($app->make(ObjectNormalizer::class), -1000); $list->insert($app->make(ItemNormalizer::class), -895); $list->insert($app->make(OpenApiNormalizer::class), -780); diff --git a/src/Laravel/Tests/EloquentTest.php b/src/Laravel/Tests/EloquentTest.php index ad847eeced9..451da7a20cf 100644 --- a/src/Laravel/Tests/EloquentTest.php +++ b/src/Laravel/Tests/EloquentTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\Laravel\Tests; use ApiPlatform\Laravel\Test\ApiTestAssertionsTrait; +use ApiPlatform\Laravel\workbench\app\Enums\BookStatus; use Illuminate\Foundation\Testing\RefreshDatabase; use Orchestra\Testbench\Concerns\WithWorkbench; use Orchestra\Testbench\TestCase; @@ -27,6 +28,19 @@ class EloquentTest extends TestCase use RefreshDatabase; use WithWorkbench; + public function testBackedEnumsNormalization(): void + { + BookFactory::new([ + 'status' => BookStatus::DRAFT, + ])->has(AuthorFactory::new())->count(10)->create(); + + $response = $this->get('/api/books', ['Accept' => ['application/ld+json']]); + $book = $response->json()['member'][0]; + + $this->assertArrayHasKey('status', $book); + $this->assertSame('DRAFT', $book['status']); + } + public function testSearchFilter(): void { BookFactory::new()->has(AuthorFactory::new())->count(10)->create(); diff --git a/src/Laravel/Tests/GraphQlTest.php b/src/Laravel/Tests/GraphQlTest.php index e296bfb1ffa..bd1829c2abc 100644 --- a/src/Laravel/Tests/GraphQlTest.php +++ b/src/Laravel/Tests/GraphQlTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\Laravel\Tests; use ApiPlatform\Laravel\Test\ApiTestAssertionsTrait; +use ApiPlatform\Laravel\workbench\app\Enums\BookStatus; use Illuminate\Config\Repository; use Illuminate\Foundation\Application; use Illuminate\Foundation\Testing\RefreshDatabase; @@ -133,6 +134,7 @@ public function testCreateBook(): void 'name' => fake()->name(), 'author' => 'api/authors/'.$author->id, 'isbn' => fake()->isbn13(), + 'status' => BookStatus::PUBLISHED, 'isAvailable' => 1 === random_int(0, 1), ], ], diff --git a/src/Laravel/workbench/app/Enums/BookStatus.php b/src/Laravel/workbench/app/Enums/BookStatus.php new file mode 100644 index 00000000000..30e3b2de355 --- /dev/null +++ b/src/Laravel/workbench/app/Enums/BookStatus.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\Laravel\workbench\app\Enums; + +enum BookStatus: string +{ + case PUBLISHED = 'PUBLISHED'; + case DRAFT = 'DRAFT'; +} diff --git a/src/Laravel/workbench/app/Models/Book.php b/src/Laravel/workbench/app/Models/Book.php index 06c638e38fd..03ce657c88b 100644 --- a/src/Laravel/workbench/app/Models/Book.php +++ b/src/Laravel/workbench/app/Models/Book.php @@ -21,6 +21,7 @@ use ApiPlatform\Laravel\Eloquent\Filter\OrFilter; use ApiPlatform\Laravel\Eloquent\Filter\PartialSearchFilter; use ApiPlatform\Laravel\Eloquent\Filter\RangeFilter; +use ApiPlatform\Laravel\workbench\app\Enums\BookStatus; use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Delete; use ApiPlatform\Metadata\Get; @@ -86,10 +87,11 @@ class Book extends Model use HasFactory; use HasUlids; - protected $visible = ['name', 'author', 'isbn', 'publication_date', 'is_available']; - protected $fillable = ['name', 'is_available']; + protected $visible = ['name', 'author', 'isbn', 'status', 'publication_date', 'is_available']; + protected $fillable = ['name', 'status', 'is_available']; protected $casts = [ 'is_available' => 'boolean', + 'status' => BookStatus::class, ]; public function author(): BelongsTo diff --git a/src/Laravel/workbench/database/factories/BookFactory.php b/src/Laravel/workbench/database/factories/BookFactory.php index d94b3f281c9..ebe4a979988 100644 --- a/src/Laravel/workbench/database/factories/BookFactory.php +++ b/src/Laravel/workbench/database/factories/BookFactory.php @@ -13,6 +13,7 @@ namespace Workbench\Database\Factories; +use ApiPlatform\Laravel\workbench\app\Enums\BookStatus; use Illuminate\Database\Eloquent\Factories\Factory; use Symfony\Component\Uid\Ulid; use Workbench\App\Models\Book; @@ -38,6 +39,7 @@ public function definition(): array 'isbn' => fake()->isbn13(), 'publication_date' => fake()->optional()->date(), 'is_available' => 1 === random_int(0, 1), + 'status' => BookStatus::PUBLISHED, 'internal_note' => fake()->text(), ]; } diff --git a/src/Laravel/workbench/database/migrations/2023_07_15_231244_create_book_table.php b/src/Laravel/workbench/database/migrations/2023_07_15_231244_create_book_table.php index 0137554453c..ed9c1459b09 100644 --- a/src/Laravel/workbench/database/migrations/2023_07_15_231244_create_book_table.php +++ b/src/Laravel/workbench/database/migrations/2023_07_15_231244_create_book_table.php @@ -34,6 +34,7 @@ public function up(): void $table->date('publication_date')->nullable(); $table->boolean('is_available')->default(true); $table->text('internal_note')->nullable(); + $table->enum('status', ['PUBLISHED', 'DRAFT'])->default('PUBLISHED'); $table->integer('author_id')->unsigned(); $table->foreign('author_id')->references('id')->on('authors'); $table->timestamps();