Skip to content

Commit

Permalink
Merge pull request #14 from snellingio/patch-1
Browse files Browse the repository at this point in the history
Fix for included collection with numeric keys
  • Loading branch information
timacdonald authored Jan 26, 2023
2 parents ad2f601 + e9c6f68 commit c42f42a
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/JsonApiResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ public function with($request)
{
return [
'included' => $this->included($request)
->uniqueStrict(fn (JsonApiResource $resource): string => $resource->toUniqueResourceIdentifier($request)),
->uniqueStrict(fn (JsonApiResource $resource): string => $resource->toUniqueResourceIdentifier($request))
->values(),
'jsonapi' => self::serverImplementationResolver()($request),
];
}
Expand Down
3 changes: 2 additions & 1 deletion src/JsonApiResourceCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public function with($request)
'included' => $this->collection
->map(fn (JsonApiResource $resource): Collection => $resource->included($request))
->flatten()
->uniqueStrict(fn (JsonApiResource $resource): string => $resource->toUniqueResourceIdentifier($request)),
->uniqueStrict(fn (JsonApiResource $resource): string => $resource->toUniqueResourceIdentifier($request))
->values(),
'jsonapi' => JsonApiResource::serverImplementationResolver()($request),
];
}
Expand Down
220 changes: 220 additions & 0 deletions tests/Feature/RelationshipsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,226 @@ public function testItFlushesTheRelationshipCache(): void
$this->assertNull($resource->requestedRelationshipsCache());
}

public function testCollectionIncludesDoesntBecomeNumericKeyedObjectAfterFilteringDuplicateRecords(): void
{
$users = [
BasicModel::make([
'id' => 'user-id-1',
'name' => 'user-name-1',
])->setRelation('avatar', BasicModel::make([
'id' => 1,
'url' => 'https://example.com/avatar1.png',
])),
BasicModel::make([
'id' => 'user-id-2',
'name' => 'user-name-2',
])->setRelation('avatar', BasicModel::make([
'id' => 1,
'url' => 'https://example.com/avatar1.png',
])),
BasicModel::make([
'id' => 'user-id-3',
'name' => 'user-name-3',
])->setRelation('avatar', BasicModel::make([
'id' => 2,
'url' => 'https://example.com/avatar2.png',
])),
];
Route::get('test-route', fn () => UserResource::collection($users));

$response = $this->getJson('test-route?include=avatar');

$response->assertOk();
$response->assertExactJson([
'data' => [
[
'id' => 'user-id-1',
'type' => 'basicModels',
'attributes' => [
'name' => 'user-name-1',
],
'relationships' => [
'avatar' => [
'data' => [
'id' => '1',
'type' => 'basicModels',
'meta' => [],
],
'links' => [],
'meta' => [],
],
],
'meta' => [],
'links' => [],
],
[
'id' => 'user-id-2',
'type' => 'basicModels',
'attributes' => [
'name' => 'user-name-2',
],
'relationships' => [
'avatar' => [
'data' => [
'id' => '1',
'type' => 'basicModels',
'meta' => [],
],
'links' => [],
'meta' => [],
],
],
'meta' => [],
'links' => [],
],
[
'id' => 'user-id-3',
'type' => 'basicModels',
'attributes' => [
'name' => 'user-name-3',
],
'relationships' => [
'avatar' => [
'data' => [
'id' => '2',
'type' => 'basicModels',
'meta' => [],
],
'links' => [],
'meta' => [],
],
],
'meta' => [],
'links' => [],
],
],
'jsonapi' => [
'version' => '1.0',
'meta' => [],
],
'included' => [
[
'id' => '1',
'type' => 'basicModels',
'attributes' => [
'url' => 'https://example.com/avatar1.png',
],
'relationships' => [],
'links' => [],
'meta' => [],
],
[
'id' => '2',
'type' => 'basicModels',
'attributes' => [
'url' => 'https://example.com/avatar2.png',
],
'relationships' => [],
'links' => [],
'meta' => [],
],
],
]);
}

public function testSingleResourceIncludesDoesntBecomeNumericKeyedObjectAfterFilteringDuplicateRecords(): void
{
$user = BasicModel::make([
'id' => 1,
'name' => 'user-name-1',
])->setRelation('posts', [
BasicModel::make([
'id' => 2,
'title' => 'Title 1',
'content' => 'Content 1',
])->setRelation('comments', [
BasicModel::make([
'id' => 3,
'content' => 'Comment 1',
])->setRelation('author', BasicModel::make([
'id' => 1,
'name' => 'user-name-1',
])),
]),
BasicModel::make([
'id' => 2,
'title' => 'Title 2',
'content' => 'Content 2',
])->setRelation('comments', new Collection()),
]);

Route::get('test-route', fn () => UserResource::make($user));

$response = $this->getJson('test-route?include=posts,posts.comments,posts.comments.author');

$response->assertOk();
$response->assertExactJson(
[
'data' => [
'id' => '1',
'type' => 'basicModels',
'attributes' => [
'name' => 'user-name-1',
],
'relationships' => [
'posts' => [
'data' => [
[
'id' => '2',
'type' => 'basicModels',
'meta' => [],
],
],
'meta' => [],
'links' => [],
],
],
'meta' => [],
'links' => [],
],
'included' => [
[
'id' => '2',
'type' => 'basicModels',
'attributes' => [
'title' => 'Title 1',
'content' => 'Content 1',
],
'relationships' => [
'comments' => [
'data' => [
[
'id' => '3',
'type' => 'basicModels',
'meta' => [],
],
],
'meta' => [],
'links' => [],
],
],
'meta' => [],
'links' => [],
],
[
'id' => '3',
'type' => 'basicModels',
'attributes' => [
'content' => 'Comment 1',
],
'relationships' => [],
'meta' => [],
'links' => [],
],
],
'jsonapi' => [
'version' => '1.0',
'meta' => [],
],
]
);
}

public function testItRemovesPotentiallyMissingRelationships(): void
{
$user = new BasicModel([
Expand Down

0 comments on commit c42f42a

Please sign in to comment.