Skip to content

Commit 1cb8ffb

Browse files
committed
fix(relationship meta): store encoded meta from relationship
1 parent 2d110cd commit 1cb8ffb

File tree

2 files changed

+79
-24
lines changed

2 files changed

+79
-24
lines changed

src/Implementation/Encoding/PhpArrayToRelationshipCollectionEncoder.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use Undabot\JsonApi\Definition\Encoding\PhpArrayToMetaEncoderInterface;
99
use Undabot\JsonApi\Definition\Encoding\PhpArrayToRelationshipCollectionEncoderInterface;
1010
use Undabot\JsonApi\Definition\Model\Resource\Relationship\Data\RelationshipDataInterface;
11+
use Undabot\JsonApi\Definition\Model\Resource\Relationship\Data\ToManyRelationshipDataInterface;
12+
use Undabot\JsonApi\Definition\Model\Resource\Relationship\Data\ToOneRelationshipDataInterface;
1113
use Undabot\JsonApi\Definition\Model\Resource\Relationship\RelationshipCollectionInterface;
1214
use Undabot\JsonApi\Implementation\Encoding\Exception\JsonApiEncodingException;
1315
use Undabot\JsonApi\Implementation\Model\Resource\Relationship\Data\ToManyRelationshipData;
@@ -59,20 +61,30 @@ public function encode(array $relationships): RelationshipCollectionInterface
5961
private function decodeRelationship(string $relationshipName, array $relationshipValue): Relationship
6062
{
6163
$relationshipData = null;
64+
$relationshipMeta = null;
6265
if (true === \array_key_exists('data', $relationshipValue)) {
6366
$relationshipData = $this->parseRelationshipData($relationshipValue['data']);
67+
if ($relationshipData instanceof ToOneRelationshipDataInterface) {
68+
if (true === \array_key_exists('meta', $relationshipValue['data'])) {
69+
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipValue['data']['meta']);
70+
}
71+
} elseif ($relationshipData instanceof ToManyRelationshipDataInterface) {
72+
$relationshipMetas = [];
73+
foreach ($relationshipValue['data'] as $relationshipDatum) {
74+
if (true === \array_key_exists('meta', $relationshipDatum)) {
75+
$relationshipMetas[] = $relationshipDatum['meta'];
76+
}
77+
}
78+
79+
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipMetas);
80+
}
6481
}
6582

6683
$relationshipLinks = null;
6784
if (true === \array_key_exists('links', $relationshipValue)) {
6885
$relationshipLinks = $this->phpArrayToLinkCollectionEncoder->encode($relationshipValue['links']);
6986
}
7087

