diff --git a/CHANGELOG.md b/CHANGELOG.md index cdb5645..345ba25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,10 @@ classes you are retaining. a `v1` server after adding this package to their Laravel application. ### Removed -- **BREAKING** The `Arr` field has been removed - use the new `ArrayList` or `ArrayHash` +- **BREAKING** The `Arr` schema field has been removed - use the new `ArrayList` or `ArrayHash` fields instead. +- **BREAKING** The `uri` method on relationship routes has been removed. Relationship URIs +are now set on the schema field for the relationship (via the `withUriFieldName` method). ## [1.0.0-alpha.1] - 2021-01-25 diff --git a/src/Routing/PendingRelationshipRegistration.php b/src/Routing/PendingRelationshipRegistration.php index 213276b..5699137 100644 --- a/src/Routing/PendingRelationshipRegistration.php +++ b/src/Routing/PendingRelationshipRegistration.php @@ -82,19 +82,6 @@ public function __construct( $this->options = []; } - /** - * Set the URI for the relationship, if it is not the same as the field name. - * - * @param string $uri - * @return $this - */ - public function uri(string $uri): self - { - $this->options['relationship_uri'] = $uri; - - return $this; - } - /** * Set the methods the controller should apply to. * diff --git a/src/Routing/RelationshipRegistrar.php b/src/Routing/RelationshipRegistrar.php index e5dc007..360def0 100644 --- a/src/Routing/RelationshipRegistrar.php +++ b/src/Routing/RelationshipRegistrar.php @@ -22,6 +22,7 @@ use Illuminate\Contracts\Routing\Registrar as RegistrarContract; use Illuminate\Routing\Route as IlluminateRoute; use Illuminate\Routing\RouteCollection; +use LaravelJsonApi\Contracts\Schema\Schema; use LaravelJsonApi\Core\Support\Str; class RelationshipRegistrar @@ -32,6 +33,11 @@ class RelationshipRegistrar */ private RegistrarContract $router; + /** + * @var Schema + */ + private Schema $schema; + /** * @var string */ @@ -51,17 +57,20 @@ class RelationshipRegistrar * RelationshipRegistrar constructor. * * @param RegistrarContract $router + * @param Schema $schema * @param string $resourceType * @param string $controller * @param string $parameter */ public function __construct( RegistrarContract $router, + Schema $schema, string $resourceType, string $controller, string $parameter ) { $this->router = $router; + $this->schema = $schema; $this->resourceType = $resourceType; $this->controller = $controller; $this->parameter = $parameter; @@ -95,7 +104,7 @@ public function register(string $fieldName, bool $hasMany, array $options = []): */ protected function addShowRelated(string $fieldName, array $options): IlluminateRoute { - $uri = $this->getRelationshipUri($fieldName, $options); + $uri = $this->getRelationshipUri($fieldName); $action = $this->getRelationshipAction( 'showRelated', 'showRelated' . Str::classify($fieldName), @@ -120,7 +129,7 @@ protected function addShowRelated(string $fieldName, array $options): Illuminate */ protected function addShowRelationship(string $fieldName, array $options): IlluminateRoute { - $uri = $this->getRelationshipUri($fieldName, $options); + $uri = $this->getRelationshipUri($fieldName); $action = $this->getRelationshipAction( 'showRelationship', 'show' . Str::classify($fieldName), @@ -145,7 +154,7 @@ protected function addShowRelationship(string $fieldName, array $options): Illum */ protected function addUpdateRelationship(string $fieldName, array $options): IlluminateRoute { - $uri = $this->getRelationshipUri($fieldName, $options); + $uri = $this->getRelationshipUri($fieldName); $action = $this->getRelationshipAction( 'updateRelationship', 'update' . Str::classify($fieldName), @@ -170,7 +179,7 @@ protected function addUpdateRelationship(string $fieldName, array $options): Ill */ protected function addAttachRelationship(string $fieldName, array $options): IlluminateRoute { - $uri = $this->getRelationshipUri($fieldName, $options); + $uri = $this->getRelationshipUri($fieldName); $action = $this->getRelationshipAction( 'attachRelationship', 'attach' . Str::classify($fieldName), @@ -195,7 +204,7 @@ protected function addAttachRelationship(string $fieldName, array $options): Ill */ protected function addDetachRelationship(string $fieldName, array $options): IlluminateRoute { - $uri = $this->getRelationshipUri($fieldName, $options); + $uri = $this->getRelationshipUri($fieldName); $action = $this->getRelationshipAction( 'detachRelationship', 'detach' . Str::classify($fieldName), @@ -277,16 +286,11 @@ private function getRelationshipAction( /** * @param string $fieldName - * @param array $options * @return string */ - private function getRelationshipUri(string $fieldName, array $options): string + private function getRelationshipUri(string $fieldName): string { - if (isset($options['relationship_uri'])) { - return $options['relationship_uri']; - } - - return Str::dasherize($fieldName); + return $this->schema->relationship($fieldName)->uriName(); } /** diff --git a/src/Routing/ResourceRegistrar.php b/src/Routing/ResourceRegistrar.php index 48290f9..e0522af 100644 --- a/src/Routing/ResourceRegistrar.php +++ b/src/Routing/ResourceRegistrar.php @@ -88,9 +88,10 @@ public function relationships( $registrar = new RelationshipRegistrar( $this->router, + $this->server->schemas()->schemaFor($resourceType), $resourceType, $controller, - $parameter + $parameter, ); $routes = new RouteCollection(); diff --git a/tests/lib/Integration/Routing/HasManyTest.php b/tests/lib/Integration/Routing/HasManyTest.php index cb71882..5bc2d9b 100644 --- a/tests/lib/Integration/Routing/HasManyTest.php +++ b/tests/lib/Integration/Routing/HasManyTest.php @@ -74,7 +74,8 @@ public function genericProvider(): array public function test(string $method, string $uri, string $action, string $name): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) { @@ -99,13 +100,13 @@ public function test(string $method, string $uri, string $action, string $name): * @param string $method * @param string $uri * @param string $action - * @param string $name * @dataProvider genericProvider */ - public function testName(string $method, string $uri, string $action, string $name): void + public function testName(string $method, string $uri, string $action): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () use ($action) { JsonApiRoute::server('v1') @@ -131,7 +132,8 @@ public function testName(string $method, string $uri, string $action, string $na public function testMiddleware(string $method, string $uri): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -157,7 +159,8 @@ public function testMiddleware(string $method, string $uri): void public function testUri(string $method, string $uri): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'blog-tags', 'tags'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -165,7 +168,7 @@ public function testUri(string $method, string $uri): void ->namespace('Api\\V1') ->resources(function ($server) { $server->resource('posts')->relationships(function ($relations) { - $relations->hasMany('blog-tags')->uri('tags'); + $relations->hasMany('blog-tags'); }); }); }); @@ -234,7 +237,8 @@ public function onlyProvider(): array public function testOnly($only, array $matches): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () use ($only) { JsonApiRoute::server('v1') @@ -312,7 +316,8 @@ public function exceptProvider() public function testExcept($except, array $matches): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () use ($except) { JsonApiRoute::server('v1') @@ -331,7 +336,8 @@ public function testExcept($except, array $matches): void public function testReadOnly(): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -403,7 +409,8 @@ public function ownActionProvider(): array public function testOwnAction(string $method, string $uri, string $action, string $expected): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () use ($action) { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) use ($action) { @@ -430,7 +437,8 @@ public function testOwnAction(string $method, string $uri, string $action, strin public function testOwnActions(string $method, string $uri, string $action, string $expected): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'tags'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) { diff --git a/tests/lib/Integration/Routing/HasOneTest.php b/tests/lib/Integration/Routing/HasOneTest.php index 3a40054..3f233ee 100644 --- a/tests/lib/Integration/Routing/HasOneTest.php +++ b/tests/lib/Integration/Routing/HasOneTest.php @@ -62,7 +62,8 @@ public function genericProvider(): array public function test(string $method, string $uri, string $action, string $name): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) { @@ -87,13 +88,13 @@ public function test(string $method, string $uri, string $action, string $name): * @param string $method * @param string $uri * @param string $action - * @param string $name * @dataProvider genericProvider */ - public function testName(string $method, string $uri, string $action, string $name): void + public function testName(string $method, string $uri, string $action): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () use ($action) { JsonApiRoute::server('v1') @@ -121,7 +122,8 @@ public function testName(string $method, string $uri, string $action, string $na public function testMiddleware(string $method, string $uri, string $action, string $name): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -149,7 +151,8 @@ public function testMiddleware(string $method, string $uri, string $action, stri public function testUri(string $method, string $uri, string $action, string $name): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'user', 'author'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -157,7 +160,7 @@ public function testUri(string $method, string $uri, string $action, string $nam ->namespace('Api\\V1') ->resources(function ($server) { $server->resource('posts')->relationships(function ($relations) { - $relations->hasOne('user')->uri('author'); + $relations->hasOne('user'); }); }); }); @@ -203,7 +206,8 @@ public function onlyProvider(): array public function testOnly($only, array $matches): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () use ($only) { JsonApiRoute::server('v1') @@ -258,7 +262,8 @@ public function exceptProvider() public function testExcept($except, array $matches): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () use ($except) { JsonApiRoute::server('v1') @@ -277,7 +282,8 @@ public function testExcept($except, array $matches): void public function testReadOnly(): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1') @@ -334,7 +340,8 @@ public function ownActionProvider(): array public function testOwnAction(string $method, string $uri, string $action, string $expected): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () use ($action) { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) use ($action) { @@ -361,7 +368,8 @@ public function testOwnAction(string $method, string $uri, string $action, strin public function testOwnActions(string $method, string $uri, string $action, string $expected): void { $server = $this->createServer('v1'); - $this->createSchema($server, 'posts', '\d+'); + $schema = $this->createSchema($server, 'posts', '\d+'); + $this->createRelation($schema, 'author'); $this->defaultApiRoutesWithNamespace(function () { JsonApiRoute::server('v1')->prefix('v1')->namespace('Api\\V1')->resources(function ($server) { @@ -377,4 +385,5 @@ public function testOwnActions(string $method, string $uri, string $action, stri $this->assertSame('post', $route->parameter('resource_id_name')); $this->assertSame('author', $route->parameter('resource_relationship')); } + } diff --git a/tests/lib/Integration/Routing/TestCase.php b/tests/lib/Integration/Routing/TestCase.php index f567c2a..290e8f7 100644 --- a/tests/lib/Integration/Routing/TestCase.php +++ b/tests/lib/Integration/Routing/TestCase.php @@ -24,6 +24,7 @@ use Illuminate\Support\Facades\Route; use LaravelJsonApi\Contracts\Schema\Container; use LaravelJsonApi\Contracts\Schema\ID; +use LaravelJsonApi\Contracts\Schema\Relation; use LaravelJsonApi\Contracts\Schema\Schema; use LaravelJsonApi\Contracts\Server\Repository; use LaravelJsonApi\Contracts\Server\Server; @@ -83,6 +84,21 @@ protected function createSchema(Server $server, string $name, string $pattern = return $schema; } + /** + * @param MockObject $schema + * @param string $fieldName + * @param string|null $uriName + * @return void + */ + protected function createRelation(MockObject $schema, string $fieldName, string $uriName = null): void + { + $relation = $this->createMock(Relation::class); + $relation->method('name')->willReturn($fieldName); + $relation->method('uriName')->willReturn($uriName ?: $fieldName); + + $schema->method('relationship')->with($fieldName)->willReturn($relation); + } + /** * @param string $method * @param string $url