Skip to content

Commit c9e2fa6

Browse files
committed
test: whenIncluded
1 parent a7db021 commit c9e2fa6

File tree

7 files changed

+199
-29
lines changed

7 files changed

+199
-29
lines changed
+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
namespace Test\Feature\Comment;
4+
5+
use DateTimeInterface;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Support\Collection;
8+
use Test\app\Http\Resources\PostResource;
9+
use Test\app\Http\Resources\UserResource;
10+
use Test\app\Models\Comment;
11+
use Test\app\Models\Post;
12+
use Test\app\Models\User;
13+
use Test\Feature\FeatureTestCase;
14+
15+
class CollectionTest extends FeatureTestCase
16+
{
17+
public function testIndexBasic()
18+
{
19+
$user = $this->dataSeed();
20+
21+
$response = $this->get("comment");
22+
23+
$response->assertExactJson($this->getJsonResult($user));
24+
}
25+
26+
public function testIndexWithInclude()
27+
{
28+
$user = $this->dataSeed();
29+
30+
$response = $this->get("comment?include=post");
31+
32+
$response->assertExactJson($this->getJsonResult($user, null, ['post']));
33+
}
34+
35+
private function dataSeed()
36+
{
37+
$user = User::factory()->create();
38+
$posts = Post::factory()->for($user)->count(3)->create();
39+
$users = User::factory()->count(9)->create();
40+
foreach ($posts as $post) {
41+
foreach ($users->random(5) as $u) {
42+
Comment::factory()->for($post)->for($u)->create();
43+
}
44+
}
45+
46+
return Comment::all();
47+
}
48+
49+
private function getJsonResult(Collection $comments, ?array $attributes = null, ?array $relationships = null)
50+
{
51+
$request = new Request(array_merge(
52+
($attributes !== null ? ['fields' => ['comment' => implode(',', $attributes)]] : []),
53+
($relationships !== null ? ['include' => implode(',', $relationships)] : []),
54+
));
55+
56+
$data = $comments->map(fn(Comment $comment) => [
57+
'id' => $comment->id,
58+
'type' => 'comment',
59+
'attributes' => array_filter(array_intersect_key([
60+
'content' => $comment->content,
61+
], array_fill_keys($attributes ?? ['content'], true))),
62+
'relationships' => [
63+
'user' => array_filter([
64+
'data' => in_array('user', $relationships ?? [])
65+
? ['type' => 'user', 'id' => $comment->user->id]
66+
: null,
67+
'links' => [
68+
'self' => "https://api.example.com/comment/{$comment->id}/relationships/user",
69+
'related' => "https://api.example.com/comment/{$comment->id}/user",
70+
]
71+
]),
72+
'post' => array_filter([
73+
'data' => in_array('post', $relationships ?? [])
74+
? ['type' => 'post', 'id' => $comment->post->id]
75+
: null,
76+
'links' => [
77+
'self' => "https://api.example.com/comment/{$comment->id}/relationships/post",
78+
'related' => "https://api.example.com/comment/{$comment->id}/post",
79+
]
80+
]),
81+
],
82+
'meta' => [
83+
'created_at' => $comment->created_at->format(DateTimeInterface::ATOM),
84+
'updated_at' => $comment->updated_at->format(DateTimeInterface::ATOM),
85+
],
86+
]);
87+
88+
/** @var Collection $include */
89+
$include = $comments
90+
->map(fn(Comment $comment) => collect()
91+
->merge(
92+
in_array('user', $relationships ?? [])
93+
? [UserResource::make($comment->user)->toArray($request)]
94+
: []
95+
)
96+
->merge(
97+
in_array('post', $relationships ?? [])
98+
? [PostResource::make($comment->post)->toArray($request)]
99+
: []
100+
))
101+
->reduce(fn(Collection $all, Collection $value) => $all->merge($value), collect());
102+
103+
return collect(array_filter([
104+
'data' => $data,
105+
'included' => $include->uniqueStrict()->values()->all(),
106+
"links" => [
107+
"first" => "http://localhost/comment?page=1",
108+
"last" => "http://localhost/comment?page=1",
109+
"next" => null,
110+
"prev" => null
111+
],
112+
"meta" => [
113+
'current_page' => 1,
114+
'from' => 1,
115+
'last_page' => 1,
116+
'links' => [
117+
[
118+
'active' => false,
119+
'label' => "&laquo; Previous",
120+
'url' => null,
121+
],
122+
[
123+
'active' => true,
124+
'label' => '1',
125+
'url' => "http://localhost/comment?page=1",
126+
],
127+
[
128+
'active' => false,
129+
'label' => "Next &raquo;",
130+
'url' => null,
131+
],
132+
],
133+
'path' => 'http://localhost/comment',
134+
'per_page' => 15,
135+
'to' => 15,
136+
'total' => 15,
137+
],
138+
]))
139+
->toArray();
140+
}
141+
}

