diff --git a/features/json/input_output.feature b/features/json/input_output.feature index 5f1982c0098..2a5a1143162 100644 --- a/features/json/input_output.feature +++ b/features/json/input_output.feature @@ -9,7 +9,7 @@ Feature: JSON DTO input and output @createSchema Scenario: Request a password reset - And I send a "POST" request to "/users/password_reset_request" with body: + And I send a "POST" request to "/users_reset/password_reset_request" with body: """ { "email": "user@example.com" @@ -27,7 +27,7 @@ Feature: JSON DTO input and output @createSchema Scenario: Request a password reset for a non-existent user - And I send a "POST" request to "/users/password_reset_request" with body: + And I send a "POST" request to "/users_reset/password_reset_request" with body: """ { "email": "does-not-exist@example.com" diff --git a/src/OpenApi/Factory/OpenApiFactory.php b/src/OpenApi/Factory/OpenApiFactory.php index fe0e6c867b6..abed0cf19c9 100644 --- a/src/OpenApi/Factory/OpenApiFactory.php +++ b/src/OpenApi/Factory/OpenApiFactory.php @@ -498,11 +498,13 @@ private function collectPaths(ApiResource $resource, ResourceMetadataCollection private function buildOpenApiResponse(array $existingResponses, int|string $status, string $description, ?Operation $openapiOperation = null, ?HttpOperation $operation = null, ?array $responseMimeTypes = null, ?array $operationOutputSchemas = null, ?ResourceMetadataCollection $resourceMetadataCollection = null): Operation { + $noOutput = \is_array($operation?->getOutput()) && null === $operation->getOutput()['class']; + if (isset($existingResponses[$status])) { return $openapiOperation; } $responseLinks = $responseContent = null; - if ($responseMimeTypes && $operationOutputSchemas) { + if ($responseMimeTypes && $operationOutputSchemas && !$noOutput) { $responseContent = $this->buildContent($responseMimeTypes, $operationOutputSchemas); } if ($resourceMetadataCollection && $operation) { diff --git a/src/State/Exception/ParameterNotSupportedException.php b/src/State/Exception/ParameterNotSupportedException.php index f3d149c825e..97694bea8a1 100644 --- a/src/State/Exception/ParameterNotSupportedException.php +++ b/src/State/Exception/ParameterNotSupportedException.php @@ -28,7 +28,7 @@ public function getType(): string return '/error/400'; } - public function getTitle(): ?string + public function getTitle(): string { return $this->message; } diff --git a/tests/Fixtures/TestBundle/ApiResource/WithParameter.php b/tests/Fixtures/TestBundle/ApiResource/WithParameter.php index cda390c124a..dfb8c4d04dd 100644 --- a/tests/Fixtures/TestBundle/ApiResource/WithParameter.php +++ b/tests/Fixtures/TestBundle/ApiResource/WithParameter.php @@ -96,23 +96,24 @@ uriTemplate: 'validate_parameters{._format}', parameters: [ 'enum' => new QueryParameter( - schema: ['enum' => ['a', 'b'], 'uniqueItems' => true], + schema: ['enum' => ['a', 'b'], 'uniqueItems' => true, 'type' => 'array'], castToArray: true, openApi: new OpenApiParameter(name: 'enum', in: 'query', style: 'deepObject') ), 'enumNotDeepObject' => new QueryParameter( - schema: ['enum' => ['a', 'b'], 'uniqueItems' => true], + schema: ['enum' => ['a', 'b'], 'uniqueItems' => true, 'type' => 'string'], castToArray: true, + castToNativeType: true, ), 'num' => new QueryParameter( - schema: ['minimum' => 1, 'maximum' => 3], + schema: ['minimum' => 1, 'maximum' => 3, 'type' => 'integer'], nativeType: new BuiltinType(TypeIdentifier::STRING), ), 'numMultipleType' => new QueryParameter( - schema: ['minimum' => 1, 'maximum' => 3], + schema: ['minimum' => 1, 'maximum' => 3, 'type' => 'array'], ), 'exclusiveNum' => new QueryParameter( - schema: ['exclusiveMinimum' => 1, 'exclusiveMaximum' => 3], + schema: ['exclusiveMinimum' => 1, 'exclusiveMaximum' => 3, 'type' => 'integer'], nativeType: new BuiltinType(TypeIdentifier::STRING), ), 'blank' => new QueryParameter( @@ -120,12 +121,12 @@ nativeType: new BuiltinType(TypeIdentifier::STRING), ), 'length' => new QueryParameter( - schema: ['maxLength' => 1, 'minLength' => 3], + schema: ['maxLength' => 1, 'minLength' => 3, 'type' => 'integer'], nativeType: new BuiltinType(TypeIdentifier::STRING), ), - 'array' => new QueryParameter(schema: ['minItems' => 2, 'maxItems' => 3]), + 'array' => new QueryParameter(schema: ['minItems' => 2, 'maxItems' => 3, 'type' => 'integer']), 'multipleOf' => new QueryParameter( - schema: ['multipleOf' => 2], + schema: ['multipleOf' => 2, 'type' => 'integer'], nativeType: new BuiltinType(TypeIdentifier::STRING), ), 'int' => new QueryParameter( diff --git a/tests/Fixtures/TestBundle/Entity/User.php b/tests/Fixtures/TestBundle/Entity/User.php index 004f51b5d61..6890002ca8f 100644 --- a/tests/Fixtures/TestBundle/Entity/User.php +++ b/tests/Fixtures/TestBundle/Entity/User.php @@ -37,7 +37,7 @@ */ #[ApiResource(operations: [ new Post( - uriTemplate: '/users/password_reset_request', + uriTemplate: '/users_reset/password_reset_request', messenger: 'input', input: PasswordResetRequest::class, output: PasswordResetRequestResult::class, diff --git a/tests/Functional/Parameters/ValidationTest.php b/tests/Functional/Parameters/ValidationTest.php index 803f1645e29..2ef96eb21b5 100644 --- a/tests/Functional/Parameters/ValidationTest.php +++ b/tests/Functional/Parameters/ValidationTest.php @@ -58,9 +58,6 @@ public static function provideQueryStrings(): array [ 'enumNotDeepObject[]=c&enumNotDeepObject[]=c', [ - [ - 'propertyPath' => 'enumNotDeepObject', 'message' => 'The value you selected is not a valid choice.', - ], [ 'propertyPath' => 'enumNotDeepObject', 'message' => 'The value you selected is not a valid choice.', ],