mirror of
https://github.com/retailcrm/graphql-php.git
synced 2025-02-06 07:49:24 +03:00
Schema: getTypeMap() should include input types defined in directive arguments
This commit is contained in:
parent
0d93d190f8
commit
64c463e889
@ -157,6 +157,18 @@ class Directive
|
|||||||
*/
|
*/
|
||||||
public function __construct(array $config)
|
public function __construct(array $config)
|
||||||
{
|
{
|
||||||
|
if (isset($config['args'])) {
|
||||||
|
$args = [];
|
||||||
|
foreach ($config['args'] as $name => $arg) {
|
||||||
|
if (is_array($arg)) {
|
||||||
|
$args[] = FieldDefinition::create($arg + ['name' => $name]);
|
||||||
|
} else {
|
||||||
|
$args[] = $arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->args = $args;
|
||||||
|
unset($config['args']);
|
||||||
|
}
|
||||||
foreach ($config as $key => $value) {
|
foreach ($config as $key => $value) {
|
||||||
$this->{$key} = $value;
|
$this->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
@ -227,6 +227,11 @@ class Schema
|
|||||||
foreach ($this->resolvedTypes as $type) {
|
foreach ($this->resolvedTypes as $type) {
|
||||||
$typeMap = TypeInfo::extractTypes($type, $typeMap);
|
$typeMap = TypeInfo::extractTypes($type, $typeMap);
|
||||||
}
|
}
|
||||||
|
foreach ($this->getDirectives() as $directive) {
|
||||||
|
if ($directive instanceof Directive) {
|
||||||
|
$typeMap = TypeInfo::extractTypesFromDirectives($directive, $typeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
// When types are set as array they are resolved in constructor
|
// When types are set as array they are resolved in constructor
|
||||||
if (is_callable($this->config->types)) {
|
if (is_callable($this->config->types)) {
|
||||||
foreach ($this->resolveAdditionalTypes() as $type) {
|
foreach ($this->resolveAdditionalTypes() as $type) {
|
||||||
|
@ -140,6 +140,21 @@ class TypeInfo
|
|||||||
return $typeMap;
|
return $typeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Directive $directive
|
||||||
|
* @param array $typeMap
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function extractTypesFromDirectives(Directive $directive, array $typeMap = [])
|
||||||
|
{
|
||||||
|
if (is_array($directive->args)) {
|
||||||
|
foreach ($directive->args as $arg) {
|
||||||
|
$typeMap = self::extractTypes($arg->getType(), $typeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $typeMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not exactly the same as the executor's definition of getFieldDef, in this
|
* Not exactly the same as the executor's definition of getFieldDef, in this
|
||||||
* statically evaluated environment we do not always have an Object type,
|
* statically evaluated environment we do not always have an Object type,
|
||||||
|
120
tests/Type/SchemaTest.php
Normal file
120
tests/Type/SchemaTest.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
namespace GraphQL\Tests\Type;
|
||||||
|
|
||||||
|
use GraphQL\Error\InvariantViolation;
|
||||||
|
use GraphQL\Type\Definition\Directive;
|
||||||
|
use GraphQL\Type\Definition\InputObjectType;
|
||||||
|
use GraphQL\Type\Definition\InterfaceType;
|
||||||
|
use GraphQL\Type\Definition\ObjectType;
|
||||||
|
use GraphQL\Type\Definition\Type;
|
||||||
|
use GraphQL\Type\Schema;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class SchemaTest extends TestCase
|
||||||
|
{
|
||||||
|
private $interfaceType;
|
||||||
|
|
||||||
|
private $implementingType;
|
||||||
|
|
||||||
|
private $directiveInputType;
|
||||||
|
|
||||||
|
private $wrappedDirectiveInputType;
|
||||||
|
|
||||||
|
private $directive;
|
||||||
|
|
||||||
|
/** @var Schema */
|
||||||
|
private $schema;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->interfaceType = new InterfaceType([
|
||||||
|
'name' => 'Interface',
|
||||||
|
'fields' => ['fieldName' => ['type' => Type::string()]],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->implementingType = new ObjectType([
|
||||||
|
'name' => 'Object',
|
||||||
|
'interfaces' => [$this->interfaceType],
|
||||||
|
'fields' => ['fieldName' => ['type' => Type::string(), 'resolve' => function () {
|
||||||
|
return '';
|
||||||
|
}]],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->directiveInputType = new InputObjectType([
|
||||||
|
'name' => 'DirInput',
|
||||||
|
'fields' => [
|
||||||
|
'field' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->wrappedDirectiveInputType = new InputObjectType([
|
||||||
|
'name' => 'WrappedDirInput',
|
||||||
|
'fields' => [
|
||||||
|
'field' => [
|
||||||
|
'type' => Type::string(),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->directive = new Directive([
|
||||||
|
'name' => 'dir',
|
||||||
|
'locations' => ['OBJECT'],
|
||||||
|
'args' => [
|
||||||
|
'arg' => [
|
||||||
|
'type' => $this->directiveInputType,
|
||||||
|
],
|
||||||
|
'argList' => [
|
||||||
|
'type' => Type::listOf($this->wrappedDirectiveInputType),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->schema = new Schema([
|
||||||
|
'query' => new ObjectType([
|
||||||
|
'name' => 'Query',
|
||||||
|
'fields' => [
|
||||||
|
'getObject' => [
|
||||||
|
'type' => $this->interfaceType,
|
||||||
|
'resolve' => function () {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]),
|
||||||
|
'directives' => [$this->directive],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type System: Schema
|
||||||
|
// Getting possible types
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @it throws human-reable error if schema.types is not defined
|
||||||
|
*/
|
||||||
|
public function testThrowsHumanReableErrorIfSchemaTypesIsNotDefined()
|
||||||
|
{
|
||||||
|
$this->markTestSkipped("Can't check interface implementations without full schema scan");
|
||||||
|
|
||||||
|
$this->expectException(InvariantViolation::class);
|
||||||
|
$this->expectExceptionMessage(
|
||||||
|
'Could not find possible implementing types for Interface in schema. ' .
|
||||||
|
'Check that schema.types is defined and is an array of all possible ' .
|
||||||
|
'types in the schema.'
|
||||||
|
);
|
||||||
|
$this->schema->isPossibleType($this->interfaceType, $this->implementingType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type Map
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @it includes input types only used in directives
|
||||||
|
*/
|
||||||
|
public function testIncludesInputTypesOnlyUsedInDirectives()
|
||||||
|
{
|
||||||
|
$typeMap = $this->schema->getTypeMap();
|
||||||
|
$this->assertArrayHasKey('DirInput', $typeMap);
|
||||||
|
$this->assertArrayHasKey('WrappedDirInput', $typeMap);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user