71-
$relationshipMeta = null;
72-
if (true === \array_key_exists('meta', $relationshipValue)) {
73-
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipValue['meta']);
74-
}
75-
7688
return new Relationship(
7789
$relationshipName,
7890
$relationshipLinks,
@@ -84,7 +96,7 @@ private function decodeRelationship(string $relationshipName, array $relationshi
8496
/**
8597
* @throws JsonApiEncodingException
8698
*/
87-
private function parseRelationshipData(?array $resourceLinkage): ?RelationshipDataInterface
99+
private function parseRelationshipData(?array $resourceLinkage): RelationshipDataInterface
88100
{
89101
try {
90102
ValidResourceLinkageAssertion::assert($resourceLinkage);
@@ -114,7 +126,7 @@ private function parseRelationshipData(?array $resourceLinkage): ?RelationshipDa
114126
$resourceIdentifier = new ResourceIdentifier(
115127
$resourceLinkage['id'],
116128
$resourceLinkage['type'],
117-
$resourceLinkage['meta'] ?? null
129+
(true === \array_key_exists('meta', $resourceLinkage)) ? $this->phpArrayToMetaEncoder->decode($resourceLinkage['meta']) : null,
118130
);
119131

120132
return ToOneRelationshipData::make($resourceIdentifier);
@@ -129,7 +141,7 @@ private function parseResourceIdentifierCollection(array $data): ResourceIdentif
129141
$resourceIdentifiers[] = new ResourceIdentifier(
130142
$datum['id'],
131143
$datum['type'],
132-
$datum['meta'] ?? null
144+
(true === \array_key_exists('meta', $datum)) ? $this->phpArrayToMetaEncoder->decode($datum['meta']) : null,
133145
);
134146
}
135147

tests/Unit/Encoding/PhpArray/Encode/PhpArrayToRelationshipCollectionEncoderTest.php

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,30 @@
55
namespace Undabot\JsonApi\Tests\Unit\Encoding\PhpArray\Encode;
66

77
use PHPUnit\Framework\TestCase;
8-
use Undabot\JsonApi\Definition\Encoding\PhpArrayToLinkCollectionEncoderInterface;
9-
use Undabot\JsonApi\Definition\Encoding\PhpArrayToMetaEncoderInterface;
8+
use Undabot\JsonApi\Definition\Model\Resource\Relationship\RelationshipCollectionInterface;
109
use Undabot\JsonApi\Implementation\Encoding\Exception\JsonApiEncodingException;
10+
use Undabot\JsonApi\Implementation\Encoding\PhpArrayToLinkCollectionEncoder;
11+
use Undabot\JsonApi\Implementation\Encoding\PhpArrayToMetaEncoder;
1112
use Undabot\JsonApi\Implementation\Encoding\PhpArrayToRelationshipCollectionEncoder;
1213
use Undabot\JsonApi\Implementation\Model\Resource\Relationship\Data\ToManyRelationshipData;
1314
use Undabot\JsonApi\Implementation\Model\Resource\Relationship\Relationship;
15+
use Undabot\JsonApi\Implementation\Model\Resource\ResourceIdentifier;
1416

1517
/**
1618
* @internal
17-
* @coversNothing
19+
* @covers \Undabot\JsonApi\Implementation\Encoding\PhpArrayToRelationshipCollectionEncoder
1820
*
1921
* @small
2022
*/
2123
final class PhpArrayToRelationshipCollectionEncoderTest extends TestCase
2224
{
23-
/** @var PhpArrayToRelationshipCollectionEncoder */
25+
/** @var PhpArrayToRelationshipCollectionEncoder $encoder */
2426
private $encoder;
2527

2628
protected function setUp(): void
2729
{
28-
$phpArrayToMetaEncoder = $this->createMock(PhpArrayToMetaEncoderInterface::class);
29-
$phpArrayToLinkCollectionEncoder = $this->createMock(PhpArrayToLinkCollectionEncoderInterface::class);
30+
$phpArrayToMetaEncoder = new PhpArrayToMetaEncoder();
31+
$phpArrayToLinkCollectionEncoder = new PhpArrayToLinkCollectionEncoder();
3032

3133
$this->encoder = new PhpArrayToRelationshipCollectionEncoder(
3234
$phpArrayToMetaEncoder,
@@ -76,20 +78,43 @@ public function testValidRelationshipsArrayIsEncodedToRelationshipsCollection():
7678

7779
$relationshipsCollection = $this->encoder->encode($validRelationshipsArray);
7880

79-
/** @var Relationship singleRelationship */
80-
$singleRelationship = $relationshipsCollection->getRelationshipByName('fakeResourceName');
81-
82-
static::assertCount(1, $relationshipsCollection->getRelationships());
81+
$this->validateRelationship($relationshipsCollection, 'fakeResourceName');
8382

84-
/** @var ToManyRelationshipData relationshipData */
85-
$relationshipData = $singleRelationship->getData();
83+
/** @var ResourceIdentifier $resourceIdentifier */
84+
foreach ($relationshipsCollection->getRelationshipByName('fakeResourceName')->getData()->getData()->getResourceIdentifiers() as $resourceIdentifier) {
85+
static::assertInstanceOf(ResourceIdentifier::class, $resourceIdentifier);
86+
static::assertNull($resourceIdentifier->getMeta());
87+
}
88+
}
8689

87-
static::assertInstanceOf(ToManyRelationshipData::class, $relationshipData);
90+
public function testValidRelationshipsArrayIsEncodedToRelationshipsCollectionWithMetaAttributesGiven(): void
91+
{
92+
$validRelationshipsArray = [
93+
'fakeResourceName' => [
94+
'type' => 'fakeResourceNames',
95+
'data' => [
96+
['id' => 'rand-str-Id-1', 'type' => 'fakeResourceName', 'meta' => []],
97+
['id' => 'rand-str-Id-2', 'type' => 'fakeResourceName', 'meta' => ['foo' => 'bar']],
98+
['id' => 'rand-str-Id-3', 'type' => 'fakeResourceName', 'meta' => ['foo' => ['bar' => 'baz']]],
99+
],
100+
],
101+
];
88102

89-
/** @var ToManyRelationshipData $relationships */
90-
$relationships = $singleRelationship->getData();
103+
$relationshipsCollection = $this->encoder->encode($validRelationshipsArray);
91104

92-
static::assertCount(3, $relationships->getData());
105+
$this->validateRelationship($relationshipsCollection, 'fakeResourceName');
106+
107+
/** @var array<int,ResourceIdentifier> $resourceIdentifiers */
108+
$resourceIdentifiers = $relationshipsCollection->getRelationshipByName('fakeResourceName')->getData()->getData()->getResourceIdentifiers();
109+
$firstResourceIdentifier = $resourceIdentifiers[0] ?? null;
110+
$secondResourceIdentifier = $resourceIdentifiers[1] ?? null;
111+
$thirdResourceIdentifier = $resourceIdentifiers[2] ?? null;
112+
static::assertInstanceOf(ResourceIdentifier::class, $firstResourceIdentifier);
113+
static::assertInstanceOf(ResourceIdentifier::class, $secondResourceIdentifier);
114+
static::assertInstanceOf(ResourceIdentifier::class, $thirdResourceIdentifier);
115+
static::assertSame([], $firstResourceIdentifier->getMeta()->getData());
116+
static::assertSame(['foo' => 'bar'], $secondResourceIdentifier->getMeta()->getData());
117+
static::assertSame(['foo' => ['bar' => 'baz']], $thirdResourceIdentifier->getMeta()->getData());
93118
}
94119

95120
public function testMissingRelationshipTypeRaisesException(): void
@@ -123,4 +148,22 @@ public function testMissingRelationshipIdRaisesException(): void
123148
$this->expectExceptionMessage('Resource identifier must have key `id`');
124149
$this->encoder->encode($invalidRelationshipArray);
125150
}
151+
152+
private function validateRelationship(RelationshipCollectionInterface $relationshipsCollection, string $relationshipName): void
153+
{
154+
/** @var Relationship $singleRelationship */
155+
$singleRelationship = $relationshipsCollection->getRelationshipByName($relationshipName);
156+
157+
static::assertCount(1, $relationshipsCollection->getRelationships());
158+
159+
/** @var ToManyRelationshipData $relationshipData */
160+
$relationshipData = $singleRelationship->getData();
161+
162+
static::assertInstanceOf(ToManyRelationshipData::class, $relationshipData);
163+
164+
/** @var ToManyRelationshipData $relationships */
165+
$relationships = $singleRelationship->getData();
166+
167+
static::assertCount(3, $relationships->getData());
168+
}
126169
}

0 commit comments

Comments
 (0)