Skip to content

Commit 168ecff

Browse files
committed
fix: add missing OpenAPI properties for jsonapi type
1 parent 761f841 commit 168ecff

File tree

2 files changed

+69
-6
lines changed

2 files changed

+69
-6
lines changed

src/ApiDefinition/OpenApiDefinitionSchemaBuilderDecorator.php

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,19 @@
1717
use Shopware\Core\Framework\DataAbstractionLayer\Field\ManyToManyAssociationField;
1818
use Shopware\Core\Framework\DataAbstractionLayer\Field\OneToManyAssociationField;
1919
use Swh\SmartRelationSync\DataAbstractionLayer\WriteCommandExtractorDecorator;
20+
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
2021

2122
class OpenApiDefinitionSchemaBuilderDecorator extends OpenApiDefinitionSchemaBuilder
2223
{
24+
private readonly CamelCaseToSnakeCaseNameConverter $converter;
25+
26+
public function __construct()
27+
{
28+
parent::__construct();
29+
30+
$this->converter = new CamelCaseToSnakeCaseNameConverter(null, false);
31+
}
32+
2333
/**
2434
* @return Schema[]
2535
*/
@@ -32,15 +42,15 @@ public function getSchemaByDefinition(
3242
): array {
3343
$schemas = parent::getSchemaByDefinition($definition, $path, $forSalesChannel, $onlyFlat, $apiType);
3444

35-
if (count($schemas) !== 1) {
45+
$relevantSchemas = $this->getRelevantSchemas($schemas, $definition);
46+
47+
if (count($relevantSchemas) === 0) {
3648
return $schemas;
3749
}
3850

3951
$relevantFields = $definition->getFields()
4052
->filter(fn(Field $field) => $this->isRelevantField($field));
4153

42-
$schema = current($schemas);
43-
4454
foreach ($relevantFields as $field) {
4555
if (!$this->shouldFieldBeIncluded($field, $forSalesChannel)) {
4656
continue;
@@ -53,12 +63,46 @@ public function getSchemaByDefinition(
5363
'type' => 'boolean',
5464
]);
5565

56-
$schema->properties[] = $property;
66+
foreach ($relevantSchemas as $schema) {
67+
$schema->properties[] = $property;
68+
}
5769
}
5870

5971
return $schemas;
6072
}
6173

74+
/**
75+
* @param Schema[] $schemas
76+
*
77+
* @return Schema[]
78+
*/
79+
private function getRelevantSchemas(array $schemas, EntityDefinition $definition): array
80+
{
81+
$schemaName = $this->snakeCaseToCamelCase($definition->getEntityName());
82+
83+
if (!array_key_exists($schemaName, $schemas)) {
84+
return [];
85+
}
86+
87+
$relevantSchemas = [$schemas[$schemaName]];
88+
89+
$schemaNameJsonApi = $schemaName . 'JsonApi';
90+
91+
if (!array_key_exists($schemaNameJsonApi, $schemas)) {
92+
return $relevantSchemas;
93+
}
94+
95+
$jsonApiSchema = $schemas[$schemaNameJsonApi];
96+
97+
$childSchema = $jsonApiSchema->allOf[1] ?? null;
98+
99+
if ($childSchema instanceof Schema) {
100+
$relevantSchemas[] = $childSchema;
101+
}
102+
103+
return $relevantSchemas;
104+
}
105+
62106
/**
63107
* @phpstan-assert-if-true ManyToManyAssociationField|OneToManyAssociationField $field
64108
*/
@@ -91,4 +135,9 @@ private function shouldFieldBeIncluded(Field $field, bool $forSalesChannel): boo
91135

92136
return true;
93137
}
138+
139+
private function snakeCaseToCamelCase(string $input): string
140+
{
141+
return $this->converter->denormalize($input);
142+
}
94143
}

tests/Functional/ApiDefinition/OpenApiDefinitionSchemaBuilderDecoratorTest.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,33 @@
44

55
namespace Swh\SmartRelationSync\Tests\Functional\ApiDefinition;
66

7+
use PHPUnit\Framework\Attributes\DataProvider;
78
use PHPUnit\Framework\TestCase;
9+
use Shopware\Core\Framework\Api\ApiDefinition\DefinitionService;
810
use Shopware\Core\Framework\Test\TestCaseBase\AdminFunctionalTestBehaviour;
911
use Symfony\Component\HttpFoundation\JsonResponse;
1012

1113
class OpenApiDefinitionSchemaBuilderDecoratorTest extends TestCase
1214
{
1315
use AdminFunctionalTestBehaviour;
1416

15-
public function testApiSchemaReturnsExpectedProperties(): void
17+
/**
18+
* @return non-empty-array<non-empty-string>[]
19+
*/
20+
public static function provideOpenApiTypes(): array
21+
{
22+
return [
23+
[DefinitionService::TYPE_JSON],
24+
[DefinitionService::TYPE_JSON_API],
25+
];
26+
}
27+
28+
#[DataProvider('provideOpenApiTypes')]
29+
public function testApiSchemaReturnsExpectedProperties(string $type): void
1630
{
1731
$this->getBrowser()->jsonRequest(
1832
'GET',
19-
'/api/_info/openapi3.json?type=json',
33+
'/api/_info/openapi3.json?type=' . $type,
2034
);
2135

2236
$response = $this->getBrowser()->getResponse();

0 commit comments

Comments
 (0)