diff --git a/src/Enums/NullResource.php b/src/Enums/NullResource.php new file mode 100644 index 0000000..18a2f7c --- /dev/null +++ b/src/Enums/NullResource.php @@ -0,0 +1,10 @@ +map(fn ($scope) => match (true) { - $scope instanceof BackedEnum => $scope->value, - $scope instanceof UnitEnum => $scope->name, - default => $scope, - }) + ->map(fn (mixed $scopeSlug) => $this->getEnumValue($scopeSlug)) ->toArray(); parent::__construct( diff --git a/src/Exceptions/MissingScopeException.php b/src/Exceptions/MissingScopeException.php index b2e9421..bc6a4ac 100644 --- a/src/Exceptions/MissingScopeException.php +++ b/src/Exceptions/MissingScopeException.php @@ -4,21 +4,18 @@ namespace MyParcelCom\JsonApi\Exceptions; -use BackedEnum; +use MyParcelCom\JsonApi\Traits\EnumTrait; use Symfony\Component\HttpFoundation\Response; use Throwable; -use UnitEnum; class MissingScopeException extends AbstractException { + use EnumTrait; + public function __construct(array $scopeSlugs, Throwable $previous = null) { $scopeStrings = collect($scopeSlugs) - ->map(fn ($scope) => match (true) { - $scope instanceof BackedEnum => $scope->value, - $scope instanceof UnitEnum => $scope->name, - default => $scope, - }) + ->map(fn (mixed $scopeSlug) => $this->getEnumValue($scopeSlug)) ->toArray(); parent::__construct( diff --git a/src/Exceptions/RelationshipCannotBeModifiedException.php b/src/Exceptions/RelationshipCannotBeModifiedException.php index 2e32af9..3629a5a 100644 --- a/src/Exceptions/RelationshipCannotBeModifiedException.php +++ b/src/Exceptions/RelationshipCannotBeModifiedException.php @@ -4,15 +4,22 @@ namespace MyParcelCom\JsonApi\Exceptions; +use MyParcelCom\JsonApi\Traits\EnumTrait; use Symfony\Component\HttpFoundation\Response; use Throwable; +use UnitEnum; class RelationshipCannotBeModifiedException extends AbstractException { - public function __construct(string $relationshipType, Throwable $previous = null) + use EnumTrait; + + public function __construct(UnitEnum|string $relationshipType, Throwable $previous = null) { parent::__construct( - "The relationship of type '{$relationshipType}' cannot be modified on this resource.", + sprintf( + "The relationship of type '%s' cannot be modified on this resource.", + $this->getEnumValue($relationshipType), + ), self::RELATIONSHIP_CANNOT_BE_MODIFIED, Response::HTTP_FORBIDDEN, $previous, diff --git a/src/Exceptions/ResourceHandledBy3rdPartyException.php b/src/Exceptions/ResourceHandledBy3rdPartyException.php index 670ccea..0cf1061 100644 --- a/src/Exceptions/ResourceHandledBy3rdPartyException.php +++ b/src/Exceptions/ResourceHandledBy3rdPartyException.php @@ -4,17 +4,19 @@ namespace MyParcelCom\JsonApi\Exceptions; +use MyParcelCom\JsonApi\Traits\EnumTrait; use Symfony\Component\HttpFoundation\Response; use Throwable; +use UnitEnum; class ResourceHandledBy3rdPartyException extends AbstractException { - public function __construct(string $resourceType, string $platform, Throwable $previous = null) - { - $message = sprintf('One or more of the %s resource is handled by a 3rd party.', $resourceType); + use EnumTrait; + public function __construct(UnitEnum|string $resourceType, string $platform, Throwable $previous = null) + { parent::__construct( - $message, + sprintf('One or more of the %s resource is handled by a 3rd party.', $this->getEnumValue($resourceType)), self::RESOURCE_HANDLED_BY_3RD_PARTY, Response::HTTP_CONFLICT, $previous, diff --git a/src/Exceptions/ResourceNotFoundException.php b/src/Exceptions/ResourceNotFoundException.php index abcd851..3f983d3 100644 --- a/src/Exceptions/ResourceNotFoundException.php +++ b/src/Exceptions/ResourceNotFoundException.php @@ -4,17 +4,19 @@ namespace MyParcelCom\JsonApi\Exceptions; +use MyParcelCom\JsonApi\Traits\EnumTrait; use Symfony\Component\HttpFoundation\Response; use Throwable; +use UnitEnum; class ResourceNotFoundException extends AbstractException { - public function __construct(string $resourceType, Throwable $previous = null) - { - $message = sprintf('One or more of the %s resource could not be found.', $resourceType); + use EnumTrait; + public function __construct(UnitEnum|string $resourceType, Throwable $previous = null) + { parent::__construct( - $message, + sprintf('One or more of the %s resource could not be found.', $this->getEnumValue($resourceType)), self::RESOURCE_NOT_FOUND, Response::HTTP_NOT_FOUND, $previous, diff --git a/src/Traits/EnumTrait.php b/src/Traits/EnumTrait.php new file mode 100644 index 0000000..32d160d --- /dev/null +++ b/src/Traits/EnumTrait.php @@ -0,0 +1,20 @@ + $enum->value, + $enum instanceof UnitEnum => $enum->name, + default => $enum, + }; + } +} diff --git a/src/Transformers/AbstractTransformer.php b/src/Transformers/AbstractTransformer.php index 9f53a0d..78efc2e 100644 --- a/src/Transformers/AbstractTransformer.php +++ b/src/Transformers/AbstractTransformer.php @@ -6,17 +6,22 @@ use DateTime; use Illuminate\Contracts\Routing\UrlGenerator; +use MyParcelCom\JsonApi\Enums\NullResource; use MyParcelCom\JsonApi\Resources\ResourceIdentifier; use MyParcelCom\JsonApi\Traits\ArrayFilterTrait; +use MyParcelCom\JsonApi\Traits\EnumTrait; +use UnitEnum; /** @template TModel */ abstract class AbstractTransformer implements TransformerInterface { use ArrayFilterTrait; + use EnumTrait; protected UrlGenerator $urlGenerator; protected string $type = ''; + protected UnitEnum $resourceType = NullResource::TYPE; public function __construct( protected TransformerFactory $transformerFactory, @@ -132,11 +137,13 @@ public function transformIdentifier($model, bool $includeMeta = false): array */ public function getType(): string { - if (empty($this->type)) { - throw new TransformerException('Error no transformer resource `type` set for model'); + $type = empty($this->type) ? $this->getEnumValue($this->resourceType) : $this->type; + + if (empty($type)) { + throw new TransformerException('Error no `resourceType` or `type` set on transformer'); } - return $this->type; + return $type; } /** diff --git a/tests/Enums/TestBackedEnum.php b/tests/Enums/TestBackedEnum.php new file mode 100644 index 0000000..961347c --- /dev/null +++ b/tests/Enums/TestBackedEnum.php @@ -0,0 +1,10 @@ +assertEquals('One or more of the API resource could not be found.', $exception->getMessage()); } + public function testResourceNotFoundExceptionUsingEnum(): void + { + $exception = new ResourceNotFoundException(TestBackedEnum::TEST); + + $this->assertEquals('One or more of the test resource could not be found.', $exception->getMessage()); + } + public function testUnprocessableEntityException(): void { $exception = new UnprocessableEntityException('RAW', new Exception('G-Star')); @@ -279,6 +287,16 @@ public function testRelationshipCannotBeModifiedException(): void ); } + public function testRelationshipCannotBeModifiedExceptionUsingEnum(): void + { + $exception = new RelationshipCannotBeModifiedException(TestBackedEnum::TEST); + + $this->assertEquals( + "The relationship of type 'test' cannot be modified on this resource.", + $exception->getMessage(), + ); + } + public function testInvalidCredentialsException(): void { $errors = [ @@ -321,4 +339,11 @@ public function testResourceHandledBy3rdPartyException(): void self::assertEquals(409, $exception->getStatus()); self::assertEquals(['3rd_party' => 'Bol'], $exception->getMeta()); } + + public function testResourceHandledBy3rdPartyExceptionUsingEnum(): void + { + $exception = new ResourceHandledBy3rdPartyException(TestBackedEnum::TEST, 'Bol'); + + $this->assertEquals('One or more of the test resource is handled by a 3rd party.', $exception->getMessage()); + } } diff --git a/tests/Stubs/TransformerStub.php b/tests/Stubs/TransformerStub.php index 4e101df..3af9681 100644 --- a/tests/Stubs/TransformerStub.php +++ b/tests/Stubs/TransformerStub.php @@ -15,16 +15,6 @@ class TransformerStub extends AbstractTransformer protected string $type = 'test'; - /** - * Helper function to reset the type for the abstract exception test. - */ - public function clearType(): self - { - $this->type = ''; - - return $this; - } - public function getId($model): string { return 'mockId'; diff --git a/tests/Transformers/AbstractTransformerTest.php b/tests/Transformers/AbstractTransformerTest.php index 345f308..5d5a1e1 100644 --- a/tests/Transformers/AbstractTransformerTest.php +++ b/tests/Transformers/AbstractTransformerTest.php @@ -9,11 +9,14 @@ use Mockery; use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; use MyParcelCom\JsonApi\Resources\ResourceIdentifier; +use MyParcelCom\JsonApi\Tests\Enums\TestBackedEnum; +use MyParcelCom\JsonApi\Tests\Enums\TestUnitEnum; use MyParcelCom\JsonApi\Tests\Stubs\TransformerStub; use MyParcelCom\JsonApi\Transformers\TransformerException; use MyParcelCom\JsonApi\Transformers\TransformerFactory; use PHPUnit\Framework\TestCase; use stdClass; +use UnitEnum; class AbstractTransformerTest extends TestCase { @@ -64,10 +67,49 @@ public function testTransform(): void $this->assertEmpty($this->transformer->getRelationLink($this->model)); } + public function testTypeUsingUnitEnum(): void + { + $transformer = new class extends TransformerStub { + protected string $type = ''; + protected UnitEnum $resourceType = TestUnitEnum::test; + + public function __construct() + { + parent::__construct(Mockery::mock(TransformerFactory::class)); + } + }; + + $this->assertSame('test', $transformer->getType()); + } + + public function testTypeUsingBackedEnum(): void + { + $transformer = new class extends TransformerStub { + protected string $type = ''; + protected UnitEnum $resourceType = TestBackedEnum::TEST; + + public function __construct() + { + parent::__construct(Mockery::mock(TransformerFactory::class)); + } + }; + + $this->assertSame('test', $transformer->getType()); + } + public function testGetTypeException(): void { + $transformer = new class extends TransformerStub { + protected string $type = ''; + + public function __construct() + { + parent::__construct(Mockery::mock(TransformerFactory::class)); + } + }; + $this->expectException(TransformerException::class); - $this->transformer->clearType()->getType(); + $transformer->getType(); } public function testTransformRelationship(): void