Skip to content

Commit

Permalink
Merge branch 'release/4.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
lindyhopchris committed Jun 26, 2024
2 parents 013380f + b2e1012 commit 0aef20a
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 36 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file. This projec

## Unreleased

## [4.1.0] - 2024-06-26

### Fixed

- [core#17](https://github.com/laravel-json-api/core/pull/17) Fix incorrect `self` link in related resource responses,
and remove `related` link that should not exist. This has been incorrect for some time, but is definitely what
the [spec defines here.](https://jsonapi.org/format/1.0/#document-top-level)
- [eloquent#36](https://github.com/laravel-json-api/eloquent/pull/36) Support Eloquent dynamic relationships.

## [4.0.0] - 2024-03-14

### Changed
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
"require": {
"php": "^8.2",
"ext-json": "*",
"laravel-json-api/core": "^4.0",
"laravel-json-api/eloquent": "^4.0",
"laravel-json-api/core": "^4.1",
"laravel-json-api/eloquent": "^4.1",
"laravel-json-api/encoder-neomerx": "^4.0",
"laravel-json-api/exceptions": "^3.0",
"laravel-json-api/spec": "^3.0",
Expand Down
9 changes: 4 additions & 5 deletions tests/dummy/tests/Api/V1/Posts/ReadAuthorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@ public function test(): void
$response = $this
->withoutExceptionHandling()
->jsonApi('users')
->get($related = url('/api/v1/posts', [$this->post, 'author']));
->get($self = url('/api/v1/posts', [$this->post, 'author']));

$response->assertFetchedOneExact($expected)->assertLinks([
'self' => url('/api/v1/posts', [$this->post, 'relationships', 'author']),
'related' => $related,
]);
$response
->assertFetchedOneExact($expected)
->assertLinks(['self' => $self]);
}

public function testFilterMatches(): void
Expand Down
9 changes: 2 additions & 7 deletions tests/dummy/tests/Api/V1/Posts/ReadCommentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,10 @@ public function test(): void
$response = $this
->withoutExceptionHandling()
->jsonApi('comments')
->get($related = url('/api/v1/posts', [$this->post, 'comments']));

$links = [
'self' => url('/api/v1/posts', [$this->post, 'relationships', 'comments']),
'related' => $related,
];
->get($self = url('/api/v1/posts', [$this->post, 'comments']));

$response->assertFetchedMany($expected)
->assertLinks($links)
->assertLinks(['self' => $self])
->assertExactMeta(['count' => 3]);
}

Expand Down
9 changes: 5 additions & 4 deletions tests/dummy/tests/Api/V1/Posts/ReadTagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ public function test(): void

$response = $this
->jsonApi('tags')
->get(url('/api/v1/posts', [$this->post, 'tags']));
->get($self = url('/api/v1/posts', [$this->post, 'tags']));

$response->assertFetchedMany($expected)->assertExactMeta([
'count' => count($expected)
]);
$response
->assertFetchedMany($expected)
->assertExactMeta(['count' => count($expected)])
->assertLinks(['self' => $self]);
}

public function testSort(): void
Expand Down
61 changes: 52 additions & 9 deletions tests/lib/Acceptance/Relationships/ToManyLinksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use App\Models\Post;
use App\Models\Tag;
use Closure;
use LaravelJsonApi\Core\Document\Links;
use LaravelJsonApi\Core\Facades\JsonApi;
use LaravelJsonApi\Laravel\Facades\JsonApiRoute;
use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController;
Expand Down Expand Up @@ -60,7 +61,7 @@ protected function setUp(): void
/**
* @return array[]
*/
public static function scenarioProvider(): array
public static function relationshipProvider(): array
{
return [
'hidden' => [
Expand Down Expand Up @@ -99,39 +100,81 @@ static function (PostSchema $schema, Post $post) {
/**
* @param Closure $scenario
* @return void
* @dataProvider scenarioProvider
* @dataProvider relationshipProvider
*/
public function testRelated(Closure $scenario): void
public function testRelationship(Closure $scenario): void
{
$expected = $scenario($this->schema, $this->post);

$response = $this
->withoutExceptionHandling()
->jsonApi('tags')
->get(url('/api/v1/posts', [$this->post, 'tags']));
->get(url('/api/v1/posts', [$this->post, 'relationships', 'tags']));

$response->assertFetchedMany([$this->tag]);
$response->assertFetchedToMany([$this->tag]);

if (is_array($expected)) {
$response->assertLinks($expected);
}
}


/**
* @return array[]
*/
public static function relatedProvider(): array
{
return [
'hidden' => [
static function (PostSchema $schema) {
$schema->relationship('tags')->hidden();
return null;
},
],
'no links' => [
static function (PostSchema $schema) {
$schema->relationship('tags')->serializeUsing(
static fn($relation) => $relation->withoutLinks()
);
return null;
},
],
'no self link' => [
static function (PostSchema $schema, Post $post) {
$schema->relationship('tags')->serializeUsing(
static fn($relation) => $relation->withoutSelfLink()
);
// related becomes self.
return ['self' => url('/api/v1/posts', [$post, 'tags'])];
},
],
'no related link' => [
static function (PostSchema $schema, Post $post) {
$schema->relationship('tags')->serializeUsing(
static fn($relation) => $relation->withoutRelatedLink()
);
// related becomes self, but it's missing so we can't do that.
return null;
},
],
];
}

/**
* @param Closure $scenario
* @return void
* @dataProvider scenarioProvider
* @dataProvider relatedProvider
*/
public function testSelf(Closure $scenario): void
public function testRelated(Closure $scenario): void
{
$expected = $scenario($this->schema, $this->post);

$response = $this
->withoutExceptionHandling()
->jsonApi('tags')
->get(url('/api/v1/posts', [$this->post, 'relationships', 'tags']));
->get(url('/api/v1/posts', [$this->post, 'tags']));

$response->assertFetchedToMany([$this->tag]);
$response->assertFetchedMany([$this->tag]);

if (is_array($expected)) {
$response->assertLinks($expected);
Expand Down
59 changes: 50 additions & 9 deletions tests/lib/Acceptance/Relationships/ToOneLinksTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected function setUp(): void
/**
* @return array[]
*/
public static function scenarioProvider(): array
public static function relationshipProvider(): array
{
return [
'hidden' => [
Expand Down Expand Up @@ -92,39 +92,80 @@ static function (PostSchema $schema, Post $post) {
/**
* @param Closure $scenario
* @return void
* @dataProvider scenarioProvider
* @dataProvider relationshipProvider
*/
public function testRelated(Closure $scenario): void
public function testRelationship(Closure $scenario): void
{
$expected = $scenario($this->schema, $this->post);

$response = $this
->withoutExceptionHandling()
->jsonApi('users')
->get(url('/api/v1/posts', [$this->post, 'author']));
->get(url('/api/v1/posts', [$this->post, 'relationships', 'author']));

$response->assertFetchedOne($this->post->author);
$response->assertFetchedToOne($this->post->author);

if (is_array($expected)) {
$response->assertLinks($expected);
}
}

/**
* @return array[]
*/
public static function relatedProvider(): array
{
return [
'hidden' => [
static function (PostSchema $schema) {
$schema->relationship('author')->hidden();
return null;
},
],
'no links' => [
static function (PostSchema $schema) {
$schema->relationship('author')->serializeUsing(
static fn($relation) => $relation->withoutLinks()
);
return null;
},
],
'no self link' => [
static function (PostSchema $schema, Post $post) {
$schema->relationship('author')->serializeUsing(
static fn($relation) => $relation->withoutSelfLink()
);
// related becomes self
return ['self' => url('/api/v1/posts', [$post, 'author'])];
},
],
'no related link' => [
static function (PostSchema $schema, Post $post) {
$schema->relationship('author')->serializeUsing(
static fn($relation) => $relation->withoutRelatedLink()
);
// related becomes self but it's missing
return null;
},
],
];
}

/**
* @param Closure $scenario
* @return void
* @dataProvider scenarioProvider
* @dataProvider relatedProvider
*/
public function testSelf(Closure $scenario): void
public function testRelated(Closure $scenario): void
{
$expected = $scenario($this->schema, $this->post);

$response = $this
->withoutExceptionHandling()
->jsonApi('users')
->get(url('/api/v1/posts', [$this->post, 'relationships', 'author']));
->get(url('/api/v1/posts', [$this->post, 'author']));

$response->assertFetchedToOne($this->post->author);
$response->assertFetchedOne($this->post->author);

if (is_array($expected)) {
$response->assertLinks($expected);
Expand Down

0 comments on commit 0aef20a

Please sign in to comment.