Skip to content

Commit 0127065

Browse files
committed
fix(jsonshcema): fix tests
1 parent f7e9360 commit 0127065

File tree

4 files changed

+38
-22
lines changed

4 files changed

+38
-22
lines changed

features/openapi/docs.feature

+2-2
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,14 @@ Feature: Documentation support
307307
And the response should be in JSON
308308
And the header "Content-Type" should be equal to "application/json; charset=utf-8"
309309
And the OpenAPI class "Resource" exists
310-
And the OpenAPI class "RelatedResource" exists
310+
And the OpenAPI class "ResourceRelated" exists
311311
And the "resourceRelated" property for the OpenAPI class "Resource" should be equal to:
312312
"""
313313
{
314314
"readOnly":true,
315315
"anyOf":[
316316
{
317-
"$ref":"#/components/schemas/RelatedResource"
317+
"$ref":"#/components/schemas/ResourceRelated"
318318
}
319319
],
320320
"nullable":true

src/JsonSchema/SchemaFactory.php

+31-15
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
namespace ApiPlatform\JsonSchema;
1515

1616
use ApiPlatform\Api\ResourceClassResolverInterface;
17+
use ApiPlatform\Exception\OperationNotFoundException;
1718
use ApiPlatform\Metadata\ApiProperty;
1819
use ApiPlatform\Metadata\CollectionOperationInterface;
1920
use ApiPlatform\Metadata\HttpOperation;
2021
use ApiPlatform\Metadata\Operation;
2122
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2223
use ApiPlatform\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
2324
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
25+
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
2426
use ApiPlatform\OpenApi\Factory\OpenApiFactory;
2527
use ApiPlatform\Util\ResourceClassInfoTrait;
2628
use Symfony\Component\PropertyInfo\Type;
@@ -270,7 +272,14 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
270272
}
271273

272274
if (null === $operation) {
273-
$operation = $this->resourceMetadataFactory->create($className)->getOperation();
275+
$resourceMetadataCollection = $this->resourceMetadataFactory->create($className);
276+
try {
277+
$operation = $resourceMetadataCollection->getOperation();
278+
} catch (OperationNotFoundException $e) {
279+
$operation = new HttpOperation();
280+
}
281+
282+
$operation = $this->findOperationForType($resourceMetadataCollection, $type, $operation);
274283
} else {
275284
// The best here is to use an Operation when calling `buildSchema`, we try to do a smart guess otherwise
276285
if (!$operation->getClass()) {
@@ -279,20 +288,7 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
279288
if ($operation->getName()) {
280289
$operation = $resourceMetadataCollection->getOperation($operation->getName());
281290
} else {
282-
// Guess the operation and use the first one that matches criterias
283-
foreach ($resourceMetadataCollection as $resourceMetadata) {
284-
foreach ($resourceMetadata->getOperations() ?? [] as $op) {
285-
if ($operation instanceof CollectionOperationInterface && $op instanceof CollectionOperationInterface) {
286-
$operation = $op;
287-
break 2;
288-
}
289-
290-
if (Schema::TYPE_INPUT === $type && \in_array($op->getMethod(), ['POST', 'PATCH', 'PUT'], true)) {
291-
$operation = $op;
292-
break 2;
293-
}
294-
}
295-
}
291+
$operation = $this->findOperationForType($resourceMetadataCollection, $type, $operation);
296292
}
297293
}
298294
}
@@ -320,6 +316,26 @@ private function getMetadata(string $className, string $type = Schema::TYPE_OUTP
320316
];
321317
}
322318

319+
private function findOperationForType(ResourceMetadataCollection $resourceMetadataCollection, string $type, Operation $operation)
320+
{
321+
// Find the operation and use the first one that matches criterias
322+
foreach ($resourceMetadataCollection as $resourceMetadata) {
323+
foreach ($resourceMetadata->getOperations() ?? [] as $op) {
324+
if ($operation instanceof CollectionOperationInterface && $op instanceof CollectionOperationInterface) {
325+
$operation = $op;
326+
break 2;
327+
}
328+
329+
if (Schema::TYPE_INPUT === $type && \in_array($op->getMethod(), ['POST', 'PATCH', 'PUT'], true)) {
330+
$operation = $op;
331+
break 2;
332+
}
333+
}
334+
}
335+
336+
return $operation;
337+
}
338+
323339
private function getSerializerContext(Operation $operation, string $type = Schema::TYPE_OUTPUT): array
324340
{
325341
return Schema::TYPE_OUTPUT === $type ? ($operation->getNormalizationContext() ?? []) : ($operation->getDenormalizationContext() ?? []);

src/Metadata/Resource/ResourceMetadataCollection.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ public function getOperation(?string $operationName = null, bool $forceCollectio
8989
}
9090

9191
// Idea:
92-
// if ($metadata) {
93-
// return (new class extends HttpOperation {})->withResource($metadata);
94-
// }
92+
// if ($metadata) {
93+
// return (new class extends HttpOperation {})->withResource($metadata);
94+
// }
9595

9696
$this->handleNotFound($operationName, $metadata);
9797
}
@@ -102,7 +102,7 @@ public function getOperation(?string $operationName = null, bool $forceCollectio
102102
private function handleNotFound(string $operationName, ?ApiResource $metadata): void
103103
{
104104
// Hide the FQDN in the exception message if possible
105-
$shortName = $metadata ? $metadata->getShortName() : $this->resourceClass;
105+
$shortName = $metadata?->getShortName() ? $metadata->getShortName() : $this->resourceClass;
106106
if (!$metadata && false !== $pos = strrpos($shortName, '\\')) {
107107
$shortName = substr($shortName, $pos + 1);
108108
}

tests/Fixtures/TestBundle/Entity/JsonSchemaResourceRelated.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use ApiPlatform\Metadata\ApiResource;
1818

1919
#[ApiResource(
20-
shortName: 'RelatedResource',
20+
shortName: 'ResourceRelated',
2121
)]
2222
class JsonSchemaResourceRelated
2323
{

0 commit comments

Comments
 (0)