Skip to content

Commit f956cde

Browse files
committed
Lot of new PHPUnit tests
1 parent 2229fcf commit f956cde

35 files changed

+1395
-50
lines changed

Api/IriConverter.php

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
namespace Dunglas\ApiBundle\Api;
1313

14+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
1415
use Dunglas\ApiBundle\Mapping\AttributeMetadataInterface;
15-
use Dunglas\ApiBundle\Mapping\ClassMetadataFactory;
16+
use Dunglas\ApiBundle\Mapping\ClassMetadataFactoryInterface;
1617
use Dunglas\ApiBundle\Model\DataProviderInterface;
1718
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
18-
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
19+
use Symfony\Component\Routing\Exception\ExceptionInterface;
1920
use Symfony\Component\Routing\RouterInterface;
2021

2122
/**
@@ -46,23 +47,23 @@ class IriConverter implements IriConverterInterface
4647
*/
4748
private $routeCache;
4849
/**
49-
* @var ClassMetadataFactory
50+
* @var ClassMetadataFactoryInterface
5051
*/
5152
private $classMetadataFactory;
5253

5354
public function __construct(
5455
ResourceCollectionInterface $resourceCollection,
5556
DataProviderInterface $dataProvider,
57+
ClassMetadataFactoryInterface $classMetadataFactory,
5658
RouterInterface $router,
57-
PropertyAccessorInterface $propertyAccessor,
58-
ClassMetadataFactory $classMetadataFactory
59+
PropertyAccessorInterface $propertyAccessor
5960
) {
6061
$this->resourceCollection = $resourceCollection;
6162
$this->dataProvider = $dataProvider;
63+
$this->classMetadataFactory = $classMetadataFactory;
6264
$this->router = $router;
6365
$this->propertyAccessor = $propertyAccessor;
6466
$this->routeCache = new \SplObjectStorage();
65-
$this->classMetadataFactory = $classMetadataFactory;
6667
}
6768

6869
/**
@@ -72,19 +73,23 @@ public function getItemFromIri($iri, $fetchData = false)
7273
{
7374
try {
7475
$parameters = $this->router->match($iri);
75-
} catch (ResourceNotFoundException $e) {
76-
return;
76+
} catch (ExceptionInterface $e) {
77+
throw new InvalidArgumentException(sprintf('No route matches "%s".', $iri), $e->getCode(), $e);
7778
}
7879

7980
if (
8081
!isset($parameters['_resource']) ||
8182
!isset($parameters['id']) ||
8283
!($resource = $this->resourceCollection->getResourceForShortName($parameters['_resource']))
8384
) {
84-
throw new \InvalidArgumentException(sprintf('No resource associated with the IRI "%s".', $iri));
85+
throw new InvalidArgumentException(sprintf('No resource associated to "%s".', $iri));
86+
}
87+
88+
if ($item = $this->dataProvider->getItem($resource, $parameters['id'], $fetchData)) {
89+
return $item;
8590
}
8691

87-
return $this->dataProvider->getItem($resource, $parameters['id'], $fetchData);
92+
throw new InvalidArgumentException(sprintf('Item not found for "%s".', $iri));
8893
}
8994

9095
/**
@@ -102,23 +107,27 @@ public function getIriFromItem($item, $referenceType = RouterInterface::ABSOLUTE
102107
);
103108
}
104109

105-
throw new \InvalidArgumentException(sprintf('No resource associated with the type "%s".', get_class($item)));
110+
throw new InvalidArgumentException(sprintf('No resource associated with the type "%s".', get_class($item)));
106111
}
107112

108113
/**
109114
* {@inheritdoc}
110115
*/
111116
public function getIriFromResource(ResourceInterface $resource, $referenceType = RouterInterface::ABSOLUTE_PATH)
112117
{
113-
return $this->router->generate($this->getRouteName($resource, 'collection'), [], $referenceType);
118+
try {
119+
return $this->router->generate($this->getRouteName($resource, 'collection'), [], $referenceType);
120+
} catch (ExceptionInterface $e) {
121+
throw new InvalidArgumentException(sprintf('Unable to generate an IRI for "%s".', $resource->getShortName()), $e->getCode(), $e);
122+
}
114123
}
115124

