Skip to content

Commit 048f189

Browse files
committed
Throw a ValidationException when document contains duplicate resources
1 parent f23b056 commit 048f189

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99
### Changed
1010

1111
* Reworded `ValidationException` messages to align them with the wordings used in the specification.
12+
* `DocumentParser` throws a `ValidationException` when it encounters duplicate resources.
1213

1314
## [1.0.0-beta.3] - 2019-09-30
1415

src/Parsers/DocumentParser.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ private function getDocument($data): DocumentInterface
160160
$allItems = Collection::wrap($document->getData())
161161
->concat($document->getIncluded());
162162

163+
$duplicateItems = $allItems->duplicates(
164+
function (ItemInterface $item) {
165+
return $this->getItemKey($item);
166+
}
167+
);
168+
169+
if ($duplicateItems->isNotEmpty()) {
170+
throw new ValidationException(sprintf('Resources MUST be unique based on their `type` and `id`, %d duplicate(s) found.', $duplicateItems->count()));
171+
}
172+
163173
$this->linkRelationships($allItems);
164174

165175
return $document;
@@ -170,8 +180,7 @@ private function getDocument($data): DocumentInterface
170180
*/
171181
private function linkRelationships(Collection $items): void
172182
{
173-
// N.B. We reverse the items to make sure the first item in the collection takes precedence
174-
$keyedItems = $items->reverse()->keyBy(
183+
$keyedItems = $items->keyBy(
175184
function (ItemInterface $item) {
176185
return $this->getItemKey($item);
177186
}

tests/Parsers/DocumentParserTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,42 @@ public function provideInvalidIncluded(): array
180180
];
181181
}
182182

183+
/**
184+
* @test
185+
*/
186+
public function it_throws_when_it_finds_duplicate_resources()
187+
{
188+
$parser = $this->getDocumentParser();
189+
190+
$this->expectException(ValidationException::class);
191+
$this->expectExceptionMessage('Resources MUST be unique based on their `type` and `id`, 1 duplicate(s) found.');
192+
193+
$parser->parse(
194+
json_encode(
195+
[
196+
'data' => [
197+
[
198+
'type' => 'master',
199+
'id' => '1',
200+
'attributes' => [
201+
'foo' => 'bar',
202+
],
203+
],
204+
],
205+
'included' => [
206+
[
207+
'type' => 'master',
208+
'id' => '1',
209+
'attributes' => [
210+
'foo' => 'bar',
211+
],
212+
],
213+
],
214+
]
215+
)
216+
);
217+
}
218+
183219
/**
184220
* @test
185221
*/

0 commit comments

Comments
 (0)