diff --git a/CHANGELOG.md b/CHANGELOG.md index 10d7d4c4f83..94e3115a93e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# 2.6.4 + +* OpenApi: Fix missing 422 responses in the documentation (#4086) + ## 2.6.3 * Identifiers: Re-allow `POST` operations even if no identifier is defined (#4052) diff --git a/src/OpenApi/Factory/OpenApiFactory.php b/src/OpenApi/Factory/OpenApiFactory.php index 073a682a1e2..d76d7d7b65c 100644 --- a/src/OpenApi/Factory/OpenApiFactory.php +++ b/src/OpenApi/Factory/OpenApiFactory.php @@ -204,6 +204,7 @@ private function collectPaths(ResourceMetadata $resourceMetadata, string $resour $successStatus = (string) $resourceMetadata->getTypedOperationAttribute($operationType, $operationName, 'status', '201'); $responses[$successStatus] = new Model\Response(sprintf('%s resource created', $resourceShortName), $responseContent, null, $responseLinks); $responses['400'] = new Model\Response('Invalid input'); + $responses['422'] = new Model\Response('Unprocessable entity'); break; case 'PATCH': case 'PUT': @@ -212,6 +213,7 @@ private function collectPaths(ResourceMetadata $resourceMetadata, string $resour $responseContent = $this->buildContent($responseMimeTypes, $operationOutputSchemas); $responses[$successStatus] = new Model\Response(sprintf('%s resource updated', $resourceShortName), $responseContent, null, $responseLinks); $responses['400'] = new Model\Response('Invalid input'); + $responses['422'] = new Model\Response('Unprocessable entity'); break; case 'DELETE': $successStatus = (string) $resourceMetadata->getTypedOperationAttribute($operationType, $operationName, 'status', '204'); diff --git a/src/Swagger/Serializer/DocumentationNormalizer.php b/src/Swagger/Serializer/DocumentationNormalizer.php index 0a2920e8316..e405251228d 100644 --- a/src/Swagger/Serializer/DocumentationNormalizer.php +++ b/src/Swagger/Serializer/DocumentationNormalizer.php @@ -526,6 +526,7 @@ private function updatePostOperation(bool $v3, \ArrayObject $pathOperation, arra (string) $resourceMetadata->getTypedOperationAttribute($operationType, $operationName, 'status', '201') => $successResponse, '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ]; return $this->addRequestBody($v3, $pathOperation, $definitions, $resourceClass, $resourceShortName, $operationType, $operationName, $requestMimeTypes); @@ -549,6 +550,7 @@ private function updatePutOperation(bool $v3, \ArrayObject $pathOperation, array (string) $resourceMetadata->getTypedOperationAttribute($operationType, $operationName, 'status', '200') => $successResponse, '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ]; return $this->addRequestBody($v3, $pathOperation, $definitions, $resourceClass, $resourceShortName, $operationType, $operationName, $requestMimeTypes, true); diff --git a/tests/OpenApi/Factory/OpenApiFactoryTest.php b/tests/OpenApi/Factory/OpenApiFactoryTest.php index 831bca493b5..42e74f73e05 100644 --- a/tests/OpenApi/Factory/OpenApiFactoryTest.php +++ b/tests/OpenApi/Factory/OpenApiFactoryTest.php @@ -317,6 +317,7 @@ public function testInvoke(): void new \ArrayObject(['GetDummyItem' => new Model\Link('getDummyItem', new \ArrayObject(['id' => '$response.body#/id']), [], 'The `id` value returned in the response can be used as the `id` parameter in `GET /dummies/{id}`.')]) ), '400' => new Model\Response('Invalid input'), + '422' => new Model\Response('Unprocessable entity'), ], 'Creates a Dummy resource.', 'Creates a Dummy resource.', @@ -368,6 +369,7 @@ public function testInvoke(): void new \ArrayObject(['GetDummyItem' => new Model\Link('getDummyItem', new \ArrayObject(['id' => '$response.body#/id']), [], 'The `id` value returned in the response can be used as the `id` parameter in `GET /dummies/{id}`.')]) ), '400' => new Model\Response('Invalid input'), + '422' => new Model\Response('Unprocessable entity'), '404' => new Model\Response('Resource not found'), ], 'Replaces the Dummy resource.', @@ -437,6 +439,7 @@ public function testInvoke(): void new \ArrayObject(['GetDummyItem' => new Model\Link('getDummyItem', new \ArrayObject(['id' => '$response.body#/id']), [], 'The `id` value returned in the response can be used as the `id` parameter in `GET /dummies/{id}`.')]) ), '400' => new Model\Response('Invalid input'), + '422' => new Model\Response('Unprocessable entity'), '404' => new Model\Response('Resource not found'), ], 'Replaces the Dummy resource.', diff --git a/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php b/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php index f6997297464..15d901adb8b 100644 --- a/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php +++ b/tests/Swagger/Serializer/DocumentationNormalizerV2Test.php @@ -241,6 +241,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -293,6 +294,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -349,6 +351,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -791,6 +794,7 @@ public function testNormalizeWithOnlyNormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -841,6 +845,7 @@ public function testNormalizeWithOnlyNormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1013,6 +1018,7 @@ public function testNormalizeNotAddExtraBodyParameters(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1063,6 +1069,7 @@ public function testNormalizeNotAddExtraBodyParameters(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1333,6 +1340,7 @@ public function testNormalizeWithOnlyDenormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1383,6 +1391,7 @@ public function testNormalizeWithOnlyDenormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1543,6 +1552,7 @@ public function testNormalizeWithNormalizationAndDenormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1593,6 +1603,7 @@ public function testNormalizeWithNormalizationAndDenormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1752,6 +1763,7 @@ public function testNormalizeSkipsNotReadableAndNotWritableProperties(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1804,6 +1816,7 @@ public function testNormalizeSkipsNotReadableAndNotWritableProperties(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -2263,6 +2276,7 @@ public function testNormalizeWithNestedNormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -2313,6 +2327,7 @@ public function testNormalizeWithNestedNormalizationGroups(): void ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -3038,6 +3053,7 @@ private function doTestNormalizeWithCustomFormatsDefinedAtOperationLevel(Operati ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -3090,6 +3106,7 @@ private function doTestNormalizeWithCustomFormatsDefinedAtOperationLevel(Operati ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -3248,6 +3265,9 @@ private function doTestNormalizeWithInputAndOutputClass(): void 404 => [ 'description' => 'Resource not found', ], + 422 => [ + 'description' => 'Unprocessable entity' + ], ], 'parameters' => [ [ @@ -3322,6 +3342,9 @@ private function doTestNormalizeWithInputAndOutputClass(): void 404 => [ 'description' => 'Resource not found', ], + 422 => [ + 'description' => 'Unprocessable entity' + ], ], ]), ], diff --git a/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php b/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php index 6d7de03e455..3ea56e07583 100644 --- a/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php +++ b/tests/Swagger/Serializer/DocumentationNormalizerV3Test.php @@ -238,6 +238,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -297,6 +298,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -372,6 +374,7 @@ private function doTestNormalize(OperationMethodResolverInterface $operationMeth ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -867,6 +870,7 @@ public function testNormalizeWithOnlyNormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -926,6 +930,7 @@ public function testNormalizeWithOnlyNormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1212,6 +1217,7 @@ public function testNormalizeWithOnlyDenormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1269,6 +1275,7 @@ public function testNormalizeWithOnlyDenormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1440,6 +1447,7 @@ public function testNormalizeWithNormalizationAndDenormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1497,6 +1505,7 @@ public function testNormalizeWithNormalizationAndDenormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -1990,6 +1999,7 @@ public function testNormalizeWithNestedNormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -2047,6 +2057,7 @@ public function testNormalizeWithNestedNormalizationGroups(): void ], '400' => ['description' => 'Invalid input'], '404' => ['description' => 'Resource not found'], + '422' => ['description' => 'Unprocessable entity'], ], ]), ], @@ -3119,6 +3130,7 @@ private function doTestNormalizeWithCustomFormatsDefinedAtOperationLevel(Operati ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ], @@ -3184,6 +3196,7 @@ private function doTestNormalizeWithCustomFormatsDefinedAtOperationLevel(Operati ], 400 => ['description' => 'Invalid input'], 404 => ['description' => 'Resource not found'], + 422 => ['description' => 'Unprocessable entity'], ], ]), ],