| 
 | 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' => "« 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 »",  | 
 | 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 | +}  | 
0 commit comments