From eb6f090e22e524ccc38ff39291a2f878b77cbc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Wed, 2 Apr 2014 10:12:36 +0200 Subject: [PATCH 1/4] Allow to specify validation group --- .../MethodHandler/DataValidationTrait.php | 14 ++++++-- .../Controller/MethodHandler/PostHandler.php | 2 +- .../Controller/MethodHandler/PutHandler.php | 2 +- .../ValidationGroupProviderInterface.php | 35 ++++++++++++++++++ .../Asset/Mvc/DataValidationObject.php | 7 ++-- .../MethodHandler/DataValidationTraitTest.php | 36 +++++++++++++++++++ 6 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/ZfrRest/Mvc/Controller/ValidationGroupProviderInterface.php diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php b/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php index ef9dd4b..93fd48d 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php @@ -20,6 +20,7 @@ use Zend\InputFilter\InputFilterPluginManager; use ZfrRest\Http\Exception\Client\UnprocessableEntityException; +use ZfrRest\Mvc\Controller\ValidationGroupProviderInterface; use ZfrRest\Mvc\Exception\RuntimeException; use ZfrRest\Resource\ResourceInterface; @@ -40,12 +41,13 @@ trait DataValidationTrait * Filter and validate the data * * @param ResourceInterface $resource - * @param array $data + * @param array $data + * @param string|null $validationGroupName * @return array * @throws RuntimeException If no input filter is bound to the resource * @throws UnprocessableEntityException If validation fails */ - public function validateData(ResourceInterface $resource, array $data) + public function validateData(ResourceInterface $resource, array $data, $validationGroupName = null) { if (!($inputFilterName = $resource->getMetadata()->getInputFilterName())) { throw new RuntimeException('No input filter name has been found in resource metadata'); @@ -55,6 +57,14 @@ public function validateData(ResourceInterface $resource, array $data) $inputFilter = $this->inputFilterPluginManager->get($inputFilterName); $inputFilter->setData($data); + if ($this->controller instanceof ValidationGroupProviderInterface && $validationGroupName) { + $validationGroups = $this->controller->getValidationGroupSpecification(); + + if (isset($validationGroups[$validationGroupName])) { + $inputFilter->setValidationGroup($validationGroups[$validationGroupName]); + } + } + if (!$inputFilter->isValid()) { throw new UnprocessableEntityException( 'Validation error', diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php b/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php index e2d8a3a..7316eb9 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php @@ -83,7 +83,7 @@ public function handleMethod(AbstractRestfulController $controller, ResourceInte $data = json_decode($controller->getRequest()->getContent(), true); if ($controller->getAutoValidate()) { - $data = $this->validateData($singleResource, $data); + $data = $this->validateData($singleResource, $data, 'post'); } if ($controller->getAutoHydrate()) { diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php b/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php index d1af871..043c069 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php @@ -76,7 +76,7 @@ public function handleMethod(AbstractRestfulController $controller, ResourceInte $data = json_decode($controller->getRequest()->getContent(), true); if ($controller->getAutoValidate()) { - $data = $this->validateData($resource, $data); + $data = $this->validateData($resource, $data, 'put'); } if ($controller->getAutoHydrate()) { diff --git a/src/ZfrRest/Mvc/Controller/ValidationGroupProviderInterface.php b/src/ZfrRest/Mvc/Controller/ValidationGroupProviderInterface.php new file mode 100644 index 0000000..b6c5c73 --- /dev/null +++ b/src/ZfrRest/Mvc/Controller/ValidationGroupProviderInterface.php @@ -0,0 +1,35 @@ + + * @licence MIT + */ +interface ValidationGroupProviderInterface +{ + /** + * Get the validation group specification + * + * @return array + */ + public function getValidationGroupSpecification(); +} diff --git a/tests/ZfrRestTest/Asset/Mvc/DataValidationObject.php b/tests/ZfrRestTest/Asset/Mvc/DataValidationObject.php index 0d4bc85..49ff50e 100644 --- a/tests/ZfrRestTest/Asset/Mvc/DataValidationObject.php +++ b/tests/ZfrRestTest/Asset/Mvc/DataValidationObject.php @@ -25,12 +25,13 @@ class DataValidationObject { use DataValidationTrait; + protected $controller; + /** - * @param InputFilterPluginManager $inputFilterPluginManager + * @param InputFilterPluginManager $inputFilterPluginManager */ public function __construct(InputFilterPluginManager $inputFilterPluginManager) { - $this->inputFilterPluginManager = $inputFilterPluginManager; + $this->inputFilterPluginManager = $inputFilterPluginManager; } - } diff --git a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php index 221f495..c838b5b 100644 --- a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php +++ b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php @@ -117,4 +117,40 @@ public function testThrowExceptionOnFailedValidation() $this->dataValidation->validateData($resource, $data); } + + public function testCanUseValidationGroup() + { + $controller = $this->getMock('ZfrRest\Mvc\Controller\ValidationGroupProviderInterface'); + + $reflProperty = new \ReflectionProperty($this->dataValidation, 'controller'); + $reflProperty->setAccessible(true); + $reflProperty->setValue($this->dataValidation, 'controller'); + + $resource = $this->getMock('ZfrRest\Resource\ResourceInterface'); + $metadata = $this->getMock('ZfrRest\Resource\Metadata\ResourceMetadataInterface'); + + $resource->expects($this->once())->method('getMetadata')->will($this->returnValue($metadata)); + $metadata->expects($this->once())->method('getInputFilterName')->will($this->returnValue('inputFilter')); + + $data = ['foo']; + + $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface'); + $inputFilter->expects($this->once())->method('setData')->with($data); + $inputFilter->expects($this->once()) + ->method('isValid') + ->will($this->returnValue(true)); + + $this->inputFilterPluginManager->expects($this->once()) + ->method('get') + ->with('inputFilter') + ->will($this->returnValue($inputFilter)); + + $inputFilter->expects($this->once()) + ->method('getValues') + ->will($this->returnValue(['filtered'])); + + $result = $this->dataValidation->validateData($resource, $data, 'post'); + + $this->assertEquals(['filtered'], $result); + } } From aa7f41bc2e916b44946e915a8df69811e1bf7f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Wed, 2 Apr 2014 10:21:35 +0200 Subject: [PATCH 2/4] Add test --- .../MethodHandler/DataValidationTraitTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php index c838b5b..b90428b 100644 --- a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php +++ b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php @@ -124,7 +124,7 @@ public function testCanUseValidationGroup() $reflProperty = new \ReflectionProperty($this->dataValidation, 'controller'); $reflProperty->setAccessible(true); - $reflProperty->setValue($this->dataValidation, 'controller'); + $reflProperty->setValue($this->dataValidation, $controller); $resource = $this->getMock('ZfrRest\Resource\ResourceInterface'); $metadata = $this->getMock('ZfrRest\Resource\Metadata\ResourceMetadataInterface'); @@ -132,6 +132,10 @@ public function testCanUseValidationGroup() $resource->expects($this->once())->method('getMetadata')->will($this->returnValue($metadata)); $metadata->expects($this->once())->method('getInputFilterName')->will($this->returnValue('inputFilter')); + $controller->expects($this->once()) + ->method('getValidationGroupSpecification') + ->will($this->returnValue(['post' => ['field']])); + $data = ['foo']; $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface'); @@ -140,6 +144,10 @@ public function testCanUseValidationGroup() ->method('isValid') ->will($this->returnValue(true)); + $inputFilter->expects($this->once()) + ->method('setValidationGroup') + ->with(['field']); + $this->inputFilterPluginManager->expects($this->once()) ->method('get') ->with('inputFilter') From 769a16331a6df8c379b0960ec0b4a6371825b253 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Wed, 2 Apr 2014 10:40:48 +0200 Subject: [PATCH 3/4] Transfer controller --- .../MethodHandler/DataValidationTrait.php | 20 ++++++++++++------- .../Controller/MethodHandler/PostHandler.php | 2 +- .../Controller/MethodHandler/PutHandler.php | 2 +- .../MethodHandler/DataValidationTraitTest.php | 8 ++------ 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php b/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php index 93fd48d..32d2437 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/DataValidationTrait.php @@ -19,6 +19,7 @@ namespace ZfrRest\Mvc\Controller\MethodHandler; use Zend\InputFilter\InputFilterPluginManager; +use Zend\Mvc\Controller\AbstractController; use ZfrRest\Http\Exception\Client\UnprocessableEntityException; use ZfrRest\Mvc\Controller\ValidationGroupProviderInterface; use ZfrRest\Mvc\Exception\RuntimeException; @@ -40,15 +41,20 @@ trait DataValidationTrait /** * Filter and validate the data * - * @param ResourceInterface $resource - * @param array $data - * @param string|null $validationGroupName + * @param ResourceInterface $resource + * @param array $data + * @param AbstractController|null $controller + * @param string|null $validationGroupName * @return array * @throws RuntimeException If no input filter is bound to the resource * @throws UnprocessableEntityException If validation fails */ - public function validateData(ResourceInterface $resource, array $data, $validationGroupName = null) - { + public function validateData( + ResourceInterface $resource, + array $data, + AbstractController $controller = null, + $validationGroupName = null + ) { if (!($inputFilterName = $resource->getMetadata()->getInputFilterName())) { throw new RuntimeException('No input filter name has been found in resource metadata'); } @@ -57,8 +63,8 @@ public function validateData(ResourceInterface $resource, array $data, $validati $inputFilter = $this->inputFilterPluginManager->get($inputFilterName); $inputFilter->setData($data); - if ($this->controller instanceof ValidationGroupProviderInterface && $validationGroupName) { - $validationGroups = $this->controller->getValidationGroupSpecification(); + if ($controller instanceof ValidationGroupProviderInterface && $validationGroupName) { + $validationGroups = $controller->getValidationGroupSpecification(); if (isset($validationGroups[$validationGroupName])) { $inputFilter->setValidationGroup($validationGroups[$validationGroupName]); diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php b/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php index 7316eb9..22b47e1 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/PostHandler.php @@ -83,7 +83,7 @@ public function handleMethod(AbstractRestfulController $controller, ResourceInte $data = json_decode($controller->getRequest()->getContent(), true); if ($controller->getAutoValidate()) { - $data = $this->validateData($singleResource, $data, 'post'); + $data = $this->validateData($singleResource, $data, $controller, 'post'); } if ($controller->getAutoHydrate()) { diff --git a/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php b/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php index 043c069..86d11cd 100644 --- a/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php +++ b/src/ZfrRest/Mvc/Controller/MethodHandler/PutHandler.php @@ -76,7 +76,7 @@ public function handleMethod(AbstractRestfulController $controller, ResourceInte $data = json_decode($controller->getRequest()->getContent(), true); if ($controller->getAutoValidate()) { - $data = $this->validateData($resource, $data, 'put'); + $data = $this->validateData($resource, $data, $controller, 'put'); } if ($controller->getAutoHydrate()) { diff --git a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php index b90428b..3e4051f 100644 --- a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php +++ b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php @@ -120,11 +120,7 @@ public function testThrowExceptionOnFailedValidation() public function testCanUseValidationGroup() { - $controller = $this->getMock('ZfrRest\Mvc\Controller\ValidationGroupProviderInterface'); - - $reflProperty = new \ReflectionProperty($this->dataValidation, 'controller'); - $reflProperty->setAccessible(true); - $reflProperty->setValue($this->dataValidation, $controller); + $controller = $this->getMock('ZfrRest\Mvc\Controller\AbstractRestfulController'); $resource = $this->getMock('ZfrRest\Resource\ResourceInterface'); $metadata = $this->getMock('ZfrRest\Resource\Metadata\ResourceMetadataInterface'); @@ -157,7 +153,7 @@ public function testCanUseValidationGroup() ->method('getValues') ->will($this->returnValue(['filtered'])); - $result = $this->dataValidation->validateData($resource, $data, 'post'); + $result = $this->dataValidation->validateData($resource, $data, $controller, 'post'); $this->assertEquals(['filtered'], $result); } From 3bfdfa68b42c182f391a683b4d2a862f4c9cecaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Gallego?= Date: Wed, 2 Apr 2014 10:43:05 +0200 Subject: [PATCH 4/4] Fix test --- .../Mvc/ControllerWithValidationGroupSpec.php | 36 +++++++++++++++++++ .../MethodHandler/DataValidationTraitTest.php | 9 ++--- 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tests/ZfrRestTest/Asset/Mvc/ControllerWithValidationGroupSpec.php diff --git a/tests/ZfrRestTest/Asset/Mvc/ControllerWithValidationGroupSpec.php b/tests/ZfrRestTest/Asset/Mvc/ControllerWithValidationGroupSpec.php new file mode 100644 index 0000000..cc7da21 --- /dev/null +++ b/tests/ZfrRestTest/Asset/Mvc/ControllerWithValidationGroupSpec.php @@ -0,0 +1,36 @@ + ['field'] + ]; + } +} diff --git a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php index 3e4051f..71609a0 100644 --- a/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php +++ b/tests/ZfrRestTest/Mvc/Controller/MethodHandler/DataValidationTraitTest.php @@ -20,6 +20,7 @@ use PHPUnit_Framework_TestCase; use ZfrRest\Options\ControllerBehavioursOptions; +use ZfrRestTest\Asset\Mvc\ControllerWithValidationGroupSpec; use ZfrRestTest\Asset\Mvc\DataValidationObject; /** @@ -120,18 +121,12 @@ public function testThrowExceptionOnFailedValidation() public function testCanUseValidationGroup() { - $controller = $this->getMock('ZfrRest\Mvc\Controller\AbstractRestfulController'); - $resource = $this->getMock('ZfrRest\Resource\ResourceInterface'); $metadata = $this->getMock('ZfrRest\Resource\Metadata\ResourceMetadataInterface'); $resource->expects($this->once())->method('getMetadata')->will($this->returnValue($metadata)); $metadata->expects($this->once())->method('getInputFilterName')->will($this->returnValue('inputFilter')); - $controller->expects($this->once()) - ->method('getValidationGroupSpecification') - ->will($this->returnValue(['post' => ['field']])); - $data = ['foo']; $inputFilter = $this->getMock('Zend\InputFilter\InputFilterInterface'); @@ -153,6 +148,8 @@ public function testCanUseValidationGroup() ->method('getValues') ->will($this->returnValue(['filtered'])); + $controller = new ControllerWithValidationGroupSpec(); + $result = $this->dataValidation->validateData($resource, $data, $controller, 'post'); $this->assertEquals(['filtered'], $result);