Skip to content

Commit d008a59

Browse files
authored
Fix openapi sort #3996 (#4013)
1 parent 837dc48 commit d008a59

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/OpenApi/Serializer/OpenApiNormalizer.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,14 @@ private function recursiveClean($data): array
5454
continue;
5555
}
5656

57+
if ('schemas' === $key) {
58+
ksort($value);
59+
}
60+
5761
// Side effect of using getPaths(): Paths which itself contains the array
5862
if ('paths' === $key) {
5963
$value = $data['paths'] = $data['paths']['paths'];
64+
ksort($value);
6065
unset($data['paths']['paths']);
6166
}
6267

tests/OpenApi/Serializer/OpenApiNormalizerTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ class OpenApiNormalizerTest extends TestCase
5353
public function testNormalize()
5454
{
5555
$resourceNameCollectionFactoryProphecy = $this->prophesize(ResourceNameCollectionFactoryInterface::class);
56-
$resourceNameCollectionFactoryProphecy->create()->shouldBeCalled()->willReturn(new ResourceNameCollection([Dummy::class]));
56+
$resourceNameCollectionFactoryProphecy->create()->shouldBeCalled()->willReturn(new ResourceNameCollection([Dummy::class, 'Zorro']));
5757
$defaultContext = ['base_url' => '/app_dev.php/'];
5858
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
5959
$propertyNameCollectionFactoryProphecy->create(Dummy::class, Argument::any())->shouldBeCalled()->willReturn(new PropertyNameCollection(['id', 'name', 'description', 'dummyDate']));
60+
$propertyNameCollectionFactoryProphecy->create('Zorro', Argument::any())->shouldBeCalled()->willReturn(new PropertyNameCollection(['id']));
6061

6162
$dummyMetadata = new ResourceMetadata(
6263
'Dummy',
@@ -74,18 +75,34 @@ public function testNormalize()
7475
[]
7576
);
7677

78+
$zorroMetadata = new ResourceMetadata(
79+
'Zorro',
80+
'This is zorro.',
81+
'http://schema.example.com/Zorro',
82+
[
83+
'get' => ['method' => 'GET'] + self::OPERATION_FORMATS,
84+
],
85+
[
86+
'get' => ['method' => 'GET'] + self::OPERATION_FORMATS,
87+
],
88+
[]
89+
);
90+
7791
$subresourceOperationFactoryProphecy = $this->prophesize(SubresourceOperationFactoryInterface::class);
7892
$subresourceOperationFactoryProphecy->create(Argument::any(), Argument::any(), Argument::any())->willReturn([]);
7993

8094
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
8195
$resourceMetadataFactoryProphecy->create(Dummy::class)->shouldBeCalled()->willReturn($dummyMetadata);
96+
$resourceMetadataFactoryProphecy->create('Zorro')->shouldBeCalled()->willReturn($zorroMetadata);
8297

8398
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
8499
$propertyMetadataFactoryProphecy->create(Dummy::class, 'id', Argument::any())->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_INT), 'This is an id.', true, false, null, null, null, true, null, null, null, null, null, null, null, ['minLength' => 3, 'maxLength' => 20, 'pattern' => '^dummyPattern$']));
85100
$propertyMetadataFactoryProphecy->create(Dummy::class, 'name', Argument::any())->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_STRING), 'This is a name.', true, true, true, true, false, false, null, null, [], null, null, null, null));
86101
$propertyMetadataFactoryProphecy->create(Dummy::class, 'description', Argument::any())->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_STRING), 'This is an initializable but not writable property.', true, false, true, true, false, false, null, null, [], null, true));
87102
$propertyMetadataFactoryProphecy->create(Dummy::class, 'dummyDate', Argument::any())->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_OBJECT, true, \DateTime::class), 'This is a \DateTimeInterface object.', true, true, true, true, false, false, null, null, []));
88103

104+
$propertyMetadataFactoryProphecy->create('Zorro', 'id', Argument::any())->shouldBeCalled()->willReturn(new PropertyMetadata(new Type(Type::BUILTIN_TYPE_INT), 'This is an id.', true, false, null, null, null, true));
105+
89106
$operationPathResolver = new CustomOperationPathResolver(new OperationPathResolver(new UnderscorePathSegmentNameGenerator()));
90107
$filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
91108
$resourceMetadataFactory = $resourceMetadataFactoryProphecy->reveal();
@@ -165,5 +182,8 @@ public function testNormalize()
165182
// Security can be disabled per-operation using an empty array
166183
$this->assertEquals([], $openApiAsArray['paths']['/dummies']['post']['security']);
167184
$this->assertEquals(['url' => '/test'], $openApiAsArray['paths']['/dummies']['post']['servers']);
185+
186+
// Make sure things are sorted
187+
$this->assertEquals(array_keys($openApiAsArray['paths']), ['/dummies', '/dummies/{id}', '/zorros', '/zorros/{id}']);
168188
}
169189
}

0 commit comments

Comments
 (0)