8000 Merge branch 'hotfix/0.11.2' · AxonDivisionDev/laravel-json-api@6ea8203 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ea8203

Browse files
committed
Merge branch 'hotfix/0.11.2'
2 parents 94c2f96 + ca34170 commit 6ea8203

File tree

11 files changed

+347
-56
lines changed

11 files changed

+347
-56
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
All notable changes to this project will be documented in this file. This project adheres to
33
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
44

5+
## [0.11.2] - 2017-11-14
6+
7+
### Added
8+
- The host can now be omitted from encoded URLs if needed.
9+
10+
### Changed
11+
- The test response `assertStatus` method now outputs the error messages if the response status is
12+
unexpected and the response has JSON API errors in it. This restores a the behaviour that was present
13+
in `v0.10`.
14+
15+
### Fixed
16+
- Corrected invalid import statement in abstract hydrator stub.
17+
518
## [0.11.1] - 2017-09-26
619

720
### Fixed

docs/api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,14 @@ register routes for your API.
134134

135135
### Host
136136

137-
When processing inbound HTTP requests, the current server host will always be used when encoding JSON API documents.
137+
When processing inbound HTTP requests, the current server host will be used when encoding JSON API documents.
138138

139139
When encoding JSON API documents outside of HTTP requests, we use the `url.host` option from your API's configuration.
140140
If the value is `null`, we default to Laravel's `app.url` config setting. Otherwise, we'll use the value you've
141141
provided.
142142

143+
If you do not want the host to be appended to URLs in the encoded document, set `url.host` to `false`.
144+
143145
### Namespace
144146

145147
The URL namespace is the URL under which all resources for the API are nested. For example, if the namespace is

src/Api/Repository.php

Lines changed: 4 additions & 4 deletions
9E88
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,16 @@ private function normalizeRootNamespace($namespace)
165165
*/
166166
private function normalizeUrl(array $url, $host = null)
167167
{
168+
$prependHost = false !== array_get($url, 'host');
169+
168170
if ($host) {
169171
$url['host'] = $host;
170-
}
171-
172-
if (!array_get($url, 'host')) {
172+
} elseif (!isset($url['host'])) {
173173
$url['host'] = $this->config->get('app.url');
174174
}
175175

176176
return new Url(
177-
(string) $url['host'],
177+
$prependHost ? (string) $url['host'] : '',
178178
(string) array_get($url, 'namespace'),
179179
(string) array_get($url, 'name')
180180
);

src/Testing/TestResponse.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Illuminate\Support\Collection;
1313
use Neomerx\JsonApi\Contracts\Document\DocumentInterface as Keys;
1414
use Neomerx\JsonApi\Contracts\Http\Headers\MediaTypeInterface;
15+
use PHPUnit\Framework\Assert as PHPUnit;
1516
use RuntimeException;
1617

1718
class TestResponse extends BaseTestResponse
@@ -56,6 +57,26 @@ public function assertJsonApiResponse(
5657
return $this;
5758
}
5859

60+
/**
61+
* Assert that the response has the given status code.
62+
*
63+
* @param int $status
64+
* @return $this
65+
*/
66+
public function assertStatus($status)
67+
{
68+
$actual = $this->getStatusCode();
69+
$message = "Expected status code {$status} but received {$actual}";
70+
$content = (array) json_decode((string) $this->getContent(), true);
71+
if (isset($content[Keys::KEYWORD_ERRORS])) {
72+
$message .= " with errors:\n" . json_encode($content, JSON_PRETTY_PRINT);
73+
}
74+
75+
PHPUnit::assertSame($status, $actual, $message);
76+
77+
return $this;
78+
}
79+
5980
/**
6081
* Assert a response with a singular resource in the `data` member.
6182
*

stubs/abstract/hydrator.stub

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
namespace DummyNamespace;
44

55
use CloudCreativity\JsonApi\Contracts\Hydrator\HydratesRelatedInterface;
6-
use CloudCreativity\JsonApi\Contracts\Object\StandardObjectInterface;
76
use CloudCreativity\JsonApi\Hydrator\AbstractHydrator;
87
use CloudCreativity\JsonApi\Hydrator\RelatedHydratorTrait;
8+
use CloudCreativity\Utils\Object\StandardObjectInterface;
99

1010
class Hydrator extends AbstractHydrator implements HydratesRelatedInterface
1111
{

stubs/api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
| detected from the inbound HTTP request. In other circumstances
6868
| (e.g. broadcasting), the host will be taken from the setting here.
6969
| If it is `null`, the `app.url` config setting is used as the default.
70+
| If you set `host` to `false`, the host will never be appended to URLs
71+
| for inbound requests.
7072
|
7173
| The name setting is the prefix for route names within this API.
7274
|

tests/Integration/BroadcastingTest.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,5 @@ public function testBroadcastWith()
1515

1616
$this->assertSame('posts', array_get($data, 'data.type'));
1717
$this->assertEquals($id = $post->getKey(), array_get($data, 'data.id'));
18-
$this->assertEquals("http://localhost/api/v1/posts/$id", array_get($data, 'data.links.self'));
1918
}
2019
}

tests/Integration/Eloquent/PostsTest.php

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,36 +94,9 @@ public function testCreate()
9494
public function testRead()
9595
{
9696
$model = $this->createPost();
97-
/** @var Tag $tag */
98-
$tag = $model->tags()->create(['name' => 'Important']);
99-
100-
$data = [
101-
'type' => 'posts',
102-
'id' => (string) $model->getKey(),
103-
'attributes' => [
104-
'title' => $model->title,
105-
'slug' => $model->slug,
106-
'content' => $model->content,
107-
],
108-
'relationships' => [
109-
'author' => [
110-
'data' => [
111-
'type' => 'users',
112-
'id' => (string) $model->author_id,
113-
],
114-
],
115-
'tags' => [
116-
'data' => [
117-
[
118-
'type' => 'tags',
119-
'id' => (string) $tag->getKey(),
120-
],
121-
],
122-
],
123-
],
124-
];
97+
$model->tags()->create(['name' => 'Important']);;
12598

126-
$this->doRead($model)->assertReadResponse($data);
99+
$this->doRead($model)->assertReadResponse($this->serialize($model));
127100
}
128101

