diff --git a/src/FieldsBuilder.php b/src/FieldsBuilder.php index c1f5afd783..45a05d0cf6 100644 --- a/src/FieldsBuilder.php +++ b/src/FieldsBuilder.php @@ -17,6 +17,7 @@ use TheCodingMachine\GraphQLite\Annotations\SourceFieldInterface; use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeException; use TheCodingMachine\GraphQLite\Mappers\CannotMapTypeExceptionInterface; +use TheCodingMachine\GraphQLite\Mappers\DuplicateMappingException; use TheCodingMachine\GraphQLite\Mappers\Parameters\ParameterMiddlewareInterface; use TheCodingMachine\GraphQLite\Mappers\Parameters\TypeHandler; use TheCodingMachine\GraphQLite\Mappers\RecursiveTypeMapperInterface; @@ -31,6 +32,7 @@ use Webmozart\Assert\Assert; use function array_merge; use function array_shift; +use function array_values; use function get_parent_class; use function ucfirst; @@ -317,7 +319,10 @@ public function handle(QueryFieldDescriptor $fieldDescriptor): ?FieldDefinition }); if ($field !== null) { - $queryList[] = $field; + if (isset($queryList[$fieldDescriptor->getName()])) { + throw DuplicateMappingException::createForQuery($refClass->getName(), $fieldDescriptor->getName()); + } + $queryList[$fieldDescriptor->getName()] = $field; } /*if ($unauthorized) { @@ -332,7 +337,7 @@ public function handle(QueryFieldDescriptor $fieldDescriptor): ?FieldDefinition }*/ } - return $queryList; + return array_values($queryList); } /** diff --git a/src/Mappers/DuplicateMappingException.php b/src/Mappers/DuplicateMappingException.php index 912324aa0f..99270d24a8 100644 --- a/src/Mappers/DuplicateMappingException.php +++ b/src/Mappers/DuplicateMappingException.php @@ -23,4 +23,9 @@ public static function createForTypeName(string $type, string $sourceClass1, str { throw new self(sprintf("The type '%s' is created by 2 different classes: '%s' and '%s'", $type, $sourceClass1, $sourceClass2)); } + + public static function createForQuery(string $sourceClass, string $queryName): self + { + throw new self(sprintf("The query '%s' is duplicate in class '%s'", $queryName, $sourceClass)); + } } diff --git a/tests/Fixtures/DuplicateQueries/TestControllerWithDuplicateQuery.php b/tests/Fixtures/DuplicateQueries/TestControllerWithDuplicateQuery.php new file mode 100644 index 0000000000..6fd62a18f0 --- /dev/null +++ b/tests/Fixtures/DuplicateQueries/TestControllerWithDuplicateQuery.php @@ -0,0 +1,25 @@ +toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']); } + + public function testDuplicateQueryException(): void + { + $factory = new SchemaFactory( + new Psr16Cache(new ArrayAdapter()), + new BasicAutoWiringContainer( + new EmptyContainer() + ) + ); + $factory->setAuthenticationService(new VoidAuthenticationService()) + ->setAuthorizationService(new VoidAuthorizationService()) + ->addControllerNamespace('TheCodingMachine\\GraphQLite\\Fixtures\\DuplicateQueries') + ->addTypeNamespace('TheCodingMachine\\GraphQLite\\Fixtures\\Integration'); + + $this->expectException(DuplicateMappingException::class); + $schema = $factory->createSchema(); + $queryString = ' + query { + duplicateQuery + } + '; + GraphQL::executeQuery( + $schema, + $queryString + ); + } + }