From 2339eead1f48de40b91b75907729926392ac8b20 Mon Sep 17 00:00:00 2001 From: soyuka Date: Fri, 13 Nov 2026 11:24:59 +0100 Subject: [PATCH 1/3] test(jsonschema): validation groups generator in definition name --- .../DefinitionNameValidationContextTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/Functional/JsonSchema/DefinitionNameValidationContextTest.php b/tests/Functional/JsonSchema/DefinitionNameValidationContextTest.php index f546adfa2b2..302c628407d 100644 --- a/tests/Functional/JsonSchema/DefinitionNameValidationContextTest.php +++ b/tests/Functional/JsonSchema/DefinitionNameValidationContextTest.php @@ -60,6 +60,19 @@ public function testValidationContextDefinitionsAreOrderIndependent(): void $this->assertContains('name', $groupsRequired, 'The POST with validationContext groups=["a"] must require "name", regardless of declaration order.'); } + public function testValidationGroupsGeneratorServiceIdIsNotALiteralGroup(): void + { + $json = self::createClient()->request('GET', '/docs', [ + 'headers' => ['Accept' => 'application/vnd.openapi+json'], + ])->toArray(); + + [$barePostName] = $this->postSchema($json, 'dummy_validation'); + [$generatorPostName] = $this->postSchema($json, 'dummy_validation/validation_sequence'); + + $this->assertStringNotContainsString('group_generator', $generatorPostName); + $this->assertSame($barePostName, $generatorPostName); + } + /** * @return array{0: string, 1: array} */ From 95dfaf2c0d1dbbdc143b10889ab6163dc4800722 Mon Sep 17 00:00:00 2001 From: soyuka Date: Fri, 13 Nov 2026 11:25:27 +0100 Subject: [PATCH 2/3] fix(jsonschema): ignore validation groups generator in definition name --- src/JsonSchema/DefinitionNameFactory.php | 6 +++--- src/JsonSchema/SchemaFactory.php | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/JsonSchema/DefinitionNameFactory.php b/src/JsonSchema/DefinitionNameFactory.php index 4b6e9dd14ce..3316da57e1a 100644 --- a/src/JsonSchema/DefinitionNameFactory.php +++ b/src/JsonSchema/DefinitionNameFactory.php @@ -107,9 +107,9 @@ private function getValidationGroupsPart(?Operation $operation): string return ''; } - $groups = \is_array($groups) ? $groups : [$groups]; - - if (\is_callable($groups)) { + if (\is_object($groups) && property_exists($groups, 'groups') && \is_array($groups->groups)) { + $groups = [$groups]; + } elseif (!\is_array($groups) || \is_callable($groups)) { return ''; } diff --git a/src/JsonSchema/SchemaFactory.php b/src/JsonSchema/SchemaFactory.php index d2b0da0ebe8..b1bc418b919 100644 --- a/src/JsonSchema/SchemaFactory.php +++ b/src/JsonSchema/SchemaFactory.php @@ -381,7 +381,11 @@ private function getValidationGroups(Operation $operation): array { $groups = $operation->getValidationContext()['groups'] ?? []; - return \is_array($groups) ? $groups : [$groups]; + if (\is_object($groups) && property_exists($groups, 'groups') && \is_array($groups->groups)) { + return [$groups]; + } + + return \is_array($groups) && !\is_callable($groups) ? $groups : []; } /** From 5f7f2f8ca24f461ff9f8635e5aae1a6ecfd365e0 Mon Sep 17 00:00:00 2001 From: soyuka Date: Fri, 13 Nov 2026 11:57:10 +0100 Subject: [PATCH 3/3] test(jsonschema): string and closure validation groups have no suffix --- src/JsonSchema/Tests/DefinitionNameFactoryTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/JsonSchema/Tests/DefinitionNameFactoryTest.php b/src/JsonSchema/Tests/DefinitionNameFactoryTest.php index a12eba4ef60..347c92dd4b5 100644 --- a/src/JsonSchema/Tests/DefinitionNameFactoryTest.php +++ b/src/JsonSchema/Tests/DefinitionNameFactoryTest.php @@ -127,13 +127,13 @@ public static function providerDefinitions(): iterable yield ['Dummy-read_validation.a', Dummy::class, 'json', null, new Post(validationContext: ['groups' => ['a']]), [AbstractNormalizer::GROUPS => ['read']]]; yield ['Dummy-read_a', Dummy::class, 'json', null, new Post(), [AbstractNormalizer::GROUPS => ['read', 'a']]]; - yield ['Dummy-validation.app.group_generator', Dummy::class, 'json', null, new Post(validationContext: ['groups' => 'app.group_generator'])]; + yield ['Dummy', Dummy::class, 'json', null, new Post(validationContext: ['groups' => 'app.group_generator'])]; yield ['Dummy-validation.seq1_seq2', Dummy::class, 'json', null, new Post(validationContext: ['groups' => self::groupSequence(['seq1', 'seq2'])])]; yield ['Dummy', Dummy::class, 'json', null, new Post(validationContext: ['groups' => [self::class, 'callableGroups']])]; - yield ['Dummy-validation.none', Dummy::class, 'json', null, new Post(validationContext: ['groups' => static fn (): array => ['x']])]; + yield ['Dummy', Dummy::class, 'json', null, new Post(validationContext: ['groups' => static fn (): array => ['x']])]; } public static function callableGroups(): array