Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Enums/NullResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace MyParcelCom\JsonApi\Enums;

enum NullResource: string
{
case TYPE = '';
}
11 changes: 4 additions & 7 deletions src/Exceptions/InvalidScopeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,22 @@

namespace MyParcelCom\JsonApi\Exceptions;

use BackedEnum;
use MyParcelCom\JsonApi\Traits\EnumTrait;
use Symfony\Component\HttpFoundation\Response;
use Throwable;
use UnitEnum;

/**
* This exception is thrown when a scope is either not available at all, not unavailable for the chosen grant type or
* not attached to the requesting client.
*/
class InvalidScopeException 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(
Expand Down
11 changes: 4 additions & 7 deletions src/Exceptions/MissingScopeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
11 changes: 9 additions & 2 deletions src/Exceptions/RelationshipCannotBeModifiedException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 6 additions & 4 deletions src/Exceptions/ResourceHandledBy3rdPartyException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 6 additions & 4 deletions src/Exceptions/ResourceNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 20 additions & 0 deletions src/Traits/EnumTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace MyParcelCom\JsonApi\Traits;

use BackedEnum;
use UnitEnum;

trait EnumTrait
{
public function getEnumValue(mixed $enum): mixed
{
return match (true) {
$enum instanceof BackedEnum => $enum->value,
$enum instanceof UnitEnum => $enum->name,
default => $enum,
};
}
}
13 changes: 10 additions & 3 deletions src/Transformers/AbstractTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

/**
Expand Down
10 changes: 10 additions & 0 deletions tests/Enums/TestBackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace MyParcelCom\JsonApi\Tests\Enums;

enum TestBackedEnum: string
{
case TEST = 'test';
}
10 changes: 10 additions & 0 deletions tests/Enums/TestUnitEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace MyParcelCom\JsonApi\Tests\Enums;

enum TestUnitEnum
{
case test;
}
25 changes: 25 additions & 0 deletions tests/Exceptions/ExceptionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use MyParcelCom\JsonApi\Exceptions\ResourceNotFoundException;
use MyParcelCom\JsonApi\Exceptions\TooManyRequestsException;
use MyParcelCom\JsonApi\Exceptions\UnprocessableEntityException;
use MyParcelCom\JsonApi\Tests\Enums\TestBackedEnum;
use PHPUnit\Framework\TestCase;

class ExceptionsTest extends TestCase
Expand Down Expand Up @@ -210,6 +211,13 @@ public function testResourceNotFoundException(): void
$this->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'));
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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());
}
}
10 changes: 0 additions & 10 deletions tests/Stubs/TransformerStub.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
44 changes: 43 additions & 1 deletion tests/Transformers/AbstractTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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
Expand Down