Skip to content

Commit f9a0a5d

Browse files
authored
Merge pull request #2 from undabot/fix/relationship-meta
Relationship meta fix
2 parents 2aa9255 + db61609 commit f9a0a5d

File tree

2 files changed

+78
-31
lines changed

2 files changed

+78
-31
lines changed

src/Implementation/Encoding/PhpArrayToRelationshipCollectionEncoder.php

Lines changed: 21 additions & 17 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;
@@ -23,18 +25,10 @@
2325

2426
class PhpArrayToRelationshipCollectionEncoder implements PhpArrayToRelationshipCollectionEncoderInterface
2527
{
26-
/** @var PhpArrayToMetaEncoderInterface */
27-
private $phpArrayToMetaEncoder;
28-
29-
/** @var PhpArrayToLinkCollectionEncoderInterface */
30-
private $phpArrayToLinkCollectionEncoder;
31-
3228
public function __construct(
33-
PhpArrayToMetaEncoderInterface $phpArrayToMetaEncoder,
34-
PhpArrayToLinkCollectionEncoderInterface $phpArrayToLinkCollectionEncoder
29+
private PhpArrayToMetaEncoderInterface $phpArrayToMetaEncoder,
30+
private PhpArrayToLinkCollectionEncoderInterface $phpArrayToLinkCollectionEncoder
3531
) {
36-
$this->phpArrayToMetaEncoder = $phpArrayToMetaEncoder;
37-
$this->phpArrayToLinkCollectionEncoder = $phpArrayToLinkCollectionEncoder;
3832
}
3933

4034
/**
@@ -59,20 +53,30 @@ public function encode(array $relationships): RelationshipCollectionInterface
5953
private function decodeRelationship(string $relationshipName, array $relationshipValue): Relationship
6054
{
6155
$relationshipData = null;
56+
$relationshipMeta = null;
6257
if (true === \array_key_exists('data', $relationshipValue)) {
6358
$relationshipData = $this->parseRelationshipData($relationshipValue['data']);
59+
if ($relationshipData instanceof ToOneRelationshipDataInterface) {
60+
if (true === \array_key_exists('meta', $relationshipValue['data'])) {
61+
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipValue['data']['meta']);
62+
}
63+
} elseif ($relationshipData instanceof ToManyRelationshipDataInterface) {
64+
$relationshipMetas = [];
65+
foreach ($relationshipValue['data'] as $relationshipDatum) {
66+
if (true === \array_key_exists('meta', $relationshipDatum)) {
67+
$relationshipMetas[] = $relationshipDatum['meta'];
68+
}
69+
}
70+
71+
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipMetas);
72+
}
6473
}
6574

6675
$relationshipLinks = null;
6776
if (true === \array_key_exists('links', $relationshipValue)) {
6877
$relationshipLinks = $this->phpArrayToLinkCollectionEncoder->encode($relationshipValue['links']);
6978
}
7079

71-
$relationshipMeta = null;
72-
if (true === \array_key_exists('meta', $relationshipValue)) {
73-
$relationshipMeta = $this->phpArrayToMetaEncoder->decode($relationshipValue['meta']);
74-
}
75-
7680
return new Relationship(
7781
$relationshipName,
7882
$relationshipLinks,
@@ -114,7 +118,7 @@ private function parseRelationshipData(?array $resourceLinkage): RelationshipDat
114118
$resourceIdentifier = new ResourceIdentifier(
115119
$resourceLinkage['id'],
116120
$resourceLinkage['type'],
117-
$resourceLinkage['meta'] ?? null
121+
(true === \array_key_exists('meta', $resourceLinkage)) ? $this->phpArrayToMetaEncoder->decode($resourceLinkage['meta']) : null,
118122
);
119123

120124
return ToOneRelationshipData::make($resourceIdentifier);
@@ -129,7 +133,7 @@ private function parseResourceIdentifierCollection(array $data): ResourceIdentif
129133
$resourceIdentifiers[] = new ResourceIdentifier(
130134
$datum['id'],
131135
$datum['type'],
132-
$datum['meta'] ?? null
136+
(true === \array_key_exists('meta', $datum)) ? $this->phpArrayToMetaEncoder->decode($datum['meta']) : null,
133137
);
134138
}
135139

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

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
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
@@ -24,8 +26,8 @@ final class PhpArrayToRelationshipCollectionEncoderTest extends TestCase
2426

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

3032
$this->encoder = new PhpArrayToRelationshipCollectionEncoder(
3133
$phpArrayToMetaEncoder,
@@ -75,20 +77,43 @@ public function testValidRelationshipsArrayIsEncodedToRelationshipsCollection():
7577

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

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

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

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

88-
/** @var ToManyRelationshipData $relationships */
89-
$relationships = $singleRelationship->getData();
102+
$relationshipsCollection = $this->encoder->encode($validRelationshipsArray);
90103

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

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

0 commit comments

Comments
 (0)