129102
/**
@@ -169,4 +142,42 @@ private function createPost($create = true)
169142

170143
return $create ? $builder->create() : $builder->make();
171144
}
145+
146+
/**
147+
* Get the posts resource that we expect in server responses.
148+
*
149+
* @param Post $model
150+
* @return array
151+
*/
152+
private function serialize(Post $model)
153+
{
154+
return [
155+
'type' => 'posts',
156+
'id' => $id = (string) $model->getKey(),
157+
'attributes' => [
158+
'title' => $model->title,
159+
'slug' => $model->slug,
160+
'content' => $model->content,
161+
],
162+
'relationships' => [
163+
'author' => [
164+
'data' => [
165+
'type' => 'users',
166+
'id' => (string) $model->author_id,
167+
],
168+
],
169+
'tags' => [
170+
'data' => $model->tags->map(function (Tag $tag) {
171+
return ['type' => 'tags', 'id' => (string) $tag->getKey()];
172+
})->all(),
173+
],
174+
'comments' => [
175+
'links' => [
176+
'self' => "http://localhost/api/v1/posts/$id/relationships/comments",
177+
'related' => "http://localhost/api/v1/posts/$id/comments",
178+
],
179+
],
180+
],
181+
];
182+
}
172183
}

tests/Integration/EncodingTest.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
namespace CloudCreativity\LaravelJsonApi\Tests\Integration;
4+
5+
use CloudCreativity\LaravelJsonApi\Routing\ApiGroup;
6+
use CloudCreativity\LaravelJsonApi\Tests\Models\Post;
7+
8+
class EncodingTest extends TestCase
9+
{
10+
11+
/**
12+
* If the URL host is set to `null`, we expect the request host to be prepended to links.
13+
*/
14+
public function testRequestedResourceHasRequestHost()
15+
{
16+
$id = factory(Post::class)->create()->getKey();
17+
config()->set('json-api-default.url.host', null);
18+
19+
$json = $this
20+
->withApiRoutes()
21+
->getJsonApi("http://www.example.com/api/v1/posts/$id")
22+
->json();
23+
24+
$this->assertLinks('http://www.example.com', $id, $json);
25+
}
26+
27+
/**
28+
* If the URL host is set to `false`, we do not expect a host to be prepended to links.
29+
*/
30+
public function testRequestedResourceDoesNotHaveHost()
31+
{
32+
$id = factory(Post::class)->create()->getKey();
33+
config()->set('json-api-default.url.host', false);
34+
35+
$json = $this
36+
->withApiRoutes()
37+
->getJsonApi("http://www.example.com/api/v1/posts/$id")
38+
->json();
39+
40+
$this->assertLinks('', $id, $json);
41+
}
42+
43+
/**
44+
* When encoding outside of a request and the URL host is set to `null`, we expect the
45+
* `app.url` config setting to be used.
46+
*/
47+
public function testSerializedResourceHasAppHost()
48+
{
49+
$post = factory(Post::class)->create();
50+
51+
config()->set('app.url', $host = 'http://www.example.com');
52+
config()->set('json-api-default.url.host', null);
53+
54+
$json = json_api('default')->encoder()->serializeData($post);
55+
$this->assertLinks($host, $post->getKey(), $json);
56+
}
57+
58+
/**
59+
* When encoding outside of a request and the URL host is set to a specified host,
60+
* we expect that to be used.
61+
*/
62+
public function testSerializedResourceHasSpecificHost()
63+
{
64+
$post = factory(Post::class)->create();
65+
66+
config()->set('app.url', 'http://localhost');
67+
config()->set('json-api-default.url.host', $host = 'http://www.example.com');
68+
69+
$json = json_api('default')->encoder()->serializeData($post);
70+
$this->assertLinks($host, $post->getKey(), $json);
71+
}
72+
73+
/**
74+
* When encoding outside of a request and the URL host is set to `false`, we expect
75+
* no host in the serialized data.
76+
*/
77+
public function testSerializedResourceDoesNotHaveAppHost()
78+
{
79+
$post = factory(Post::class)->create();
80+
81+
config()->set('app.url', 'http://www.example.com');
82+
config()->set('json-api-default.url.host', false);
83+
84+
$json = json_api('default')->encoder()->serializeData($post);
85+
$this->assertLinks('', $post->getKey(), $json);
86+
}
87+
88+
/**
89+
* @param $host
90+
* @param $id
91+
* @param array $json
92+
*/
93+
private function assertLinks($host, $id, array $json)
94+
{
95+
$this->assertArraySubset([
96+
'data' => [
97+
'links' => [
98+
'self' => "$host/api/v1/posts/$id",
99+
],
100+
],
101+
], $json);
102+
}
103+
104+
/**
105+
* @return $this
106+
*/
107+
private function withApiRoutes()
108+
{
109+
$this->withDefaultApi([], function (ApiGroup $api) {
110+
$api->resource('posts');
111+
});
112+
113+
return $this;
114+
}
115+
}

0 commit comments

Comments
 (0)
0