Skip to content

Commit 01f5c61

Browse files
committed
test: unit json-api-collection
1 parent 752481b commit 01f5c61

File tree

4 files changed

+166
-13
lines changed

4 files changed

+166
-13
lines changed

src/JsonApiCollection.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
namespace Ark4ne\JsonApi\Resource;
44

55
use Ark4ne\JsonApi\Resource\Concerns\AsRelationship;
6+
use Illuminate\Http\Resources\Json\JsonResource;
67
use Illuminate\Http\Resources\Json\ResourceCollection;
8+
use Illuminate\Support\Arr;
79

810
class JsonApiCollection extends ResourceCollection implements Resourceable
911
{
@@ -14,8 +16,8 @@ class JsonApiCollection extends ResourceCollection implements Resourceable
1416
/**
1517
* Create a new anonymous resource collection.
1618
*
17-
* @param mixed $resource
18-
* @param string $collects
19+
* @param mixed $resource
20+
* @param class-string $collects
1921
*
2022
* @return void
2123
*/
@@ -30,15 +32,19 @@ public function toArray($request, bool $minimal = false): array
3032
{
3133
$data = [];
3234

35+
$this->with = collect($this->with)->toArray();
3336
foreach ($this->collection as $resource) {
3437
$data[] = $resource->toArray($request, $minimal);
3538

36-
if (!$minimal) {
37-
$with = $resource->with($request);
39+
if ($resource instanceof JsonResource) {
40+
$with = collect($resource->with($request))->toArray();
41+
if ($minimal) {
42+
unset($with['included']);
43+
}
3844
foreach ($with as $key => $value) {
39-
$this->with[$key] = array_merge(
45+
$this->with[$key] = array_merge_recursive(
4046
$this->with[$key] ?? [],
41-
collect($value)->all()
47+
$value
4248
);
4349
}
4450
}
@@ -50,10 +56,16 @@ public function toArray($request, bool $minimal = false): array
5056
public function with($request)
5157
{
5258
return collect($this->with)
53-
->map(static fn($value) => is_iterable($value)
54-
? collect($value)->unique()->all()
55-
: $value)
59+
->map(static function ($value) {
60+
if (is_iterable($value)) {
61+
$value = collect($value)->all();
62+
$isAssoc = Arr::isAssoc($value);
63+
$value = array_unique($value, SORT_REGULAR);
64+
return $isAssoc ? $value : array_values($value);
65+
}
66+
return $value;
67+
})
5668
->filter()
57-
->all();
69+
->toArray();
5870
}
5971
}

tests/Support/Stub.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Test\Support;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Stub
8+
{
9+
public static function model(array $attributes): Model
10+
{
11+
return new class($attributes) extends Model {
12+
public function __construct(array $attributes = [])
13+
{
14+
$this->fillable = array_keys($attributes);
15+
parent::__construct($attributes);
16+
}
17+
};
18+
}
19+
}

tests/Unit/Concerns/RelationshipsTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Http\Request;
1111
use Illuminate\Http\Resources\Json\JsonResource;
1212
use Test\Support\Reflect;
13+
use Test\Support\Stub;
1314
use Test\TestCase;
1415

1516
class RelationshipsTest extends TestCase
@@ -220,9 +221,7 @@ public function testRequestedRelationshipsTwoDepthInclude()
220221

221222
public function testRequestedRelationshipsWithMissingValue()
222223
{
223-
$model = new class(['id' => 1]) extends Model {
224-
protected $fillable = ['id'];
225-
};
224+
$model = Stub::model(['id' => 1]);
226225

227226
Reflect::set($model, 'relations', ['loadedRelation' => (object)['id' => 3]]);
228227

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<?php
2+
3+
namespace Test\Unit;
4+
5+
use Ark4ne\JsonApi\Resource\JsonApiCollection;
6+
use Ark4ne\JsonApi\Resource\Resourceable;
7+
use Illuminate\Database\Eloquent\Model;
8+
use Illuminate\Http\Request;
9+
use Illuminate\Http\Resources\Json\JsonResource;
10+
use Test\Support\Stub;
11+
use Test\TestCase;
12+
13+
class JsonApiCollectionTest extends TestCase
14+
{
15+
public function testToArrayBasic()
16+
{
17+
foreach (range(1, 3) as $idx) {
18+
$models[] = Stub::model(['id' => $idx]);
19+
}
20+
21+
$collection = new class(collect($models), null) extends JsonApiCollection {
22+
};
23+
24+
$request = new Request();
25+
26+
$collect = [
27+
['id' => 1],
28+
['id' => 2],
29+
['id' => 3],
30+
];
31+
$this->assertEquals($collect, $collection->toArray($request));
32+
$this->assertEquals([], $collection->with($request));
33+
$this->assertEquals([
34+
'data' => $collect
35+
], $collection->toResponse($request)->getData(true));
36+
}
37+
38+
public function testToArrayResource()
39+
{
40+
foreach (range(1, 3) as $idx) {
41+
$resources[] = $this->getResource(Stub::model(['id' => $idx]));
42+
}
43+
44+
$collection = new class(collect($resources), null) extends JsonApiCollection {
45+
};
46+
47+
$request = new Request();
48+
49+
$collect = [
50+
['type' => 'my-model', 'id' => 1],
51+
['type' => 'my-model', 'id' => 2],
52+
['type' => 'my-model', 'id' => 3],
53+
];
54+
$this->assertEquals($collect, $collection->toArray($request));
55+
$this->assertEquals([
56+
'meta' => ['foo' => ['bar-1', 'bar-2', 'bar-3']],
57+
'included' => $collect
58+
], $collection->with($request));
59+
60+
$collection->with = [];
61+
$this->assertEquals([
62+
'data' => $collect,
63+
'meta' => ['foo' => ['bar-1', 'bar-2', 'bar-3']],
64+
'included' => $collect
65+
], $collection->toResponse($request)->getData(true));
66+
}
67+
68+
public function testToArrayResourceMinimal()
69+
{
70+
foreach (range(1, 3) as $idx) {
71+
$resources[] = $this->getResource(Stub::model(['id' => $idx]));
72+
}
73+
74+
$collection = new class(collect($resources), null) extends JsonApiCollection {
75+
public function toArray($request, bool $minimal = false): array
76+
{
77+
$this->with = ['other' => 'slug'];
78+
return parent::toArray($request, true);
79+
}
80+
};
81+
82+
$request = new Request();
83+
84+
$collect = [
85+
['type' => 'my-model', 'id' => 1],
86+
['type' => 'my-model', 'id' => 2],
87+
['type' => 'my-model', 'id' => 3],
88+
];
89+
$this->assertEquals($collect, $collection->toArray($request, true));
90+
$this->assertEquals([
91+
'meta' => [
92+
'foo' => ['bar-1', 'bar-2', 'bar-3']
93+
],
94+
'other' => 'slug'
95+
], $collection->with($request));
96+
$collection->with = [];
97+
$this->assertEquals([
98+
'data' => $collect,
99+
'meta' => ['foo' => ['bar-1', 'bar-2', 'bar-3']],
100+
'other' => 'slug'
101+
], $collection->toResponse($request)->getData(true));
102+
}
103+
104+
private function getResource(Model $model)
105+
{
106+
return new class($model) extends JsonResource implements Resourceable {
107+
public function toArray($request, bool $minimal = false): array
108+
{
109+
$this->with['bar'] = [];
110+
$this->with['meta']['foo'] = "bar-{$this->id}";
111+
$this->with['included'][] = [
112+
'type' => 'my-model',
113+
'id' => $this->id,
114+
] + $this->resource->toArray();
115+
116+
return [
117+
'type' => 'my-model',
118+
'id' => $this->id,
119+
];
120+
}
121+
};
122+
}
123+
}

0 commit comments

Comments
 (0)