116125
/**
117126
* Gets the route name related to a resource.
118127
*
119128
* @param ResourceInterface $resource
120129
*
121-
* @return string
130+
* @return string|null
122131
*/
123132
private function getRouteName(ResourceInterface $resource, $prefix)
124133
{

Api/IriConverterInterface.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Dunglas\ApiBundle\Api;
1313

14+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
1415
use Symfony\Component\Routing\RouterInterface;
1516

1617
/**
@@ -26,7 +27,9 @@ interface IriConverterInterface
2627
* @param string $iri
2728
* @param bool $fetchData
2829
*
29-
* @return object|null
30+
* @return object
31+
*
32+
* @throws InvalidArgumentException
3033
*/
3134
public function getItemFromIri($iri, $fetchData = false);
3235

@@ -37,6 +40,8 @@ public function getItemFromIri($iri, $fetchData = false);
3740
* @param bool $referenceType
3841
*
3942
* @return string
43+
*
44+
* @throws InvalidArgumentException
4045
*/
4146
public function getIriFromItem($item, $referenceType = RouterInterface::ABSOLUTE_PATH);
4247

@@ -47,6 +52,8 @@ public function getIriFromItem($item, $referenceType = RouterInterface::ABSOLUTE
4752
* @param bool $referenceType
4853
*
4954
* @return string
55+
*
56+
* @throws InvalidArgumentException
5057
*/
5158
public function getIriFromResource(ResourceInterface $resource, $referenceType = RouterInterface::ABSOLUTE_PATH);
5259
}

Api/Operation/OperationFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private function createOperation(
132132

133133
// Populate route name
134134
if (null === $routeName) {
135-
$routeName = self::$inflectorCache[$shortName].'_'.$defaultAction;
135+
$routeName = self::ROUTE_NAME_PREFIX.self::$inflectorCache[$shortName].'_'.$defaultAction;
136136
}
137137
}
138138

Api/Resource.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Dunglas\ApiBundle\Api\Filter\FilterInterface;
1515
use Dunglas\ApiBundle\Api\Operation\OperationInterface;
16+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
1617

1718
/**
1819
* {@inheritdoc}
@@ -56,11 +57,13 @@ class Resource implements ResourceInterface
5657

5758
/**
5859
* @param string $entityClass
60+
*
61+
* @throws InvalidArgumentException
5962
*/
6063
public function __construct($entityClass)
6164
{
6265
if (!class_exists($entityClass)) {
63-
throw new \InvalidArgumentException(sprintf('The class %s does not exist.', $entityClass));
66+
throw new InvalidArgumentException(sprintf('The class "%s" does not exist.', $entityClass));
6467
}
6568

6669
$this->entityClass = $entityClass;

Api/ResourceCollection.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Dunglas\ApiBundle\Api;
1313

14+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
1415
use Dunglas\ApiBundle\Util\ClassInfoTrait;
1516

1617
/**
@@ -39,12 +40,12 @@ public function init(array $resources)
3940
foreach ($resources as $resource) {
4041
$entityClass = $resource->getEntityClass();
4142
if (isset($this->entityClassIndex[$entityClass])) {
42-
throw new \InvalidArgumentException(sprintf('A Resource class already exists for "%s".', $entityClass));
43+
throw new InvalidArgumentException(sprintf('A Resource class already exists for "%s".', $entityClass));
4344
}
4445

4546
$shortName = $resource->getShortName();
4647
if (isset($this->shortNameIndex[$shortName])) {
47-
throw new \InvalidArgumentException(sprintf('A Resource class with the short name "%s" already exists.', $shortName));
48+
throw new InvalidArgumentException(sprintf('A Resource class with the short name "%s" already exists.', $shortName));
4849
}
4950

5051
$this->append($resource);

Api/ResourceCollectionInterface.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Dunglas\ApiBundle\Api;
1313

14+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
15+
1416
/**
1517
* A collection of {@see ResourceInterface} classes.
1618
*
@@ -23,7 +25,7 @@ interface ResourceCollectionInterface extends \Traversable
2325
*
2426
* @param ResourceInterface[] $resources
2527
*
26-
* @throws \InvalidArgumentException
28+
* @throws InvalidArgumentException
2729
*/
2830
public function init(array $resources);
2931

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## 1.0.0 beta 3
44

55
* The Hydra documentation URL is now `/apidoc` (was `/vocab`)
6+
* Exceptions implements `Dunglas\ApiBundle\Exception\ExceptionInterface`
7+
* Prefix automatically generated route names by `api_`
68
* Automatic detection of the method of the entity class returning the identifier when using Doctrine (previously `getId()` was always used)
79
* New extension point in `Dunglas\ApiBundle\Doctrine\Orm\DataProvider` allowing to customize Doctrine paginator and performance optimization when using typical queries
810
* New `Dunglas\ApiBundle\JsonLd\Event\Events::CONTEXT_BUILDER` event allowing to modify the JSON-LD context

Controller/ResourceController.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@
1414
use Dunglas\ApiBundle\Event\Events;
1515
use Dunglas\ApiBundle\Event\DataEvent;
1616
use Dunglas\ApiBundle\Exception\DeserializationException;
17+
use Dunglas\ApiBundle\Exception\ExceptionInterface;
1718
use Dunglas\ApiBundle\Api\ResourceInterface;
19+
use Dunglas\ApiBundle\Exception\InvalidArgumentException;
1820
use Dunglas\ApiBundle\Model\PaginatorInterface;
1921
use Dunglas\ApiBundle\JsonLd\Response;
2022
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
2123
use Symfony\Component\HttpFoundation\Request;
2224
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
2325
use Symfony\Component\Validator\ConstraintViolationListInterface;
24-
use Symfony\Component\Serializer\Exception\Exception;
26+
use Symfony\Component\Serializer\Exception\ExceptionInterface as SerializerExceptionInterface;
2527

2628
/**
2729
* CRUD operations for a JSON-LD/Hydra API.
@@ -43,7 +45,7 @@ class ResourceController extends Controller
4345
*
4446
* @return ResourceInterface
4547
*
46-
* @throws \InvalidArgumentException
48+
* @throws InvalidArgumentException
4749
*/
4850
protected function getResource(Request $request)
4951
{
@@ -52,12 +54,12 @@ protected function getResource(Request $request)
5254
}
5355

5456
if (!$request->attributes->has('_resource')) {
55-
throw new \InvalidArgumentException('The current request doesn\'t have an associated resource.');
57+
throw new InvalidArgumentException('The current request doesn\'t have an associated resource.');
5658
}
5759

5860
$shortName = $request->attributes->get('_resource');
5961
if (!($this->resource = $this->get('api.resource_collection')->getResourceForShortName($shortName))) {
60-
throw new \InvalidArgumentException(sprintf('The resource "%s" cannot be found.', $shortName));
62+
throw new InvalidArgumentException(sprintf('The resource "%s" cannot be found.', $shortName));
6163
}
6264

6365
return $this->resource;
@@ -178,7 +180,9 @@ public function cpostAction(Request $request)
178180
'json-ld',
179181
$resource->getDenormalizationContext()
180182
);
181-
} catch (Exception $e) {
183+
} catch (ExceptionInterface $e) {
184+
throw new DeserializationException($e->getMessage(), $e->getCode(), $e);
185+
} catch (SerializerExceptionInterface $e) {
182186
throw new DeserializationException($e->getMessage(), $e->getCode(), $e);
183187
}
184188

