Esempio n. 1
0
 public function testCustomTypes()
 {
     $authorType = null;
     $userInterface = new ObjectType(['name' => 'UserInterface', 'fields' => ['name' => new StringType()], 'resolveType' => function () use($authorType) {
         return $authorType;
     }]);
     $authorType = new ObjectType(['name' => 'Author', 'fields' => ['name' => new StringType()], 'interfaces' => [$userInterface]]);
     $schema = new Schema(['query' => new ObjectType(['name' => 'QueryType', 'fields' => ['user' => ['type' => $userInterface, 'resolve' => function () {
         return ['name' => 'Alex'];
     }]]])]);
     $schema->getTypesList()->addType($authorType);
     $processor = new Processor($schema);
     $processor->processPayload('{ user { name } }');
     $this->assertEquals(['data' => ['user' => ['name' => 'Alex']]], $processor->getResponseData());
     $processor->processPayload('{
                 __schema {
                     types {
                         name
                     }
                 }
             }');
     $data = $processor->getResponseData();
     $this->assertArraySubset([11 => ['name' => 'Author']], $data['data']['__schema']['types']);
     $processor->processPayload('{ user { name { } } }');
     $result = $processor->getResponseData();
     $this->assertEquals(['errors' => [['message' => 'Unexpected token "RBRACE"', 'locations' => [['line' => 1, 'column' => 19]]]]], $result);
     $processor->getExecutionContext()->clearErrors();
     $processor->processPayload('{ user { name { invalidSelection } } }');
     $result = $processor->getResponseData();
     $this->assertEquals(['data' => ['user' => null], 'errors' => [['message' => 'You can\'t specify fields for scalar type "String"', 'locations' => [['line' => 1, 'column' => 10]]]]], $result);
 }
Esempio n. 2
0
 public function testType()
 {
     $reportType = new ObjectType(['name' => 'Report', 'fields' => ['time' => new TestTimeType(), 'title' => new StringType()]]);
     $processor = new Processor(new Schema(['query' => new ObjectType(['name' => 'RootQueryType', 'fields' => ['latestReport' => ['type' => $reportType, 'resolve' => function () {
         return ['title' => 'Accident #1', 'time' => '13:30:12'];
     }]]])]));
     $processor->processPayload('{ latestReport { title, time} }');
     $this->assertEquals(['data' => ['latestReport' => ['title' => 'Accident #1', 'time' => '13:30:12']]], $processor->getResponseData());
 }
Esempio n. 3
0
 /**
  * @dataProvider queries
  *
  * @param $query
  * @param $expected
  */
 public function testDateInput($query, $expected)
 {
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['stringQuery' => ['type' => new StringType(), 'args' => ['from' => new DateTimeType(), 'fromtz' => new DateTimeTzType()], 'resolve' => function ($source, $args) {
         return sprintf('Result with %s date and %s tz', empty($args['from']) ? 'default' : $args['from'], empty($args['fromtz']) ? 'default' : $args['fromtz']);
     }]]])]);
     $processor = new Processor($schema);
     $processor->processPayload($query);
     $result = $processor->getResponseData();
     $this->assertEquals($expected, $result);
 }
Esempio n. 4
0
 /**
  * @dataProvider queries
  *
  * @param $query
  * @param $expected
  * @param $variables
  */
 public function testVariables($query, $expected, $variables)
 {
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['stringQuery' => ['type' => new StringType(), 'args' => ['sortOrder' => new StringType()], 'resolve' => function ($args) {
         return sprintf('Result with %s order', empty($args['sortOrder']) ? 'default' : $args['sortOrder']);
     }]]])]);
     $processor = new Processor($schema);
     $processor->processPayload($query, $variables);
     $result = $processor->getResponseData();
     $this->assertEquals($expected, $result);
 }
 public function testDefaultEnum()
 {
     $enumType = new EnumType(['name' => 'InternalStatus', 'values' => [['name' => 1, 'value' => 'ACTIVE'], ['name' => 0, 'value' => 'DISABLED']]]);
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['stringQuery' => ['type' => new StringType(), 'args' => ['statObject' => new InputObjectType(['name' => 'StatObjectType', 'fields' => ['status' => ['type' => $enumType, 'default' => 1], 'level' => new NonNullType(new IntType())]])], 'resolve' => function ($source, $args) {
         return sprintf('Result with level %s and status %s', $args['statObject']['level'], $args['statObject']['status']);
     }]]])]);
     $processor = new Processor($schema);
     $processor->processPayload('{ stringQuery(statObject: { level: 1 }) }');
     $result = $processor->getResponseData();
     $this->assertEquals(['data' => ['stringQuery' => 'Result with level 1 and status ACTIVE']], $result);
 }