tests/Feature/FeatureTestCase.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Test\Feature;
4+
5+
use Illuminate\Foundation\Testing\RefreshDatabase;
6+
use Test\Support\UseLocalApp;
7+
use Test\TestCase;
8+
9+
abstract class FeatureTestCase extends TestCase
10+
{
11+
use RefreshDatabase, UseLocalApp;
12+
13+
public function setUp(): void
14+
{
15+
parent::setUp();
16+
$this->useLocalApp();
17+
}
18+
}

tests/Feature/CollectionTest.php renamed to tests/Feature/User/CollectionTest.php

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,19 @@
11
<?php
22

3-
namespace Test\Feature;
3+
namespace Test\Feature\User;
44

55
use DateTimeInterface;
6-
use Illuminate\Foundation\Testing\RefreshDatabase;
76
use Illuminate\Http\Request;
87
use Illuminate\Support\Collection;
98
use Test\app\Http\Resources\CommentResource;
109
use Test\app\Http\Resources\PostResource;
1110
use Test\app\Models\Comment;
1211
use Test\app\Models\Post;
1312
use Test\app\Models\User;
14-
use Test\Support\UseLocalApp;
15-
use Test\TestCase;
13+
use Test\Feature\FeatureTestCase;
1614

17-
class CollectionTest extends TestCase
15+
class CollectionTest extends FeatureTestCase
1816
{
19-
use RefreshDatabase, UseLocalApp;
20-
21-
public function setUp(): void
22-
{
23-
parent::setUp();
24-
$this->useLocalApp();
25-
}
26-
2717
public function testGetIndex()
2818
{
2919
$users = $this->dataSeed();

tests/Feature/ResourceTest.php renamed to tests/Feature/User/ResourceTest.php

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
<?php
22

3-
namespace Test\Feature;
3+
namespace Test\Feature\User;
44

55
use DateTimeInterface;
6-
use Illuminate\Foundation\Testing\RefreshDatabase;
76
use Illuminate\Http\Request;
87
use Test\app\Http\Resources\CommentResource;
98
use Test\app\Http\Resources\PostResource;
109
use Test\app\Models\Comment;
1110
use Test\app\Models\Post;
1211
use Test\app\Models\User;
13-
use Test\Support\UseLocalApp;
14-
use Test\TestCase;
12+
use Test\Feature\FeatureTestCase;
1513

16-
class ResourceTest extends TestCase
14+
class ResourceTest extends FeatureTestCase
1715
{
18-
use RefreshDatabase, UseLocalApp;
19-
20-
public function setUp(): void
21-
{
22-
parent::setUp();
23-
$this->useLocalApp();
24-
}
25-
2616
public function testShowBasic()
2717
{
2818
$user = $this->dataSeed();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Test\app\Http\Controllers;
4+
5+
use Illuminate\Routing\Controller;
6+
use Test\app\Http\Resources\CommentResource;
7+
use Test\app\Models\Comment;
8+
9+
class CommentController extends Controller
10+
{
11+
use AsApiController;
12+
13+
protected function getModelClass(): string
14+
{
15+
return Comment::class;
16+
}
17+
18+
protected function getResourceClass(): string
19+
{
20+
return CommentResource::class;
21+
}
22+
}

tests/app/Http/Resources/CommentResource.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,16 @@ protected function toResourceMeta(Request $request): ?iterable
2929
protected function toRelationships(Request $request): iterable
3030
{
3131
return [
32-
'user' => fn() => new UserResource($this->user),
33-
'post' => fn() => new PostResource($this->post),
32+
'user' => fn() => UserResource::make($this->whenIncluded($request, 'user', $this->user))
33+
->asRelationship([
34+
'self' => "https://api.example.com/comment/{$this->id}/relationships/user",
35+
'related' => "https://api.example.com/comment/{$this->id}/user",
36+
]),
37+
'post' => fn() => PostResource::make($this->whenIncluded($request, 'post', $this->post))
38+
->asRelationship([
39+
'self' => "https://api.example.com/comment/{$this->id}/relationships/post",
40+
'related' => "https://api.example.com/comment/{$this->id}/post",
41+
]),
3442
];
3543
}
3644
}

tests/app/routes.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
use Illuminate\Support\Facades\Route;
44
use Test\app\Http\Controllers;
55

6-
Route::apiResource('user', Controllers\UserController::class);
6+
Route::apiResource('user', Controllers\UserController::class)->only(['index', 'show']);
7+
Route::apiResource('comment', Controllers\CommentController::class)->only(['index', 'show']);
78

0 commit comments

Comments
 (0)