From c37feaf01223f3caa28d2ab2a9ba2930bd7a121b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Sun, 16 Mar 2014 14:43:56 +0100 Subject: [PATCH] Add extraction constants --- src/ZfrRest/Resource/ResourceInterface.php | 7 + .../View/Renderer/DefaultResourceRenderer.php | 11 +- .../Resource/Metadata/Annotation/User.php | 6 +- .../Renderer/DefaultResourceRendererTest.php | 141 ++++++++++++++++++ 4 files changed, 157 insertions(+), 8 deletions(-) diff --git a/src/ZfrRest/Resource/ResourceInterface.php b/src/ZfrRest/Resource/ResourceInterface.php index be81358..b85d885 100755 --- a/src/ZfrRest/Resource/ResourceInterface.php +++ b/src/ZfrRest/Resource/ResourceInterface.php @@ -26,6 +26,13 @@ */ interface ResourceInterface { + /** + * Extraction constants that define how extraction associations are rendered + */ + const ASSOCIATION_EXTRACTION_NONE = 'NONE'; + const ASSOCIATION_EXTRACTION_EMBED = 'EMBED'; + const ASSOCIATION_EXTRACTION_ID = 'ID'; + /** * Get the resource metadata * diff --git a/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php b/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php index e13302c..1a6a0cd 100644 --- a/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php +++ b/src/ZfrRest/View/Renderer/DefaultResourceRenderer.php @@ -20,6 +20,7 @@ use Zend\Paginator\Paginator; use Zend\Stdlib\Hydrator\HydratorPluginManager; +use ZfrRest\Exception\RuntimeException; use ZfrRest\Resource\Metadata\ResourceMetadataFactory; use ZfrRest\Resource\Metadata\ResourceMetadataInterface; use ZfrRest\Resource\Resource; @@ -62,7 +63,7 @@ public function __construct( public function render($nameOrModel, $values = null) { if (!$nameOrModel instanceof ResourceModel) { - return; + throw new RuntimeException('Resource renderer expect a ResourceModel instance'); } $resource = $nameOrModel->getResource(); @@ -80,7 +81,7 @@ public function render($nameOrModel, $values = null) $payload = $this->renderItem($data, $resourceMetadata); } - $payload = array_merge($payload, $this->renderMeta($resource)); + $payload = array_merge($this->renderMeta($resource), $payload); return $payload; } @@ -129,7 +130,7 @@ protected function renderAssociations(array $data, ResourceMetadataInterface $re $extractionStrategy = $associationMetadata['extraction']; // If set to NONE, we don't even want the association to be in the payload - if ($extractionStrategy === 'NONE') { + if ($extractionStrategy === ResourceInterface::ASSOCIATION_EXTRACTION_NONE) { unset($data[$association]); continue; } @@ -168,7 +169,7 @@ protected function renderAssociation($object, $extractionStrategy, $isCollection $association = null; switch($extractionStrategy) { - case 'ID': + case ResourceInterface::ASSOCIATION_EXTRACTION_ID: $identifiers = []; foreach ($object as $datum) { @@ -179,7 +180,7 @@ protected function renderAssociation($object, $extractionStrategy, $isCollection $association = $identifiers; break; - case 'EMBED': + case ResourceInterface::ASSOCIATION_EXTRACTION_EMBED: $embedded = []; foreach ($object as $datum) { diff --git a/tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/User.php b/tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/User.php index 03f6148..a90312a 100644 --- a/tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/User.php +++ b/tests/ZfrRestTest/Asset/Resource/Metadata/Annotation/User.php @@ -49,7 +49,7 @@ class User * @ORM\OneToMany(targetEntity="Tweet") * @REST\Association(extraction="ID") */ - protected $tweets; + //protected $tweets; public function __construct() { @@ -116,8 +116,8 @@ public function addTweet(Tweet $tweet) /** * @return ArrayCollection */ - public function getTweets() + /*public function getTweets() { return $this->tweets; - } + }*/ } diff --git a/tests/ZfrRestTest/View/Renderer/DefaultResourceRendererTest.php b/tests/ZfrRestTest/View/Renderer/DefaultResourceRendererTest.php index 424d975..dc988b5 100644 --- a/tests/ZfrRestTest/View/Renderer/DefaultResourceRendererTest.php +++ b/tests/ZfrRestTest/View/Renderer/DefaultResourceRendererTest.php @@ -149,4 +149,145 @@ public function testCanRenderSingleResourceWithAssociationAsEmbed() $this->assertEquals($expectedPayload, $payload); } + + public function testCanRenderCollectionResourceWithoutAssociation() + { + $address1 = new Address(); + $address2 = new Address(); + + $user1 = new User(); + $user1->setId(2); + $user1->setUsername('bakura'); + $user1->setAddress($address1); + + $user2 = new User(); + $user2->setId(3); + $user2->setUsername('ocramius'); + $user2->setAddress($address2); + + $metadata = $this->resourceMetadataFactory->getMetadataForClass( + 'ZfrRestTest\Asset\Resource\Metadata\Annotation\User' + ); + + // In this test, we enforce that association extraction is set to NONE + $metadata->propertyMetadata['associations']['address']['extraction'] = 'NONE'; + + $resourceModel = new ResourceModel(new Resource([$user1, $user2], $metadata)); + $payload = $this->resourceRenderer->render($resourceModel); + + $expectedPayload = [ + 'items' => [ + [ + 'id' => 2, + 'username' => 'bakura' + ], + [ + 'id' => 3, + 'username' => 'ocramius' + ] + ] + ]; + + $this->assertEquals($expectedPayload, $payload); + } + + public function testCanRenderCollectionResourceWithAssociationAsId() + { + $address1 = new Address(); + $address1->setId(45); + + $address2 = new Address(); + $address2->setId(344); + + $user1 = new User(); + $user1->setId(2); + $user1->setUsername('bakura'); + $user1->setAddress($address1); + + $user2 = new User(); + $user2->setId(3); + $user2->setUsername('ocramius'); + $user2->setAddress($address2); + + $metadata = $this->resourceMetadataFactory->getMetadataForClass( + 'ZfrRestTest\Asset\Resource\Metadata\Annotation\User' + ); + + // In this test, we enforce that association extraction is set to ID + $metadata->propertyMetadata['associations']['address']['extraction'] = 'ID'; + + $resourceModel = new ResourceModel(new Resource([$user1, $user2], $metadata)); + $payload = $this->resourceRenderer->render($resourceModel); + + $expectedPayload = [ + 'items' => [ + [ + 'id' => 2, + 'username' => 'bakura', + 'address' => 45 + ], + [ + 'id' => 3, + 'username' => 'ocramius', + 'address' => 344 + ] + ] + ]; + + $this->assertEquals($expectedPayload, $payload); + } + + public function testCanRenderCollectionResourceWithAssociationAsEmbed() + { + $address1 = new Address(); + $address1->setId(45); + $address1->setCountry('France'); + + $address2 = new Address(); + $address2->setId(344); + $address2->setCountry('Italia'); + + $user1 = new User(); + $user1->setId(2); + $user1->setUsername('bakura'); + $user1->setAddress($address1); + + $user2 = new User(); + $user2->setId(3); + $user2->setUsername('ocramius'); + $user2->setAddress($address2); + + $metadata = $this->resourceMetadataFactory->getMetadataForClass( + 'ZfrRestTest\Asset\Resource\Metadata\Annotation\User' + ); + + // In this test, we enforce that association extraction is set to EMBED + $metadata->propertyMetadata['associations']['address']['extraction'] = 'EMBED'; + + $resourceModel = new ResourceModel(new Resource([$user1, $user2], $metadata)); + $payload = $this->resourceRenderer->render($resourceModel); + + $expectedPayload = [ + 'items' => [ + [ + 'id' => 2, + 'username' => 'bakura', + 'address' => [ + 'id' => 45, + 'country' => 'France' + ] + ], + [ + 'id' => 3, + 'username' => 'ocramius', + 'address' => [ + 'id' => 344, + 'country' => 'Italia' + ] + ] + ] + ]; + + $this->assertEquals($expectedPayload, $payload); + } }