Esempio n. 6
0
 public function testInvalidVariableType()
 {
     $processor = new Processor(new StarWarsSchema());
     $processor->processPayload('query($someId: Int){
             human(id: $someId) {
                 name
             }
         }');
     $data = $processor->getResponseData();
     $this->assertEquals($data, ['data' => ['human' => null], 'errors' => [['message' => 'Invalid variable "someId" type, allowed type is "ID"', 'locations' => [['line' => 1, 'column' => 7]]]]]);
 }
 /**
  * @inheritdoc
  */
 public function connect(Application $app)
 {
     /** @var ControllerCollection $controllers */
     $controllers = $app['controllers_factory'];
     $controllers->before(function (Request $request) {
         if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
             $data = json_decode($request->getContent(), true);
             $request->request->replace(is_array($data) ? $data : []);
         }
     })->match('/', function (Application $app, Request $request) {
         $query = $request->get('query', '');
         $variables = $request->get('variables', []);
         $processor = new Processor($this->schema);
         $processor->processPayload($query, $variables);
         return $app->json($processor->getResponseData());
     });
     return $controllers;
 }
Esempio n. 8
0
 /**
  * @dataProvider queries
  *
  * @param $query
  * @param $expected
  */
 public function testNullableResolving($query, $expected)
 {
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['nonNullScalar' => ['type' => new NonNullType(new IntType()), 'resolve' => function () {
         return null;
     }], 'nonNullList' => ['type' => new NonNullType(new ListType(new IntType())), 'resolve' => function () {
         return null;
     }], 'user' => ['type' => new NonNullType(new ObjectType(['name' => 'User', 'fields' => ['id' => new NonNullType(new IdType()), 'name' => new StringType()]])), 'resolve' => function () {
         return ['id' => new uid('6cfb044c-9c0a-4ddd-9ef8-a0b940818db3'), 'name' => 'Alex'];
     }], 'nonNullListOfNpnNull' => ['type' => new NonNullType(new ListType(new NonNullType(new IntType()))), 'resolve' => function () {
         return [1, null];
     }], 'nonNullArgument' => ['args' => ['ids' => new NonNullType(new ListType(new IntType()))], 'type' => new IntType(), 'resolve' => function () {
         return 1;
     }], 'nonNullArgument2' => ['args' => ['ids' => new NonNullType(new ListType(new NonNullType(new IntType())))], 'type' => new IntType(), 'resolve' => function () {
         return 1;
     }]]])]);
     $processor = new Processor($schema);
     $processor->processPayload($query);
     $result = $processor->getResponseData();
     $this->assertEquals($expected, $result);
 }
Esempio n. 9
0
 public function testLoad10k()
 {
     $time = microtime(true);
     $postType = new ObjectType(['name' => 'Post', 'fields' => ['id' => new IdType(), 'title' => new StringType(), 'authors' => ['type' => new ListType(new ObjectType(['name' => 'Author', 'fields' => ['name' => new StringType()]]))]]]);
     $data = [];
     for ($i = 1; $i <= 10000; ++$i) {
         $authors = [];
         while (count($authors) < rand(1, 4)) {
             $authors[] = ['name' => 'Author ' . substr(md5(time()), 0, 4)];
         }
         $data[] = ['id' => $i, 'title' => 'Title of ' . $i, 'authors' => $authors];
     }
     $p = new Processor(new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['posts' => ['type' => new ListType($postType), 'resolve' => function () use($data) {
         return $data;
     }]]])]));
     return true;
     $p->processPayload('{ posts { id, title, authors { name } } }');
     $res = $p->getResponseData();
     echo "Count: " . count($res['data']['posts']) . "\n";
     var_dump($res['data']['posts'][0]);
     printf("Test Time: %04f\n", microtime(true) - $time);
 }
Esempio n. 10
0
 public function testListInsideInputObject()
 {
     $processor = new Processor(new Schema(['query' => new ObjectType(['name' => 'RootQueryType', 'fields' => ['empty' => ['type' => new StringType(), 'resolve' => function () {
     }]]]), 'mutation' => new ObjectType(['name' => 'RootMutation', 'fields' => ['createList' => ['type' => new StringType(), 'args' => ['topArgument' => new InputObjectType(['name' => 'topArgument', 'fields' => ['postObject' => new ListType(new InputObjectType(['name' => 'postObject', 'fields' => ['title' => new NonNullType(new StringType())]]))]])], 'resolve' => function () {
         return 'success message';
     }]]])]));
     $processor->processPayload('mutation { createList(topArgument: { postObject:[ { title: null } ] })}');
     $this->assertEquals(['data' => ['createList' => null], 'errors' => [['message' => 'Not valid type for argument "topArgument" in query "createList"', 'locations' => [['line' => 1, 'column' => 23]]]]], $processor->getResponseData());
     $processor->getExecutionContext()->clearErrors();
     $processor->processPayload('mutation { createList(topArgument:{
                                     postObject:[{title: "not empty"}] })}');
     $this->assertEquals(['data' => ['createList' => 'success message']], $processor->getResponseData());
 }