@@ -241,7 +245,9 @@ public function putAction(Request $request, $id)
241245
'json-ld',
242246
$context
243247
);
244-
} catch (Exception $e) {
248+
} catch (ExceptionInterface $e) {
249+
throw new DeserializationException($e->getMessage(), $e->getCode(), $e);
250+
} catch (SerializerExceptionInterface $e) {
245251
throw new DeserializationException($e->getMessage(), $e->getCode(), $e);
246252
}
247253

Doctrine/EventSubscriber.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Dunglas\ApiBundle\Doctrine;
1313

14+
use Doctrine\Common\Persistence\ObjectManager;
1415
use Doctrine\Common\Persistence\ManagerRegistry;
1516
use Dunglas\ApiBundle\Event\Events;
1617
use Dunglas\ApiBundle\Event\DataEvent;
@@ -109,7 +110,7 @@ public function deleteObject(DataEvent $event)
109110
*
110111
* @param DataEvent $event
111112
*
112-
* @return \Doctrine\Common\Persistence\ObjectManager|bool
113+
* @return ObjectManager|false
113114
*/
114115
private function getManagerIfApplicable(DataEvent $event)
115116
{

Exception/DeserializationException.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace Dunglas\ApiBundle\Exception;
1313

14-
use Symfony\Component\Serializer\Exception\ExceptionInterface;
14+
use Symfony\Component\Serializer\Exception\ExceptionInterface as SerializerExceptionInterface;
1515

1616
/**
1717
* Deserialization exception.
1818
*
1919
* @author Samuel ROZE <[email protected]>
2020
* @author Kévin Dunglas <[email protected]>
2121
*/
22-
class DeserializationException extends \Exception implements ExceptionInterface
22+
class DeserializationException extends \Exception implements ExceptionInterface, SerializerExceptionInterface
2323
{
2424
}

0 commit comments

Comments
 (0)