diff --git a/features/hal.feature b/features/hal.feature
index 8c65b6ebd0b..08731cb1a7d 100644
--- a/features/hal.feature
+++ b/features/hal.feature
@@ -4,6 +4,15 @@ Feature: HAL support
I need to be able to retrieve valid HAL responses.
@createSchema
+ Scenario: Retrieve the API entrypoint
+ When I add "Accept" header equal to "application/hal+json"
+ And I send a "GET" request to "/"
+ Then the response status code should be 200
+ And the response should be in JSON
+ And the header "Content-Type" should be equal to "application/hal+json"
+ And the JSON node "_links.self.href" should be equal to "/"
+ And the JSON node "_links.dummy.href" should be equal to "/dummies"
+
Scenario: Create a third level
When I add "Content-Type" header equal to "application/json"
And I send a "POST" request to "/third_levels" with body:
diff --git a/src/Action/EntrypointAction.php b/src/Action/EntrypointAction.php
index 202f164e43f..4f9dd391d7f 100644
--- a/src/Action/EntrypointAction.php
+++ b/src/Action/EntrypointAction.php
@@ -11,7 +11,8 @@
namespace ApiPlatform\Core\Action;
-use ApiPlatform\Core\JsonLd\EntrypointBuilderInterface;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
/**
* Generates the API entrypoint.
@@ -20,15 +21,15 @@
*/
final class EntrypointAction
{
- private $entrypointBuilder;
+ private $resourceNameCollectionFactory;
- public function __construct(EntrypointBuilderInterface $entrypointBuilder)
+ public function __construct(ResourceNameCollectionFactoryInterface $resourceNameCollection)
{
- $this->entrypointBuilder = $entrypointBuilder;
+ $this->resourceNameCollectionFactory = $resourceNameCollection;
}
- public function __invoke() : array
+ public function __invoke() : ResourceNameCollection
{
- return $this->entrypointBuilder->getEntrypoint();
+ return $this->resourceNameCollectionFactory->create();
}
}
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/api.xml b/src/Bridge/Symfony/Bundle/Resources/config/api.xml
index 40dbb25b446..4aa2ebfbc93 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/api.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/api.xml
@@ -25,6 +25,8 @@
+ %api_platform.formats%
+
@@ -114,6 +116,10 @@
+
+
+
+
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/hal.xml b/src/Bridge/Symfony/Bundle/Resources/config/hal.xml
index 8c1a411f333..19b17099a87 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/hal.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/hal.xml
@@ -5,13 +5,27 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
jsonhal
+
+
+
+
+
+
+
+
+
+
+ %api_platform.collection.pagination.page_parameter_name%
+
+
+
+
@@ -23,13 +37,6 @@
-
-
-
- %api_platform.collection.pagination.page_parameter_name%
-
-
-
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/hydra.xml b/src/Bridge/Symfony/Bundle/Resources/config/hydra.xml
index 995b0966e6b..4e5607ce539 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/hydra.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/hydra.xml
@@ -5,13 +5,6 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
-
-
-
-
-
-
@@ -49,12 +42,20 @@
+
+
+
+
+
+
+
+
-
+
@@ -82,11 +83,8 @@
-
-
-
-
+
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/routing/hal.xml b/src/Bridge/Symfony/Bundle/Resources/config/routing/api.xml
similarity index 85%
rename from src/Bridge/Symfony/Bundle/Resources/config/routing/hal.xml
rename to src/Bridge/Symfony/Bundle/Resources/config/routing/api.xml
index 8615a58eb6f..0a04cf423c8 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/routing/hal.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/routing/api.xml
@@ -5,8 +5,9 @@
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd">
-
+
api_platform.action.entrypoint
+
1
index
index
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/routing/hydra.xml b/src/Bridge/Symfony/Bundle/Resources/config/routing/hydra.xml
index 2a0c5902210..b877b8254e9 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/routing/hydra.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/routing/hydra.xml
@@ -5,14 +5,6 @@
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd">
-
- api_platform.action.entrypoint
- 1
- jsonld
- index
- index
-
-
api_platform.hydra.action.documentation
1
diff --git a/src/Bridge/Symfony/Bundle/Resources/config/routing/jsonld.xml b/src/Bridge/Symfony/Bundle/Resources/config/routing/jsonld.xml
index b2814ac45d6..ce129f51816 100644
--- a/src/Bridge/Symfony/Bundle/Resources/config/routing/jsonld.xml
+++ b/src/Bridge/Symfony/Bundle/Resources/config/routing/jsonld.xml
@@ -5,14 +5,6 @@
xsi:schemaLocation="http://symfony.com/schema/routing
http://symfony.com/schema/routing/routing-1.0.xsd">
-
- api_platform.action.entrypoint
- 1
- jsonld
- index
- index
-
-
api_platform.jsonld.action.context
1
diff --git a/src/Bridge/Symfony/Routing/ApiLoader.php b/src/Bridge/Symfony/Routing/ApiLoader.php
index 4c066ec0559..b16469b9ce1 100644
--- a/src/Bridge/Symfony/Routing/ApiLoader.php
+++ b/src/Bridge/Symfony/Routing/ApiLoader.php
@@ -40,14 +40,16 @@ final class ApiLoader extends Loader
private $resourceMetadataFactory;
private $resourcePathGenerator;
private $container;
+ private $formats;
- public function __construct(KernelInterface $kernel, ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, ResourcePathNamingStrategyInterface $resourcePathGenerator, ContainerInterface $container)
+ public function __construct(KernelInterface $kernel, ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, ResourcePathNamingStrategyInterface $resourcePathGenerator, ContainerInterface $container, array $formats)
{
$this->fileLoader = new XmlFileLoader(new FileLocator($kernel->locateResource('@ApiPlatformBundle/Resources/config/routing')));
$this->resourceNameCollectionFactory = $resourceNameCollectionFactory;
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->resourcePathGenerator = $resourcePathGenerator;
$this->container = $container;
+ $this->formats = $formats;
}
/**
@@ -57,9 +59,7 @@ public function load($data, $type = null)
{
$routeCollection = new RouteCollection();
- $routeCollection->addCollection($this->fileLoader->load('hal.xml'));
- $routeCollection->addCollection($this->fileLoader->load('jsonld.xml'));
- $routeCollection->addCollection($this->fileLoader->load('hydra.xml'));
+ $this->loadExternalFiles($routeCollection);
if ($this->container->getParameter('api_platform.enable_swagger')) {
$routeCollection->addCollection($this->fileLoader->load('swagger.xml'));
@@ -92,6 +92,21 @@ public function supports($resource, $type = null)
return 'api_platform' === $type;
}
+ /**
+ * Load external files.
+ *
+ * @param RouteCollection $routeCollection
+ */
+ private function loadExternalFiles(RouteCollection $routeCollection)
+ {
+ $routeCollection->addCollection($this->fileLoader->load('api.xml'));
+
+ if (isset($this->formats['jsonld'])) {
+ $routeCollection->addCollection($this->fileLoader->load('jsonld.xml'));
+ $routeCollection->addCollection($this->fileLoader->load('hydra.xml'));
+ }
+ }
+
/**
* Creates and adds a route for the given operation to the route collection.
*
diff --git a/src/EventListener/SerializeListener.php b/src/EventListener/SerializeListener.php
index 6f013e9bad5..2f4b35a7590 100644
--- a/src/EventListener/SerializeListener.php
+++ b/src/EventListener/SerializeListener.php
@@ -14,6 +14,7 @@
use ApiPlatform\Core\Exception\RuntimeException;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\Core\Util\RequestAttributesExtractor;
+use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
@@ -49,17 +50,11 @@ public function onKernelView(GetResponseForControllerResultEvent $event)
return;
}
- if ($request->attributes->get('_api_respond') && !is_object($controllerResult)) {
- if (!$this->serializer instanceof EncoderInterface) {
- throw new RuntimeException('The serializer instance must implements the "%s" interface.', EncoderInterface::class);
- }
-
- $event->setControllerResult($this->serializer->encode($controllerResult, $request->getRequestFormat()));
- }
-
try {
$attributes = RequestAttributesExtractor::extractAttributes($request);
} catch (RuntimeException $e) {
+ $this->serializeRawData($event, $request, $controllerResult);
+
return;
}
@@ -68,4 +63,30 @@ public function onKernelView(GetResponseForControllerResultEvent $event)
$event->setControllerResult($this->serializer->serialize($controllerResult, $request->getRequestFormat(), $context));
}
+
+ /**
+ * Tries to serialize data that are not API resources (e.g. the entrypoint or data returned by a custom controller).
+ *
+ * @param GetResponseForControllerResultEvent $event
+ * @param Request $request
+ * @param object $controllerResult
+ */
+ private function serializeRawData(GetResponseForControllerResultEvent $event, Request $request, $controllerResult)
+ {
+ if (!$request->attributes->get('_api_respond')) {
+ return;
+ }
+
+ if (is_object($controllerResult)) {
+ $event->setControllerResult($this->serializer->serialize($controllerResult, $request->getRequestFormat()));
+
+ return;
+ }
+
+ if (!$this->serializer instanceof EncoderInterface) {
+ throw new RuntimeException('The serializer instance must implements the "%s" interface.', EncoderInterface::class);
+ }
+
+ $event->setControllerResult($this->serializer->encode($controllerResult, $request->getRequestFormat()));
+ }
}
diff --git a/src/Hal/Serializer/ResourceNameCollectionNormalizer.php b/src/Hal/Serializer/ResourceNameCollectionNormalizer.php
new file mode 100644
index 00000000000..b986d79bd33
--- /dev/null
+++ b/src/Hal/Serializer/ResourceNameCollectionNormalizer.php
@@ -0,0 +1,71 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ApiPlatform\Core\Hal\Serializer;
+
+use ApiPlatform\Core\Api\IriConverterInterface;
+use ApiPlatform\Core\Api\UrlGeneratorInterface;
+use ApiPlatform\Core\Exception\InvalidArgumentException;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+
+/**
+ * Normalizes the API entrypoint.
+ *
+ * @author Kévin Dunglas
+ */
+final class ResourceNameCollectionNormalizer implements NormalizerInterface
+{
+ const FORMAT = 'jsonhal';
+
+ private $resourceMetadataFactory;
+ private $iriConverter;
+ private $urlGenerator;
+
+ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator)
+ {
+ $this->resourceMetadataFactory = $resourceMetadataFactory;
+ $this->iriConverter = $iriConverter;
+ $this->urlGenerator = $urlGenerator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function normalize($object, $format = null, array $context = [])
+ {
+ $entrypoint = ['_links' => ['self' => ['href' => $this->urlGenerator->generate('api_entrypoint')]]];
+
+ foreach ($object as $resourceClass) {
+ $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
+
+ if (empty($resourceMetadata->getCollectionOperations())) {
+ continue;
+ }
+ try {
+ $entrypoint['_links'][lcfirst($resourceMetadata->getShortName())]['href'] = $this->iriConverter->getIriFromResourceClass($resourceClass);
+ } catch (InvalidArgumentException $ex) {
+ // Ignore resources without GET operations
+ }
+ }
+
+ return $entrypoint;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsNormalization($data, $format = null)
+ {
+ return self::FORMAT === $format && $data instanceof ResourceNameCollection;
+ }
+}
diff --git a/src/Hydra/ApiDocumentationBuilder.php b/src/Hydra/ApiDocumentationBuilder.php
index 636a7912731..d91375ebb48 100644
--- a/src/Hydra/ApiDocumentationBuilder.php
+++ b/src/Hydra/ApiDocumentationBuilder.php
@@ -248,7 +248,7 @@ public function getApiDocumentation() : array
$doc['hydra:description'] = $this->description;
}
- $doc['hydra:entrypoint'] = $this->urlGenerator->generate('api_hydra_entrypoint');
+ $doc['hydra:entrypoint'] = $this->urlGenerator->generate('api_entrypoint');
$doc['hydra:supportedClass'] = $classes;
return $doc;
diff --git a/src/Hydra/EntrypointBuilder.php b/src/Hydra/Serializer/ResourceNameCollectionNormalizer.php
similarity index 60%
rename from src/Hydra/EntrypointBuilder.php
rename to src/Hydra/Serializer/ResourceNameCollectionNormalizer.php
index 7ff2039af20..245c2341c00 100644
--- a/src/Hydra/EntrypointBuilder.php
+++ b/src/Hydra/Serializer/ResourceNameCollectionNormalizer.php
@@ -9,30 +9,30 @@
* file that was distributed with this source code.
*/
-namespace ApiPlatform\Core\Hydra;
+namespace ApiPlatform\Core\Hydra\Serializer;
use ApiPlatform\Core\Api\IriConverterInterface;
use ApiPlatform\Core\Api\UrlGeneratorInterface;
use ApiPlatform\Core\Exception\InvalidArgumentException;
-use ApiPlatform\Core\JsonLd\EntrypointBuilderInterface;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
-use ApiPlatform\Core\Metadata\Resource\Factory\ResourceNameCollectionFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
/**
- * {@inheritdoc}
+ * Normalizes the API entrypoint.
*
* @author Kévin Dunglas
*/
-final class EntrypointBuilder implements EntrypointBuilderInterface
+final class ResourceNameCollectionNormalizer implements NormalizerInterface
{
- private $resourceNameCollectionFactory;
+ const FORMAT = 'jsonld';
+
private $resourceMetadataFactory;
private $iriConverter;
private $urlGenerator;
- public function __construct(ResourceNameCollectionFactoryInterface $resourceNameCollectionFactory, ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator)
+ public function __construct(ResourceMetadataFactoryInterface $resourceMetadataFactory, IriConverterInterface $iriConverter, UrlGeneratorInterface $urlGenerator)
{
- $this->resourceNameCollectionFactory = $resourceNameCollectionFactory;
$this->resourceMetadataFactory = $resourceMetadataFactory;
$this->iriConverter = $iriConverter;
$this->urlGenerator = $urlGenerator;
@@ -41,15 +41,15 @@ public function __construct(ResourceNameCollectionFactoryInterface $resourceName
/**
* {@inheritdoc}
*/
- public function getEntrypoint(string $referenceType = UrlGeneratorInterface::ABS_PATH) : array
+ public function normalize($object, $format = null, array $context = [])
{
$entrypoint = [
- '@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Entrypoint'], $referenceType),
- '@id' => $this->urlGenerator->generate('api_hydra_entrypoint', [], $referenceType),
+ '@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Entrypoint']),
+ '@id' => $this->urlGenerator->generate('api_entrypoint'),
'@type' => 'Entrypoint',
];
- foreach ($this->resourceNameCollectionFactory->create() as $resourceClass) {
+ foreach ($object as $resourceClass) {
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
if (empty($resourceMetadata->getCollectionOperations())) {
@@ -64,4 +64,12 @@ public function getEntrypoint(string $referenceType = UrlGeneratorInterface::ABS
return $entrypoint;
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supportsNormalization($data, $format = null)
+ {
+ return self::FORMAT === $format && $data instanceof ResourceNameCollection;
+ }
}
diff --git a/src/JsonLd/EntrypointBuilderInterface.php b/src/JsonLd/EntrypointBuilderInterface.php
deleted file mode 100644
index e1fe43ed256..00000000000
--- a/src/JsonLd/EntrypointBuilderInterface.php
+++ /dev/null
@@ -1,29 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace ApiPlatform\Core\JsonLd;
-
-use ApiPlatform\Core\Api\UrlGeneratorInterface;
-
-/**
- * API entrypoint builder interface.
- *
- * @author Kévin Dunglas
- */
-interface EntrypointBuilderInterface
-{
- /**
- * Gets the entrypoint content of the API.
- *
- * @return array
- */
- public function getEntrypoint(string $referenceType = UrlGeneratorInterface::ABS_PATH) : array;
-}
diff --git a/src/Serializer/ItemNormalizer.php b/src/Serializer/ItemNormalizer.php
index c61b70802fb..d3d42ab8f2d 100644
--- a/src/Serializer/ItemNormalizer.php
+++ b/src/Serializer/ItemNormalizer.php
@@ -45,6 +45,6 @@ public function denormalize($data, $class, $format = null, array $context = [])
$context['object_to_populate'] = $this->iriConverter->getItemFromIri($data['id'], true);
}
- return parent::denormalize($data, $class, $format, $context); // TODO: Change the autogenerated stub
+ return parent::denormalize($data, $class, $format, $context);
}
}
diff --git a/src/Swagger/ApiDocumentationBuilder.php b/src/Swagger/ApiDocumentationBuilder.php
index 550d6721d6f..cc412647943 100644
--- a/src/Swagger/ApiDocumentationBuilder.php
+++ b/src/Swagger/ApiDocumentationBuilder.php
@@ -180,7 +180,6 @@ public function getApiDocumentation() : array
}
}
-
$resourceClassIri .= '/{id}';
$itemOperationsDocs[$resourceClassIri] = $operation['item'];
diff --git a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
index 9b9d6e9dd77..55123417217 100644
--- a/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
+++ b/tests/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtensionTest.php
@@ -279,7 +279,6 @@ private function getContainerBuilderProphecy()
'api_platform.doctrine.orm.query_extension.pagination',
'api_platform.doctrine.orm.query_extension.order',
'api_platform.doctrine.listener.view.write',
- 'api_platform.jsonld.context_builder',
'api_platform.jsonld.normalizer.item',
'api_platform.jsonld.encoder',
'api_platform.jsonld.action.context',
@@ -290,15 +289,16 @@ private function getContainerBuilderProphecy()
'api_platform.swagger.action.documentation',
'api_platform.swagger.action.ui',
'api_platform.hal.encoder',
+ 'api_platform.hal.normalizer.resource_name_collection',
'api_platform.hal.normalizer.item',
'api_platform.hal.normalizer.collection',
'api_platform.hydra.action.documentation',
'api_platform.hydra.action.exception',
'api_platform.hydra.documentation_builder',
- 'api_platform.hydra.entrypoint_builder',
'api_platform.hydra.listener.response.add_link_header',
'api_platform.hydra.listener.exception.validation',
'api_platform.hydra.listener.exception',
+ 'api_platform.hydra.normalizer.resource_name_collection',
'api_platform.hydra.normalizer.collection',
'api_platform.hydra.normalizer.partial_collection_view',
'api_platform.hydra.normalizer.collection_filters',
diff --git a/tests/Bridge/Symfony/Routing/ApiLoaderTest.php b/tests/Bridge/Symfony/Routing/ApiLoaderTest.php
index 3444df54207..937d60b0e03 100644
--- a/tests/Bridge/Symfony/Routing/ApiLoaderTest.php
+++ b/tests/Bridge/Symfony/Routing/ApiLoaderTest.php
@@ -32,16 +32,13 @@ class ApiLoaderTest extends \PHPUnit_Framework_TestCase
public function testApiLoader()
{
$resourceMetadata = new ResourceMetadata();
-
$resourceMetadata = $resourceMetadata->withShortName('dummy');
-
//default operation based on OperationResourceMetadataFactory
$resourceMetadata = $resourceMetadata->withItemOperations([
'get' => ['method' => 'GET'],
'put' => ['method' => 'PUT'],
'delete' => ['method' => 'DELETE'],
]);
-
//custom operations
$resourceMetadata = $resourceMetadata->withCollectionOperations([
'my_op' => ['method' => 'GET', 'controller' => 'some.service.name'], //with controller
@@ -159,7 +156,7 @@ private function getApiLoaderWithResourceMetadata(ResourceMetadata $resourceMeta
$resourcePathGeneratorProphecy = $this->prophesize(ResourcePathNamingStrategyInterface::class);
$resourcePathGeneratorProphecy->generateResourceBasePath('dummy')->willReturn('dummies');
- $apiLoader = new ApiLoader($kernelProphecy->reveal(), $resourceNameCollectionFactoryProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), $resourcePathGeneratorProphecy->reveal(), $containerProphecy->reveal());
+ $apiLoader = new ApiLoader($kernelProphecy->reveal(), $resourceNameCollectionFactoryProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), $resourcePathGeneratorProphecy->reveal(), $containerProphecy->reveal(), ['jsonld' => ['application/ld+json']]);
return $apiLoader;
}
diff --git a/tests/Hal/Serializer/ItemNormalizerTest.php b/tests/Hal/Serializer/ItemNormalizerTest.php
index c786a3d429e..7d5f67000a9 100644
--- a/tests/Hal/Serializer/ItemNormalizerTest.php
+++ b/tests/Hal/Serializer/ItemNormalizerTest.php
@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
-namespace ApiPlatform\Core\Tests\Hal;
+namespace ApiPlatform\Core\Tests\Hal\Serializer;
use ApiPlatform\Core\Api\IriConverterInterface;
use ApiPlatform\Core\Api\ResourceClassResolverInterface;
diff --git a/tests/Hal/Serializer/ResourceNameCollectionNormalizerTest.php b/tests/Hal/Serializer/ResourceNameCollectionNormalizerTest.php
new file mode 100644
index 00000000000..0cc89cc93f3
--- /dev/null
+++ b/tests/Hal/Serializer/ResourceNameCollectionNormalizerTest.php
@@ -0,0 +1,69 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ApiPlatform\Core\Tests\Hal\Serializer;
+
+use ApiPlatform\Core\Api\IriConverterInterface;
+use ApiPlatform\Core\Api\UrlGeneratorInterface;
+use ApiPlatform\Core\Hal\Serializer\ResourceNameCollectionNormalizer;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
+use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
+use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
+
+/**
+ * @author Kévin Dunglas
+ */
+class ResourceNameCollectionNormalizerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testSupportNormalization()
+ {
+ $collection = new ResourceNameCollection();
+
+ $factoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+ $urlGeneratorProphecy = $this->prophesize(UrlGeneratorInterface::class);
+
+ $normalizer = new ResourceNameCollectionNormalizer($factoryProphecy->reveal(), $iriConverterProphecy->reveal(), $urlGeneratorProphecy->reveal());
+
+ $this->assertTrue($normalizer->supportsNormalization($collection, ResourceNameCollectionNormalizer::FORMAT));
+ $this->assertFalse($normalizer->supportsNormalization($collection, 'json'));
+ $this->assertFalse($normalizer->supportsNormalization(new \stdClass(), ResourceNameCollectionNormalizer::FORMAT));
+ }
+
+ public function testNormalize()
+ {
+ $collection = new ResourceNameCollection([Dummy::class]);
+
+ $factoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $factoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, ['get']))->shouldBeCalled();
+
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+ $iriConverterProphecy->getIriFromResourceClass(Dummy::class)->willReturn('/api/dummies')->shouldBeCalled();
+
+ $urlGeneratorProphecy = $this->prophesize(UrlGeneratorInterface::class);
+ $urlGeneratorProphecy->generate('api_entrypoint')->willReturn('/api')->shouldBeCalled();
+
+ $normalizer = new ResourceNameCollectionNormalizer($factoryProphecy->reveal(), $iriConverterProphecy->reveal(), $urlGeneratorProphecy->reveal());
+
+ $expected = [
+ '_links' => [
+ 'self' => [
+ 'href' => '/api',
+ ],
+ 'dummy' => [
+ 'href' => '/api/dummies',
+ ],
+ ],
+ ];
+ $this->assertEquals($expected, $normalizer->normalize($collection, ResourceNameCollectionNormalizer::FORMAT));
+ }
+}
diff --git a/tests/Hydra/Serializer/ResourceNameCollectionNormalizerTest.php b/tests/Hydra/Serializer/ResourceNameCollectionNormalizerTest.php
new file mode 100644
index 00000000000..d18f4ab56f7
--- /dev/null
+++ b/tests/Hydra/Serializer/ResourceNameCollectionNormalizerTest.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace ApiPlatform\Core\Tests\Hydra\Serializer;
+
+use ApiPlatform\Core\Api\IriConverterInterface;
+use ApiPlatform\Core\Api\UrlGeneratorInterface;
+use ApiPlatform\Core\Hydra\Serializer\ResourceNameCollectionNormalizer;
+use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
+use ApiPlatform\Core\Metadata\Resource\ResourceMetadata;
+use ApiPlatform\Core\Metadata\Resource\ResourceNameCollection;
+use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
+
+/**
+ * @author Kévin Dunglas
+ */
+class ResourceNameCollectionNormalizerTest extends \PHPUnit_Framework_TestCase
+{
+ public function testSupportNormalization()
+ {
+ $collection = new ResourceNameCollection();
+
+ $factoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+ $urlGeneratorProphecy = $this->prophesize(UrlGeneratorInterface::class);
+
+ $normalizer = new ResourceNameCollectionNormalizer($factoryProphecy->reveal(), $iriConverterProphecy->reveal(), $urlGeneratorProphecy->reveal());
+
+ $this->assertTrue($normalizer->supportsNormalization($collection, ResourceNameCollectionNormalizer::FORMAT));
+ $this->assertFalse($normalizer->supportsNormalization($collection, 'json'));
+ $this->assertFalse($normalizer->supportsNormalization(new \stdClass(), ResourceNameCollectionNormalizer::FORMAT));
+ }
+
+ public function testNormalize()
+ {
+ $collection = new ResourceNameCollection([Dummy::class]);
+
+ $factoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
+ $factoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadata('Dummy', null, null, null, ['get']))->shouldBeCalled();
+
+ $iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
+ $iriConverterProphecy->getIriFromResourceClass(Dummy::class)->willReturn('/api/dummies')->shouldBeCalled();
+
+ $urlGeneratorProphecy = $this->prophesize(UrlGeneratorInterface::class);
+ $urlGeneratorProphecy->generate('api_entrypoint')->willReturn('/api')->shouldBeCalled();
+ $urlGeneratorProphecy->generate('api_jsonld_context', ['shortName' => 'Entrypoint'])->willReturn('/context/Entrypoint')->shouldBeCalled();
+
+ $normalizer = new ResourceNameCollectionNormalizer($factoryProphecy->reveal(), $iriConverterProphecy->reveal(), $urlGeneratorProphecy->reveal());
+
+ $expected = [
+ '@context' => '/context/Entrypoint',
+ '@id' => '/api',
+ '@type' => 'Entrypoint',
+ 'dummy' => '/api/dummies',
+ ];
+ $this->assertEquals($expected, $normalizer->normalize($collection, ResourceNameCollectionNormalizer::FORMAT));
+ }
+}