Esempio n. 11
0
 public function testComplexityReducer()
 {
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['me' => ['type' => new ObjectType(['name' => 'User', 'fields' => ['firstName' => ['type' => new StringType(), 'args' => ['shorten' => new BooleanType()], 'resolve' => function ($value, $args) {
         return empty($args['shorten']) ? $value['firstName'] : $value['firstName'];
     }], 'lastName' => new StringType(), 'code' => new StringType(), 'likes' => ['type' => new IntType(), 'cost' => 10, 'resolve' => function () {
         return 42;
     }]]]), 'cost' => function ($args, $context, $childCost) {
         $argsCost = isset($args['cost']) ? $args['cost'] : 1;
         return 1 + $argsCost * $childCost;
     }, 'resolve' => function ($value, $args) {
         $data = ['firstName' => 'John', 'code' => '007'];
         return $data;
     }, 'args' => ['cost' => ['type' => new IntType(), 'default' => 1]]]]])]);
     $processor = new Processor($schema);
     $processor->setMaxComplexity(10);
     $processor->processPayload('{ me { firstName, lastName } }');
     $this->assertArrayNotHasKey('error', $processor->getResponseData());
     $processor->processPayload('{ me { } }');
     $this->assertEquals(['errors' => [['message' => 'Unexpected token "RBRACE"', 'locations' => [['line' => 1, 'column' => 10]]]]], $processor->getResponseData());
     $processor->getExecutionContext()->clearErrors();
     $processor->processPayload('{ me { firstName, likes } }');
     $this->assertEquals(['errors' => [['message' => 'query exceeded max allowed complexity of 10']]], $processor->getResponseData());
     $processor->getExecutionContext()->clearErrors();
     // don't let complexity reducer affect query errors
     $processor->processPayload('{ me { badfield } }');
     $this->assertArraySubset(['errors' => [['message' => 'Field "badfield" not found in type "User"']]], $processor->getResponseData());
     $processor->getExecutionContext()->clearErrors();
     foreach (range(1, 5) as $cost_multiplier) {
         $visitor = new MaxComplexityQueryVisitor(1000);
         // arbitrarily high cost
         $processor->processPayload("{ me (cost: {$cost_multiplier}) { firstName, lastName, code, likes } }", ['cost' => $cost_multiplier], [$visitor]);
         $expected = 1 + 13 * (1 + $cost_multiplier);
         $this->assertEquals($expected, $visitor->getMemo());
     }
     // TODO, variables not yet supported
     /*$query = 'query costQuery ($cost: Int) { me (cost: $cost) { firstName, lastName, code, likes } }';
       foreach (range(1,5) as $cost_multiplier) {
         $visitor = new \Youshido\GraphQL\Execution\Visitor\MaxComplexityQueryVisitor(1000); // arbitrarily high cost
         $processor->processPayload($query, ['cost' => $cost_multiplier], [$visitor]);
         $expected = 1 + 13 * (1 + $cost_multiplier);
         $this->assertEquals($expected, $visitor->getMemo());
       }*/
 }
Esempio n. 12
0
 public function testCombinedFields()
 {
     $schema = new TestEmptySchema();
     $interface = new InterfaceType(['name' => 'TestInterface', 'fields' => ['id' => ['type' => new IntType()], 'name' => ['type' => new IntType()]], 'resolveType' => function ($type) {
     }]);
     $object1 = new ObjectType(['name' => 'Test1', 'fields' => ['id' => ['type' => new IntType()], 'name' => ['type' => new IntType()], 'lastName' => ['type' => new IntType()]], 'interfaces' => [$interface]]);
     $object2 = new ObjectType(['name' => 'Test2', 'fields' => ['id' => ['type' => new IntType()], 'name' => ['type' => new IntType()], 'thirdName' => ['type' => new IntType()]], 'interfaces' => [$interface]]);
     $unionType = new UnionType(['name' => 'UnionType', 'types' => [$object1, $object2], 'resolveType' => function () {
     }]);
     $schema->addQueryField(new Field(['name' => 'union', 'type' => $unionType, 'args' => ['id' => ['type' => TypeMap::TYPE_INT]], 'resolve' => function () {
         return ['id' => 1, 'name' => 'Alex'];
     }]));
     $schema->addMutationField(new Field(['name' => 'mutation', 'type' => $unionType, 'args' => ['type' => new EnumType(['name' => 'MutationType', 'values' => [['name' => 'Type1', 'value' => 'type_1'], ['name' => 'Type2', 'value' => 'type_2']]])], 'resolve' => function () {
         return null;
     }]));
     $processor = new Processor($schema);
     $processor->processPayload($this->introspectionQuery);
     $responseData = $processor->getResponseData();
     /** strange that this test got broken after I fixed the field resolve behavior */
     $this->assertArrayNotHasKey('errors', $responseData);
 }
