diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8c5573d..5f5ed61 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [1.8.0]
### Added
-- Support for `doctrine/annotations: ^2.0`
- Support for PHP 8 attributes
+- Support for `doctrine/annotations: ^2.0`
## [1.7.0]
### Added
diff --git a/composer.json b/composer.json
index 370ffb7..e02257d 100644
--- a/composer.json
+++ b/composer.json
@@ -30,7 +30,7 @@
"doctrine/annotations": "^1.14 || ^2.0"
},
"require-dev": {
- "phpunit/phpunit": "^7.5 || ^9.5",
+ "phpunit/phpunit": "^9.6",
"mockery/mockery": "^1.3.6",
"symfony/yaml": "^3.4.34|^4.3|^5.4|^6.0",
"doctrine/doctrine-bundle": "^1.12.0|^2.1",
diff --git a/src/Attribute/Query.php b/src/Attribute/Query.php
index e47ff38..6ace7d0 100644
--- a/src/Attribute/Query.php
+++ b/src/Attribute/Query.php
@@ -5,7 +5,6 @@
namespace Paysera\Bundle\ApiBundle\Attribute;
use Attribute;
-use Paysera\Bundle\ApiBundle\Annotation\Validation;
use Paysera\Bundle\ApiBundle\Entity\QueryResolverOptions;
use Paysera\Bundle\ApiBundle\Entity\RestRequestOptions;
use Paysera\Bundle\ApiBundle\Exception\ConfigurationException;
diff --git a/src/Service/RoutingLoader/RoutingAttributeLoader.php b/src/Service/RoutingLoader/RoutingAttributeLoader.php
index 46c5c82..e925406 100644
--- a/src/Service/RoutingLoader/RoutingAttributeLoader.php
+++ b/src/Service/RoutingLoader/RoutingAttributeLoader.php
@@ -17,6 +17,8 @@
*/
class RoutingAttributeLoader extends AttributeRouteControllerLoader
{
+ private const ATTRIBUTE_SUPPORT_PHP_VERSION_ID = 80100; // `new` in initializers support is required
+
/**
* @var RestRequestHelper
*/
@@ -57,7 +59,7 @@ protected function configureRoute(
$this->loadAnnotations($route, $class, $method);
- if (PHP_VERSION_ID >= 80000) {
+ if (PHP_VERSION_ID >= self::ATTRIBUTE_SUPPORT_PHP_VERSION_ID) {
$this->loadAttributes($route, $class, $method);
}
}
diff --git a/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedClassRequiredPermissionsController.php b/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedClassRequiredPermissionsController.php
new file mode 100644
index 0000000..50808dd
--- /dev/null
+++ b/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedClassRequiredPermissionsController.php
@@ -0,0 +1,31 @@
+ 'internal.field1'])]
+class AttributedClassValidationController
+{
+ /**
+ * @Route(path="/attributed/class/testValidation", methods={"POST"})
+ */
+ #[Body(parameterName: 'resource')]
+ #[Validation(groups: ['field1_email'], violationPathMap: ['field1' => 'my_mapped_key'])]
+ public function testValidation(MyObject $resource): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/class/testValidationFromClass", methods={"POST"})
+ */
+ #[Body(parameterName: 'resource')]
+ public function testValidationFromClass(MyObject $resource): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+}
diff --git a/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedController.php b/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedController.php
new file mode 100644
index 0000000..8bf78f2
--- /dev/null
+++ b/tests/Functional/Fixtures/FixtureTestBundle/Controller/AttributedController.php
@@ -0,0 +1,264 @@
+ 'my_mapped_key'])]
+ public function testBodyNormalizationWithValidation(MyObject $resource): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testBodyNormalizationWithInnerTypeValidation", methods={"POST"})
+ */
+ #[Body(parameterName: 'resource')]
+ #[Validation(groups: ['internal_field1_email'])]
+ public function testBodyNormalizationWithInnerTypeValidation(MyObject $resource): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testBodyValidationCanBeTurnedOff", methods={"POST"})
+ */
+ #[Body(parameterName: 'resource')]
+ #[Validation(enabled: false)]
+ public function testBodyValidationCanBeTurnedOff(MyObject $resource): Response
+ {
+ return new Response('OK');
+ }
+
+ /**
+ * @Route(path="/attributed/testBodyValidationCanBeTurnedOffWithEmptyGroups", methods={"POST"})
+ */
+ #[Body(parameterName: 'resource')]
+ #[Validation(groups: [])]
+ public function testBodyValidationCanBeTurnedOffWithEmptyGroups(MyObject $resource): Response
+ {
+ return new Response('OK');
+ }
+
+ /**
+ * @Route(path="/attributed/testPathAttribute/{id}", methods={"GET"})
+ * @Route(path="/attributed/testPathAttribute", methods={"GET"})
+ */
+ #[PathAttribute(parameterName: 'parameter', pathPartName: 'id', resolverType: 'prefixed')]
+ public function testPathAttribute(string $parameter = 'default'): Response
+ {
+ return new Response($parameter);
+ }
+
+ /**
+ * @Route(path="/attributed/testPathAttributeWithFindingObject/{id}", methods={"GET"})
+ */
+ #[PathAttribute(parameterName: 'myObject', pathPartName: 'id')]
+ public function testPathAttributeWithFindingObject(MyObject $myObject): Response
+ {
+ return new Response($myObject->getField1());
+ }
+
+ /**
+ * @Route(path="/attributed/testPathAttributeWithFailedResolution/{id}", methods={"GET"})
+ */
+ #[PathAttribute(parameterName: 'myObject', pathPartName: 'id', resolverType: 'always_null')]
+ public function testPathAttributeWithFailedResolution(MyObject $myObject): Response
+ {
+ // should fail before calling controller
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolver", methods={"GET"})
+ */
+ #[Query(parameterName: 'parameter', denormalizationType: 'extract:parameter')]
+ public function testQueryResolver(string $parameter): Response
+ {
+ return new Response($parameter);
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverWithDenormalizationGroup", methods={"GET"})
+ */
+ #[Query(parameterName: 'parameter', denormalizationType: 'extract:parameter', denormalizationGroup: 'custom')]
+ public function testQueryResolverWithDenormalizationGroup(string $parameter): Response
+ {
+ return new Response($parameter);
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverPagerLimitIs42", methods={"GET"})
+ */
+ #[Query(parameterName: 'pager')]
+ public function testQueryResolverPagerLimitIs42(Pager $pager): Response
+ {
+ return new Response($pager->getLimit() === 42 ? 'OK' : 'FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverHasDefaultValidation", methods={"GET"})
+ */
+ #[Query(parameterName: 'myObject')]
+ public function testQueryResolverHasDefaultValidation(MyObject $myObject): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverCanTurnOffValidation", methods={"GET"})
+ */
+ #[Query(parameterName: 'myObject', validation: new Validation(enabled: false))]
+ public function testQueryResolverCanTurnOffValidation(MyObject $myObject): Response
+ {
+ return new Response('OK');
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverCanTurnOffValidationWithEmptyGroups", methods={"GET"})
+ */
+ #[Query(parameterName: 'myObject', validation: new Validation(groups: []))]
+ public function testQueryResolverCanTurnOffValidationWithEmptyGroups(MyObject $myObject): Response
+ {
+ return new Response('OK');
+ }
+
+ /**
+ * @Route(path="/attributed/testQueryResolverValidationWithInvalidData", methods={"GET"})
+ */
+ #[Query(parameterName: 'myObject', validation: new Validation(groups: ['field1_email'], violationPathMap: ['field1' => 'mapped_key']))]
+ public function testQueryResolverValidationWithInvalidData(MyObject $myObject): Response
+ {
+ // should fail validation
+ return new Response('FAIL');
+ }
+
+ /**
+ * @Route(path="/attributed/testRequiredPermissions", methods={"GET"})
+ */
+ #[RequiredPermissions(permissions: ['ROLE_USER', 'ROLE_ADMIN'])]
+ public function testRequiredPermissions(): Response
+ {
+ return new Response('OK');
+ }
+
+ /**
+ * @Route(path="/attributed/testResponseNormalization", methods={"GET"})
+ */
+ #[ResponseNormalization(normalizationType: 'my_object_custom')]
+ public function testResponseNormalization(): MyObject
+ {
+ return (new MyObject())
+ ->setField1('hi')
+ ;
+ }
+
+ /**
+ * @Route(path="/attributed/testResponseNormalizationWithNormalizationGroup", methods={"GET"})
+ */
+ #[ResponseNormalization(normalizationGroup: 'custom')]
+ public function testResponseNormalizationWithNormalizationGroup(): MyObject
+ {
+ return (new MyObject())
+ ->setField1('hi')
+ ;
+ }
+
+ /**
+ * @Route(path="/attributed/testResponseNormalizationWithGuessedNormalizer", methods={"GET"})
+ */
+ #[ResponseNormalization]
+ public function testResponseNormalizationWithGuessedNormalizer(): MyObject
+ {
+ return (new MyObject())
+ ->setField1('hi')
+ ;
+ }
+}
diff --git a/tests/Functional/Fixtures/FixtureTestBundle/Resources/config/services.xml b/tests/Functional/Fixtures/FixtureTestBundle/Resources/config/services.xml
index b4ada44..46836bd 100644
--- a/tests/Functional/Fixtures/FixtureTestBundle/Resources/config/services.xml
+++ b/tests/Functional/Fixtures/FixtureTestBundle/Resources/config/services.xml
@@ -78,10 +78,16 @@
+
+
+
diff --git a/tests/Functional/Fixtures/config/common.yml b/tests/Functional/Fixtures/config/common.yml
index c3b2acb..ccb0059 100644
--- a/tests/Functional/Fixtures/config/common.yml
+++ b/tests/Functional/Fixtures/config/common.yml
@@ -37,7 +37,7 @@ doctrine:
services:
logger:
- class: Psr\Log\NullLogger
+ class: Psr\Log\NullLogger # Symfony\Component\ErrorHandler\BufferingLogger
public: true
rest_registry:
alias: paysera_api.rest_request_options_registry
diff --git a/tests/Functional/FunctionalAnnotationsTest.php b/tests/Functional/FunctionalAnnotationsTest.php
index eee6dd4..946146e 100644
--- a/tests/Functional/FunctionalAnnotationsTest.php
+++ b/tests/Functional/FunctionalAnnotationsTest.php
@@ -20,11 +20,42 @@ protected function setUp(): void
* @param Request $request
* @param Response|null $extraResponseVersion
*/
- public function testRestRequestConfiguration(
+ public function testAnnotatedRestRequestConfiguration(
Response $expectedResponse,
Request $request,
Response $extraResponseVersion = null
) {
+ $this->makeTest('annotated', $expectedResponse, $request, $extraResponseVersion);
+ }
+
+ /**
+ * @dataProvider restRequestsConfigurationProvider
+ * @param Response $expectedResponse
+ * @param Request $request
+ * @param Response|null $extraResponseVersion
+ */
+ public function testAttributedRestRequestConfiguration(
+ Response $expectedResponse,
+ Request $request,
+ Response $extraResponseVersion = null
+ ) {
+ $this->makeTest('attributed', $expectedResponse, $request, $extraResponseVersion);
+ }
+
+ private function makeTest(
+ string $pathPrefix,
+ Response $expectedResponse,
+ Request $request,
+ Response $extraResponseVersion = null
+ ): void {
+ if ($pathPrefix === 'attributed') {
+ $this->checkAttributeConfigurationSupport();
+ }
+
+ $request->server->set(
+ 'REQUEST_URI',
+ sprintf('/%s%s', $pathPrefix, $request->server->get('REQUEST_URI'))
+ );
$response = $this->handleRequest($request);
$assertionMessage = 'expected correct content';
@@ -52,14 +83,14 @@ public function testRestRequestConfiguration(
);
}
- public function restRequestsConfigurationProvider()
+ public function restRequestsConfigurationProvider(): array
{
return [
'testBodyNormalizationWithExtractedKeyValue' => [
new Response('this_should_be_extracted'),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithExtractedKeyValue',
+ '/testBodyNormalizationWithExtractedKeyValue',
[
'something' => 'unimportant',
'key' => 'this_should_be_extracted',
@@ -70,14 +101,14 @@ public function restRequestsConfigurationProvider()
new Response('default'),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithExtractedKeyValue'
+ '/testBodyNormalizationWithExtractedKeyValue'
),
],
'testBodyNormalizationWithDenormalizationGroup' => [
new Response('custom'),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithDenormalizationGroup',
+ '/testBodyNormalizationWithDenormalizationGroup',
[
'key_custom' => 'custom',
'key' => 'wrong_key',
@@ -91,7 +122,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithExtractedKeyValue',
+ '/testBodyNormalizationWithExtractedKeyValue',
'something',
['Content-Type' => 'text/plain']
),
@@ -103,14 +134,14 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithRequiredBody'
+ '/testBodyNormalizationWithRequiredBody'
),
],
'testBodyAndResponseNormalization' => [
new Response('{"field1":"value1"}'),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyAndResponseNormalization',
+ '/testBodyAndResponseNormalization',
['field1' => 'value1']
),
],
@@ -121,7 +152,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyAndResponseNormalization',
+ '/testBodyAndResponseNormalization',
['internal' => ['field1' => 1]]
),
],
@@ -132,7 +163,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithCustomContentType',
+ '/testBodyNormalizationWithCustomContentType',
['key' => 'value']
),
],
@@ -140,7 +171,7 @@ public function restRequestsConfigurationProvider()
new Response('prefixed_my_text'),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithCustomContentType',
+ '/testBodyNormalizationWithCustomContentType',
'my_text',
['Content-Type' => 'text/plain']
),
@@ -152,7 +183,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithCustomContentTypeAndJsonDecode',
+ '/testBodyNormalizationWithCustomContentTypeAndJsonDecode',
['key' => 'value']
),
],
@@ -160,7 +191,7 @@ public function restRequestsConfigurationProvider()
new Response('value'),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithCustomContentTypeAndJsonDecode',
+ '/testBodyNormalizationWithCustomContentTypeAndJsonDecode',
json_encode(['key' => 'value']),
['Content-Type' => 'text/plain']
),
@@ -169,7 +200,7 @@ public function restRequestsConfigurationProvider()
new Response('prefixed_by_body'),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithSemiContentTypeRestriction',
+ '/testBodyNormalizationWithSemiContentTypeRestriction',
'by_body',
['Content-Type' => 'text/something']
),
@@ -181,7 +212,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'POST',
- '/annotated/testBodyNormalizationWithSemiContentTypeRestriction',
+ '/testBodyNormalizationWithSemiContentTypeRestriction',
'by_body',
['Content-Type' => 'image/gif']
),
@@ -203,7 +234,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithValidation',
+ '/testBodyNormalizationWithValidation',
['field1' => 'not an email']
),
new Response(
@@ -238,7 +269,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyNormalizationWithInnerTypeValidation',
+ '/testBodyNormalizationWithInnerTypeValidation',
['field1' => 'blah', 'internal' => ['field1' => 'not an email']]
),
new Response(
@@ -260,7 +291,7 @@ public function restRequestsConfigurationProvider()
new Response('OK', 200),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyValidationCanBeTurnedOff',
+ '/testBodyValidationCanBeTurnedOff',
['field1' => '']
),
],
@@ -268,7 +299,7 @@ public function restRequestsConfigurationProvider()
new Response('OK', 200),
$this->createJsonRequest(
'POST',
- '/annotated/testBodyValidationCanBeTurnedOffWithEmptyGroups',
+ '/testBodyValidationCanBeTurnedOffWithEmptyGroups',
['field1' => '']
),
],
@@ -276,35 +307,35 @@ public function restRequestsConfigurationProvider()
new Response('prefixed_123'),
$this->createRequest(
'GET',
- '/annotated/testPathAttribute/123'
+ '/testPathAttribute/123'
),
],
'testPathAttribute with optional resolution' => [
new Response('default'),
$this->createRequest(
'GET',
- '/annotated/testPathAttribute'
+ '/testPathAttribute'
),
],
'testPathAttributeWithFindingObject' => [
new Response('123'),
$this->createRequest(
'GET',
- '/annotated/testPathAttributeWithFindingObject/123'
+ '/testPathAttributeWithFindingObject/123'
),
],
'testPathAttributeWithFailedResolution' => [
new Response('{"error":"not_found","error_description":"Resource was not found"}', 404),
$this->createRequest(
'GET',
- '/annotated/testPathAttributeWithFailedResolution/{id}'
+ '/testPathAttributeWithFailedResolution/{id}'
),
],
'testQueryResolver' => [
new Response('my_param'),
$this->createRequest(
'GET',
- '/annotated/testQueryResolver?parameter=my_param'
+ '/testQueryResolver?parameter=my_param'
),
],
'testQueryResolver is always mandatory' => [
@@ -314,21 +345,21 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolver?other_parameter=my_param'
+ '/testQueryResolver?other_parameter=my_param'
),
],
'testQueryResolverWithDenormalizationGroup' => [
new Response('custom'),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverWithDenormalizationGroup?parameter=wrong_key¶meter_custom=custom'
+ '/testQueryResolverWithDenormalizationGroup?parameter=wrong_key¶meter_custom=custom'
),
],
'testQueryResolverPagerLimitIs42' => [
new Response('OK'),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverPagerLimitIs42?limit=42'
+ '/testQueryResolverPagerLimitIs42?limit=42'
),
],
'testQueryResolverHasDefaultValidation' => [
@@ -338,7 +369,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverHasDefaultValidation?field1='
+ '/testQueryResolverHasDefaultValidation?field1='
),
],
'testQueryResolverCanTurnOffValidation' => [
@@ -348,7 +379,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverCanTurnOffValidation?field1='
+ '/testQueryResolverCanTurnOffValidation?field1='
),
],
'testQueryResolverCanTurnOffValidationWithEmptyGroups' => [
@@ -358,7 +389,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverCanTurnOffValidationWithEmptyGroups?field1='
+ '/testQueryResolverCanTurnOffValidationWithEmptyGroups?field1='
),
],
'testQueryResolverValidationWithInvalidData - normalizer errors do not map fields' => [
@@ -368,7 +399,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverValidationWithInvalidData'
+ '/testQueryResolverValidationWithInvalidData'
),
],
'testQueryResolverValidationWithInvalidData' => [
@@ -388,7 +419,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testQueryResolverValidationWithInvalidData?field1=not_an_email'
+ '/testQueryResolverValidationWithInvalidData?field1=not_an_email'
),
new Response(
json_encode([
@@ -412,7 +443,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testRequiredPermissions'
+ '/testRequiredPermissions'
),
],
'testRequiredPermissions without not enough permissions' => [
@@ -422,7 +453,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/testRequiredPermissions',
+ '/testRequiredPermissions',
null,
[],
'user'
@@ -432,7 +463,7 @@ public function restRequestsConfigurationProvider()
new Response('OK'),
$this->createRequest(
'GET',
- '/annotated/testRequiredPermissions',
+ '/testRequiredPermissions',
null,
[],
'admin'
@@ -445,7 +476,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/class/testRequiredPermissions'
+ '/class/testRequiredPermissions'
),
],
'testRequiredPermissions with class annotation and with not enough permissions' => [
@@ -455,7 +486,7 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/class/testRequiredPermissions',
+ '/class/testRequiredPermissions',
null,
[],
'user'
@@ -465,7 +496,7 @@ public function restRequestsConfigurationProvider()
new Response('OK'),
$this->createRequest(
'GET',
- '/annotated/class/testRequiredPermissions',
+ '/class/testRequiredPermissions',
null,
[],
'admin'
@@ -478,14 +509,14 @@ public function restRequestsConfigurationProvider()
),
$this->createRequest(
'GET',
- '/annotated/class/simpleAction'
+ '/class/simpleAction'
),
],
'testRequiredPermissions with class annotation and REST-specific method annotations: OK' => [
new Response('OK'),
$this->createRequest(
'GET',
- '/annotated/class/simpleAction',
+ '/class/simpleAction',
null,
[],
'user'
@@ -508,7 +539,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/class/testValidation',
+ '/class/testValidation',
['field1' => 'not an email', 'internal' => ['field1' => 'also not an email']]
),
new Response(
@@ -543,7 +574,7 @@ public function restRequestsConfigurationProvider()
),
$this->createJsonRequest(
'POST',
- '/annotated/class/testValidationFromClass',
+ '/class/testValidationFromClass',
['field1' => 'not an email', 'internal' => ['field1' => 'also not an email']]
),
new Response(
@@ -565,21 +596,21 @@ public function restRequestsConfigurationProvider()
new Response('{"field1_custom":"hi"}'),
$this->createRequest(
'GET',
- '/annotated/testResponseNormalization'
+ '/testResponseNormalization'
),
],
'testResponseNormalizationWithNormalizationGroup' => [
new Response('{"field1_custom":"hi"}'),
$this->createRequest(
'GET',
- '/annotated/testResponseNormalizationWithNormalizationGroup'
+ '/testResponseNormalizationWithNormalizationGroup'
),
],
'testResponseNormalizationWithGuessedNormalizer' => [
new Response('{"field1":"hi"}'),
$this->createRequest(
'GET',
- '/annotated/testResponseNormalizationWithGuessedNormalizer'
+ '/testResponseNormalizationWithGuessedNormalizer'
),
],
];
diff --git a/tests/Functional/FunctionalTestCase.php b/tests/Functional/FunctionalTestCase.php
index 199f425..703b3bc 100644
--- a/tests/Functional/FunctionalTestCase.php
+++ b/tests/Functional/FunctionalTestCase.php
@@ -7,6 +7,7 @@
use Doctrine\ORM\Tools\SchemaTool;
use Paysera\Bundle\ApiBundle\Tests\Functional\Fixtures\TestKernel;
use PHPUnit\Framework\TestCase;
+use Symfony\Bundle\FrameworkBundle\Routing\AttributeRouteControllerLoader;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ResettableContainerInterface;
use Symfony\Component\HttpKernel\Kernel;
@@ -108,4 +109,15 @@ protected function getEntityManager(): EntityManagerInterface
{
return $this->kernel->getContainer()->get('doctrine.orm.entity_manager');
}
+
+ protected function checkAttributeConfigurationSupport(): void
+ {
+ if (!class_exists(AttributeRouteControllerLoader::class)) {
+ $this->markTestSkipped('Unsupported Symfony version');
+ }
+
+ if (PHP_VERSION_ID < 80100) {
+ $this->markTestSkipped('Unsupported PHP version');
+ }
+ }
}
diff --git a/tests/Unit/Service/Annotation/ReflectionMethodWrapperTest.php b/tests/Unit/Service/RoutingLoader/ReflectionMethodWrapperTest.php
similarity index 82%
rename from tests/Unit/Service/Annotation/ReflectionMethodWrapperTest.php
rename to tests/Unit/Service/RoutingLoader/ReflectionMethodWrapperTest.php
index 6a746d6..030e782 100644
--- a/tests/Unit/Service/Annotation/ReflectionMethodWrapperTest.php
+++ b/tests/Unit/Service/RoutingLoader/ReflectionMethodWrapperTest.php
@@ -1,7 +1,7 @@
getParameterByName('param2');
$this->assertSame('param2', $reflectionParameter->getName());
}
- public function testGetParameterByNameWithNoSuchParameter()
+ public function testGetParameterByNameWithNoSuchParameter(): void
{
$wrapper = new ReflectionMethodWrapper(new ReflectionMethod(self::class, 'fixtureMethod'));
@@ -26,14 +26,14 @@ public function testGetParameterByNameWithNoSuchParameter()
$wrapper->getParameterByName('nonExisting');
}
- public function testGetNonBuiltInTypeForParameter()
+ public function testGetNonBuiltInTypeForParameter(): void
{
$wrapper = new ReflectionMethodWrapper(new ReflectionMethod(self::class, 'fixtureMethod'));
$this->assertSame('DateTime', $wrapper->getNonBuiltInTypeForParameter('param2'));
}
- public function testGetNonBuiltInTypeForParameterWithBuiltInType()
+ public function testGetNonBuiltInTypeForParameterWithBuiltInType(): void
{
$wrapper = new ReflectionMethodWrapper(new ReflectionMethod(self::class, 'fixtureMethod'));
@@ -41,7 +41,7 @@ public function testGetNonBuiltInTypeForParameterWithBuiltInType()
$wrapper->getNonBuiltInTypeForParameter('param1');
}
- public function testGetNonBuiltInTypeForParameterWithNoType()
+ public function testGetNonBuiltInTypeForParameterWithNoType(): void
{
$wrapper = new ReflectionMethodWrapper(new ReflectionMethod(self::class, 'fixtureMethod'));
@@ -49,11 +49,11 @@ public function testGetNonBuiltInTypeForParameterWithNoType()
$wrapper->getNonBuiltInTypeForParameter('param3');
}
- public function testGetFriendlyName()
+ public function testGetFriendlyName(): void
{
$wrapper = new ReflectionMethodWrapper(new ReflectionMethod(self::class, 'fixtureMethod'));
$this->assertSame(
- 'Paysera\Bundle\ApiBundle\Tests\Unit\Service\Annotation\ReflectionMethodWrapperTest::fixtureMethod',
+ sprintf('%s::%s', get_class($this), 'fixtureMethod'),
$wrapper->getFriendlyName()
);
}
diff --git a/tests/Unit/Service/Annotation/RestRequestOptionsBuilderTest.php b/tests/Unit/Service/RoutingLoader/RestRequestAnnotationOptionsBuilderTest.php
similarity index 86%
rename from tests/Unit/Service/Annotation/RestRequestOptionsBuilderTest.php
rename to tests/Unit/Service/RoutingLoader/RestRequestAnnotationOptionsBuilderTest.php
index df2a44c..a36d451 100644
--- a/tests/Unit/Service/Annotation/RestRequestOptionsBuilderTest.php
+++ b/tests/Unit/Service/RoutingLoader/RestRequestAnnotationOptionsBuilderTest.php
@@ -1,7 +1,7 @@
shouldReceive('validateRestRequestOptions')
- ->andReturnUsing(function (RestRequestOptions $options, string $fieldlyName) use ($expectedOptions) {
+ ->andReturnUsing(function (RestRequestOptions $options, string $friendlyName) use ($expectedOptions) {
$this->assertEquals($expectedOptions, $options);
$this->assertEquals(
- 'Paysera\Bundle\ApiBundle\Tests\Unit\Service\Annotation\RestRequestOptionsBuilderTest::fixtureMethod',
- $fieldlyName
+ sprintf('%s::%s', get_class($this), 'fixtureMethod'),
+ $friendlyName
);
})
;
@@ -61,7 +61,7 @@ public function testBuildOptions()
$this->assertEquals($expectedOptions, $options);
}
- public function testBuildOptionsWithSeveralUnsupportedAnnotations()
+ public function testBuildOptionsWithSeveralUnsupportedAnnotations(): void
{
$optionsValidator = Mockery::mock(RestRequestOptionsValidator::class);
@@ -75,7 +75,7 @@ public function testBuildOptionsWithSeveralUnsupportedAnnotations()
], new ReflectionMethod(self::class, 'fixtureMethod'));
}
- public function fixtureMethod()
+ public function fixtureMethod(): void
{
// do nothing
}
diff --git a/tests/Unit/Service/RoutingLoader/RestRequestAttributeOptionsBuilderTest.php b/tests/Unit/Service/RoutingLoader/RestRequestAttributeOptionsBuilderTest.php
new file mode 100644
index 0000000..4e74811
--- /dev/null
+++ b/tests/Unit/Service/RoutingLoader/RestRequestAttributeOptionsBuilderTest.php
@@ -0,0 +1,68 @@
+shouldReceive('apply')->andReturnUsing(function (RestRequestOptions $options) {
+ $options->setRequiredPermissions(['modified1']);
+ });
+
+ $annotationMock2 = Mockery::mock(RestAttributeInterface::class);
+ $annotationMock2->shouldReceive('apply')->andReturnUsing(function (RestRequestOptions $options) {
+ $options->setResponseNormalizationType('modified2');
+ });
+
+ $expectedOptions = (new RestRequestOptions())
+ ->setRequiredPermissions(['modified1'])
+ ->setResponseNormalizationType('modified2')
+ ;
+
+ $optionsValidator
+ ->shouldReceive('validateRestRequestOptions')
+ ->andReturnUsing(function (RestRequestOptions $options, string $friendlyName) use ($expectedOptions) {
+ $this->assertEquals($expectedOptions, $options);
+ $this->assertEquals(
+ sprintf('%s::%s', get_class($this), 'fixtureMethod'),
+ $friendlyName
+ );
+ })
+ ;
+
+ $annotations = [
+ $annotationMock1,
+ $annotationMock2,
+ ];
+
+ $options = $builder->buildOptions($annotations, $reflectionMethod);
+
+ $this->assertEquals($expectedOptions, $options);
+ }
+
+ public function fixtureMethod(): void
+ {
+ // do nothing
+ }
+}