Bugfix/merged overrides missing operations (#18725)

| Q               | A
|-----------------|-----
| Branch?         | 1.14 <!-- see the comment below -->
| Bug fix?        | yes
| New feature?    | no
| BC breaks?      | no
| License         | MIT

<!--
 - Bug fixes must be submitted against the 1.14 or 2.1 branch
 - Features and deprecations must be submitted against the 2.2 branch
 - Make sure that the correct base branch is set

To be sure you are not breaking any Backward Compatibilities, check the
documentation:

https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html
-->
continuation of https://github.com/Sylius/Sylius/pull/16146
This commit is contained in:
Grzegorz Sadowski 2026-01-15 14:15:41 +01:00 committed by GitHub
commit 9aa9696278
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 104 additions and 3 deletions

View file

@ -31,6 +31,10 @@ final class LegacyResourceMetadataMerger implements MetadataMergerInterface
foreach ($newMetadata as $key => $value) {
if ('properties' === $key) {
if ($value === null) {
continue;
}
foreach ($value as $keyProperty => $property) {
$oldMetadata[$key][$keyProperty] = $property;
}
@ -55,7 +59,9 @@ final class LegacyResourceMetadataMerger implements MetadataMergerInterface
continue;
}
$oldMetadata[$key] = $value;
if ($value !== null) {
$oldMetadata[$key] = $value;
}
}
return $oldMetadata;

View file

@ -107,8 +107,8 @@ final class MergingXmlExtractor extends AbstractResourceExtractor implements Pro
$resourceMetadata,
);
$this->properties[$resourceClass] = array_merge(
$this->properties[$resourceClass],
$resourceMetadata['properties'],
$this->properties[$resourceClass] ?? [],
$resourceMetadata['properties'] ?? [],
);
continue;

View file

@ -170,6 +170,101 @@ final class LegacyResourceMetadataMergerSpec extends ObjectBehavior
]);
}
function it_keeps_existing_item_operations_when_the_new_one_doesnt_have_them(): void
{
$this->merge([
'itemOperations' => [
'get' => ['foo' => 'bar'],
],
], [
'itemOperations' => null,
])->shouldReturn([
'itemOperations' => [
'get' => ['foo' => 'bar'],
],
]);
}
function it_keeps_existing_collection_operations_when_the_new_one_doesnt_have_them(): void
{
$this->merge([
'collectionOperations' => [
'get' => ['foo' => 'bar'],
],
], [
'collectionOperations' => null,
])->shouldReturn([
'collectionOperations' => [
'get' => ['foo' => 'bar'],
],
]);
}
function it_keeps_existing_subresource_operations_when_the_new_one_doesnt_have_them(): void
{
$this->merge([
'subresourceOperations' => [
'get' => ['foo' => 'bar'],
],
], [
'subresourceOperations' => null,
])->shouldReturn([
'subresourceOperations' => [
'get' => ['foo' => 'bar'],
],
]);
}
function it_preserves_operations_when_extending_resource_with_only_properties(): void
{
// Simulates: XML extension defines only a new property without redefining operations
// This is what MergingXmlExtractor returns when XML has <property> but no <itemOperations>
$this->merge([
'shortName' => 'Order',
'itemOperations' => [
'get' => ['method' => 'GET', 'path' => '/orders/{id}'],
'put' => ['method' => 'PUT', 'path' => '/orders/{id}'],
'delete' => ['method' => 'DELETE', 'path' => '/orders/{id}'],
],
'collectionOperations' => [
'get' => ['method' => 'GET', 'path' => '/orders'],
'post' => ['method' => 'POST', 'path' => '/orders'],
],
'properties' => [
'id' => ['identifier' => true],
'number' => ['description' => 'Order number'],
],
], [
'shortName' => null,
'description' => null,
'iri' => null,
'itemOperations' => null,
'collectionOperations' => null,
'subresourceOperations' => null,
'graphql' => null,
'attributes' => null,
'properties' => [
'customField' => ['description' => 'Custom field added by extension'],
],
])->shouldReturn([
'shortName' => 'Order',
'itemOperations' => [
'get' => ['method' => 'GET', 'path' => '/orders/{id}'],
'put' => ['method' => 'PUT', 'path' => '/orders/{id}'],
'delete' => ['method' => 'DELETE', 'path' => '/orders/{id}'],
],
'collectionOperations' => [
'get' => ['method' => 'GET', 'path' => '/orders'],
'post' => ['method' => 'POST', 'path' => '/orders'],
],
'properties' => [
'id' => ['identifier' => true],
'number' => ['description' => 'Order number'],
'customField' => ['description' => 'Custom field added by extension'],
],
]);
}
function it_merges_complex_metadata(): void
{
$this->merge([