Skip to content

Commit 1a84c24

Browse files
committed
Merge branch 'release/1.1.0' into main
2 parents 4cac2f1 + 6ac2bfd commit 1a84c24

File tree

8 files changed

+353
-15
lines changed

8 files changed

+353
-15
lines changed

Diff for: CHANGELOG.md

+27-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33
All notable changes to this project will be documented in this file. This project adheres to
44
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
55

6+
## [1.1.0] - 2022-01-03
7+
8+
### Added
9+
10+
- The default JSON:API resource class can now be changed via
11+
the `LaravelJsonApi\Laravel\LaravelJsonApi::defaultResource()` method. This should be set in a service
12+
provider's `register()` method.
13+
- [#127](https://github.com/laravel-json-api/laravel/issues/127) The `JsonApiResource` class now has a
14+
protected `serializeRelation` method that can be used to override the default serialization of relationships if
15+
needed.
16+
- [#111](https://github.com/laravel-json-api/laravel/issues/111) Relationship documents returned by relationship `self`
17+
routes will now include any non-standard links set on the resource relationship in the top-level `links` member.
18+
19+
### Fixed
20+
21+
- [#147](https://github.com/laravel-json-api/laravel/issues/147) Related relationship response now correctly merge the
22+
relationship links into the top-level document links member.
23+
- [#130](https://github.com/laravel-json-api/laravel/issues/130) The `JsonApiResource` now correctly handles conditional
24+
fields when iterating over relationships to find a specific relation.
25+
- [#105](https://github.com/laravel-json-api/laravel/issues/105) The JSON:API document returned by a relationship `self`
26+
route now handles a relationship not existing if it is hidden. Previously an exception was thrown when attempting to
27+
merge relationship links into the document.
28+
- [#111](https://github.com/laravel-json-api/laravel/issues/111) Relationship documents now handle a relationship that
29+
does not have one or both of the `self` and `related` relationship links.
30+
631
## [1.0.1] - 2021-12-08
732

833
### Changed
@@ -13,8 +38,8 @@ All notable changes to this project will be documented in this file. This projec
1338
### Fixed
1439

1540
- [#139](https://github.com/laravel-json-api/laravel/issues/139) Fix the `WhereHas` and `WhereDoesntHave` filters.
16-
Previously these were not iterating over the filters from the correct resource schema - they were iterating over
17-
the filters from the schema to which the relationship belonged. They now correctly iterate over the filters from the
41+
Previously these were not iterating over the filters from the correct resource schema - they were iterating over the
42+
filters from the schema to which the relationship belonged. They now correctly iterate over the filters from the
1843
schema for the resource that is on the inverse side of the relationship.
1944

2045
## [1.0.0] - 2021-07-31

Diff for: composer.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
"require": {
2626
"php": "^7.4|8.0.*",
2727
"ext-json": "*",
28-
"laravel-json-api/core": "^1.0.0",
28+
"laravel-json-api/core": "^1.1",
2929
"laravel-json-api/eloquent": "^1.0.1",
30-
"laravel-json-api/encoder-neomerx": "^1.0.0",
31-
"laravel-json-api/exceptions": "^1.0.0",
32-
"laravel-json-api/spec": "^1.0.0",
33-
"laravel-json-api/validation": "^1.0.0",
30+
"laravel-json-api/encoder-neomerx": "^1.1",
31+
"laravel-json-api/exceptions": "^1.0",
32+
"laravel-json-api/spec": "^1.0",
33+
"laravel-json-api/validation": "^1.0",
3434
"laravel/framework": "^8.30"
3535
},
3636
"require-dev": {

Diff for: src/LaravelJsonApi.php

+14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use InvalidArgumentException;
2424
use LaravelJsonApi\Core\Auth\AuthorizerResolver;
2525
use LaravelJsonApi\Core\Query\Custom\ExtendedQueryParameters;
26+
use LaravelJsonApi\Core\Resources\ResourceResolver;
2627
use LaravelJsonApi\Eloquent\Resources\Relation;
2728
use LaravelJsonApi\Laravel\Http\Requests\RequestResolver;
2829

@@ -58,6 +59,19 @@ public static function defaultAuthorizer(string $authorizerClass): self
5859
return new self();
5960
}
6061

62+
/**
63+
* Set the default resource class.
64+
*
65+
* @param string $resourceClass
66+
* @return LaravelJsonApi
67+
*/
68+
public static function defaultResource(string $resourceClass): self
69+
{
70+
ResourceResolver::useDefault($resourceClass);
71+
72+
return new self();
73+
}
74+
6175
/**
6276
* Register a HTTP query class for the supplied resource type or types.
6377
*

Diff for: tests/dummy/tests/Api/V1/Posts/ReadAuthorTest.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ public function test(): void
5151
$response = $this
5252
->withoutExceptionHandling()
5353
->jsonApi('users')
54-
->get(url('/api/v1/posts', [$this->post, 'author']));
54+
->get($related = url('/api/v1/posts', [$this->post, 'author']));
5555

56-
$response->assertFetchedOneExact($expected);
56+
$response->assertFetchedOneExact($expected)->assertLinks([
57+
'self' => url('/api/v1/posts', [$this->post, 'relationships', 'author']),
58+
'related' => $related,
59+
]);
5760
}
5861

5962
public function testFilterMatches(): void

Diff for: tests/dummy/tests/Api/V1/Posts/ReadCommentsTest.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,16 @@ public function test(): void
5656
$response = $this
5757
->withoutExceptionHandling()
5858
->jsonApi('comments')
59-
->get(url('/api/v1/posts', [$this->post, 'comments']));
59+
->get($related = url('/api/v1/posts', [$this->post, 'comments']));
6060

61-
$response->assertFetchedMany($expected)->assertExactMeta([
62-
'count' => 3,
63-
]);
61+
$links = [
62+
'self' => url('/api/v1/posts', [$this->post, 'relationships', 'comments']),
63+
'related' => $related,
64+
];
65+
66+
$response->assertFetchedMany($expected)
67+
->assertLinks($links)
68+
->assertExactMeta(['count' => 3]);
6469
}
6570

6671
public function testPaginated(): void

Diff for: tests/dummy/tests/Api/V1/Posts/ReadTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public function test(): void
3737
->withoutExceptionHandling()
3838
->jsonApi()
3939
->expects('posts')
40-
->get(url('/api/v1/posts', $expected['id']));
40+
->get($self = url('/api/v1/posts', $expected['id']));
4141

42-
$response->assertFetchedOneExact($expected);
42+
$response->assertFetchedOneExact($expected)->assertLinks(compact('self'));
4343
}
4444

4545
public function testIncludeAuthorAndTags(): void
+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
/*
3+
* Copyright 2022 Cloud Creativity Limited
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
declare(strict_types=1);
19+
20+
namespace LaravelJsonApi\Laravel\Tests\Acceptance\Relationships;
21+
22+
use App\JsonApi\V1\Posts\PostSchema;
23+
use App\Models\Post;
24+
use App\Models\Tag;
25+
use Closure;
26+
use LaravelJsonApi\Core\Facades\JsonApi;
27+
use LaravelJsonApi\Laravel\Facades\JsonApiRoute;
28+
use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController;
29+
use LaravelJsonApi\Laravel\Tests\Acceptance\TestCase;
30+
use function url;
31+
32+
class ToManyLinksTest extends TestCase
33+
{
34+
35+
/**
36+
* @var PostSchema
37+
*/
38+
private PostSchema $schema;
39+
40+
/**
41+
* @var Post
42+
*/
43+
private Post $post;
44+
45+
/**
46+
* @var Tag
47+
*/
48+
private Tag $tag;
49+
50+
/**
51+
* @return void
52+
*/
53+
protected function setUp(): void
54+
{
55+
parent::setUp();
56+
57+
JsonApiRoute::server('v1')->prefix('api/v1')->resources(function ($server) {
58+
$server->resource('posts', JsonApiController::class)->relationships(function ($relationships) {
59+
$relationships->hasMany('tags');
60+
});
61+
});
62+
63+
$this->schema = JsonApi::server('v1')->schemas()->schemaFor('posts');
64+
$this->post = Post::factory()->create();
65+
$this->post->tags()->attach($this->tag = Tag::factory()->create());
66+
}
67+
68+
/**
69+
* @return array[]
70+
*/
71+
public function scenarioProvider(): array
72+
{
73+
return [
74+
'hidden' => [
75+
static function (PostSchema $schema) {
76+
$schema->relationship('tags')->hidden();
77+
return null;
78+
},
79+
],
80+
'no links' => [
81+
static function (PostSchema $schema) {
82+
$schema->relationship('tags')->serializeUsing(
83+
static fn($relation) => $relation->withoutLinks()
84+
);
85+
return null;
86+
},
87+
],
88+
'no self link' => [
89+
static function (PostSchema $schema, Post $post) {
90+
$schema->relationship('tags')->serializeUsing(
91+
static fn($relation) => $relation->withoutSelfLink()
92+
);
93+
return ['related' => url('/api/v1/posts', [$post, 'tags'])];
94+
},
95+
],
96+
'no related link' => [
97+
static function (PostSchema $schema, Post $post) {
98+
$schema->relationship('tags')->serializeUsing(
99+
static fn($relation) => $relation->withoutRelatedLink()
100+
);
101+
return ['self' => url('/api/v1/posts', [$post, 'relationships', 'tags'])];
102+
},
103+
],
104+
];
105+
}
106+
107+
/**
108+
* @param Closure $scenario
109+
* @return void
110+
* @dataProvider scenarioProvider
111+
*/
112+
public function testRelated(Closure $scenario): void
113+
{
114+
$expected = $scenario($this->schema, $this->post);
115+
116+
$response = $this
117+
->withoutExceptionHandling()
118+
->jsonApi('tags')
119+
->get(url('/api/v1/posts', [$this->post, 'tags']));
120+
121+
$response->assertFetchedMany([$this->tag]);
122+
123+
if (is_array($expected)) {
124+
$response->assertLinks($expected);
125+
}
126+
}
127+
128+
/**
129+
* @param Closure $scenario
130+
* @return void
131+
* @dataProvider scenarioProvider
132+
*/
133+
public function testSelf(Closure $scenario): void
134+
{
135+
$expected = $scenario($this->schema, $this->post);
136+
137+
$response = $this
138+
->withoutExceptionHandling()
139+
->jsonApi('tags')
140+
->get(url('/api/v1/posts', [$this->post, 'relationships', 'tags']));
141+
142+
$response->assertFetchedToMany([$this->tag]);
143+
144+
if (is_array($expected)) {
145+
$response->assertLinks($expected);
146+
}
147+
}
148+
149+
}

0 commit comments

Comments
 (0)