Esempio n. 13
0
<?php

namespace BlogTest;

header('Access-Control-Allow-Credentials: false', true);
header('Access-Control-Allow-Origin: *');
if ($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
    return;
}
use Examples\Blog\Schema\BlogSchema;
use Youshido\GraphQL\Execution\Processor;
use Youshido\GraphQL\Schema\Schema;
require_once __DIR__ . '/schema-bootstrap.php';
/** @var Schema $schema */
$schema = new BlogSchema();
if (isset($_SERVER['CONTENT_TYPE']) && $_SERVER['CONTENT_TYPE'] === 'application/json') {
    $rawBody = file_get_contents('php://input');
    $requestData = json_decode($rawBody ?: '', true);
} else {
    $requestData = $_POST;
}
$payload = isset($requestData['query']) ? $requestData['query'] : null;
$variables = isset($requestData['variables']) ? $requestData['variables'] : null;
$processor = new Processor($schema);
$response = $processor->processPayload($payload, $variables)->getResponseData();
header('Content-Type: application/json');
echo json_encode($response);
Esempio n. 14
0
<?php

namespace Sandbox;

use Youshido\GraphQL\Execution\Processor;
use Youshido\GraphQL\Schema\Schema;
use Youshido\GraphQL\Type\Object\ObjectType;
use Youshido\GraphQL\Type\Scalar\StringType;
require_once __DIR__ . '/../../../../../vendor/autoload.php';
$processor = new Processor(new Schema(['query' => new ObjectType(['name' => 'RootQueryType', 'fields' => ['currentTime' => ['type' => new StringType(), 'resolve' => function () {
    return date('Y-m-d H:ia');
}]]])]));
$processor->processPayload('{ currentTime }');
echo json_encode($processor->getResponseData()) . "\n";
Esempio n. 15
0
<?php

namespace BlogTest;

use Examples\Blog\Schema\BlogSchema;
use Youshido\GraphQL\Execution\Processor;
use Youshido\GraphQL\Schema\Schema;
require_once __DIR__ . '/schema-bootstrap.php';
/** @var Schema $schema */
$schema = new BlogSchema();
$processor = new Processor($schema);
$payload = 'mutation { likePost(id:5) { title(truncated: false), status, likeCount } }';
$payload = '{ latestPost { title, status, likeCount } }';
$payload = '{ pageContentUnion { ... on Post { title, summary } ... on Banner { title, imageLink } } }';
$payload = '{ pageContentInterface { title} }';
$payload = 'mutation { createPost(author: "Alex", post: {title: "Hey, this is my new post", summary: "my post" }) { title } }';
$processor->processPayload($payload);
echo json_encode($processor->getResponseData()) . "\n";
Esempio n. 16
0
 public function testSimpleFragment()
 {
     $schema = new Schema(['query' => new ObjectType(['name' => 'RootQuery', 'fields' => ['user' => ['type' => new UserType(), 'resolve' => function ($args) {
         return ['id' => 'user-id-1', 'fullName' => 'Alex'];
     }, 'args' => ['id' => new IntType()]]]])]);
     $query = '
     {
         User1: user(id: 1) {
             fullName
         }
         User2: user(id: 1) {
             ...Fields
         }
     }
     
     fragment Fields on User {
         fullName
     }';
     $processor = new Processor($schema);
     $processor->processPayload($query);
     $result = $processor->getResponseData();
     $expected = ['data' => ['User1' => ['fullName' => 'Alex'], 'User2' => ['fullName' => 'Alex']]];
     $this->assertEquals($expected, $result);
 }
Esempio n. 17
0
 protected function resolveQuery(Query $query)
 {
     $this->assertClientHasOperationAccess($query);
     return parent::resolveQuery($query);
 }
Esempio n. 18
0
<?php

namespace Examples\StarWars;

use Youshido\GraphQL\Execution\Processor;
use Youshido\GraphQL\Schema;
require_once __DIR__ . '/schema-bootstrap.php';
/** @var Schema\AbstractSchema $schema */
$schema = new StarWarsRelaySchema();
$processor = new Processor($schema);
$payload = '
            query StarWarsAppHomeRoute($names_0:[String]!) {
              factions(names:$names_0) {
                id,
                ...F2
              }
            }
            fragment F0 on Ship {
              id,
              name
            }
            fragment F1 on Faction {
              id,
              factionId
            }
            fragment F2 on Faction {
              id,
              factionId,
              name,
              _shipsDRnzJ:ships(first:10) {
                edges {