Merge pull request #340 from simPod/cs-language-server

Fix CS in tests/Server
This commit is contained in:
Vladimir Razuvaev 2018-09-02 21:23:47 +07:00 committed by GitHub
commit ce0272b447
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 719 additions and 654 deletions

View File

@ -1,9 +1,13 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server\Psr7; namespace GraphQL\Tests\Server\Psr7;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface; use Psr\Http\Message\UriInterface;
use function strtolower;
class PsrRequestStub implements ServerRequestInterface class PsrRequestStub implements ServerRequestInterface
{ {
@ -13,14 +17,10 @@ class PsrRequestStub implements ServerRequestInterface
public $method; public $method;
/** /** @var PsrStreamStub */
* @var PsrStreamStub
*/
public $body; public $body;
/** /** @var mixed[] */
* @var array
*/
public $parsedBody; public $parsedBody;
/** /**
@ -32,7 +32,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getProtocolVersion() public function getProtocolVersion()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -50,7 +50,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withProtocolVersion($version) public function withProtocolVersion($version)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -80,7 +80,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getHeaders() public function getHeaders()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -93,7 +93,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function hasHeader($name) public function hasHeader($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -113,7 +113,8 @@ class PsrRequestStub implements ServerRequestInterface
public function getHeader($name) public function getHeader($name)
{ {
$name = strtolower($name); $name = strtolower($name);
return isset($this->headers[$name]) ? $this->headers[$name] : [];
return $this->headers[$name] ?? [];
} }
/** /**
@ -137,7 +138,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getHeaderLine($name) public function getHeaderLine($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -157,7 +158,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withHeader($name, $value) public function withHeader($name, $value)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -178,7 +179,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withAddedHeader($name, $value) public function withAddedHeader($name, $value)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -195,7 +196,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withoutHeader($name) public function withoutHeader($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -223,7 +224,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withBody(StreamInterface $body) public function withBody(StreamInterface $body)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -244,7 +245,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getRequestTarget() public function getRequestTarget()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -266,7 +267,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withRequestTarget($requestTarget) public function withRequestTarget($requestTarget)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -296,7 +297,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withMethod($method) public function withMethod($method)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -345,7 +346,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withUri(UriInterface $uri, $preserveHost = false) public function withUri(UriInterface $uri, $preserveHost = false)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -359,7 +360,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getServerParams() public function getServerParams()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -374,7 +375,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getCookieParams() public function getCookieParams()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -396,7 +397,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withCookieParams(array $cookies) public function withCookieParams(array $cookies)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -440,7 +441,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withQueryParams(array $query) public function withQueryParams(array $query)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -457,7 +458,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getUploadedFiles() public function getUploadedFiles()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -473,7 +474,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withUploadedFiles(array $uploadedFiles) public function withUploadedFiles(array $uploadedFiles)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -526,7 +527,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withParsedBody($data) public function withParsedBody($data)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -542,7 +543,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getAttributes() public function getAttributes()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -562,7 +563,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function getAttribute($name, $default = null) public function getAttribute($name, $default = null)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -582,7 +583,7 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withAttribute($name, $value) public function withAttribute($name, $value)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -601,6 +602,6 @@ class PsrRequestStub implements ServerRequestInterface
*/ */
public function withoutAttribute($name) public function withoutAttribute($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
} }

View File

@ -1,6 +1,8 @@
<?php <?php
namespace GraphQL\Tests\Server\Psr7;
declare(strict_types=1);
namespace GraphQL\Tests\Server\Psr7;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
@ -22,7 +24,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getProtocolVersion() public function getProtocolVersion()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -40,7 +42,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function withProtocolVersion($version) public function withProtocolVersion($version)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -70,7 +72,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getHeaders() public function getHeaders()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -83,7 +85,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function hasHeader($name) public function hasHeader($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -102,7 +104,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getHeader($name) public function getHeader($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -126,7 +128,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getHeaderLine($name) public function getHeaderLine($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -148,6 +150,7 @@ class PsrResponseStub implements ResponseInterface
{ {
$tmp = clone $this; $tmp = clone $this;
$tmp->headers[$name][] = $value; $tmp->headers[$name][] = $value;
return $tmp; return $tmp;
} }
@ -169,7 +172,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function withAddedHeader($name, $value) public function withAddedHeader($name, $value)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -186,7 +189,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function withoutHeader($name) public function withoutHeader($name)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -196,7 +199,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getBody() public function getBody()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -216,6 +219,7 @@ class PsrResponseStub implements ResponseInterface
{ {
$tmp = clone $this; $tmp = clone $this;
$tmp->body = $body; $tmp->body = $body;
return $tmp; return $tmp;
} }
@ -229,7 +233,7 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getStatusCode() public function getStatusCode()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -256,6 +260,7 @@ class PsrResponseStub implements ResponseInterface
{ {
$tmp = clone $this; $tmp = clone $this;
$tmp->statusCode = $code; $tmp->statusCode = $code;
return $tmp; return $tmp;
} }
@ -274,6 +279,6 @@ class PsrResponseStub implements ResponseInterface
*/ */
public function getReasonPhrase() public function getReasonPhrase()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
} }

View File

@ -1,7 +1,12 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server\Psr7; namespace GraphQL\Tests\Server\Psr7;
use Psr\Http\Message\StreamInterface; use Psr\Http\Message\StreamInterface;
use function strlen;
use const SEEK_SET;
class PsrStreamStub implements StreamInterface class PsrStreamStub implements StreamInterface
{ {
@ -33,7 +38,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function close() public function close()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -45,7 +50,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function detach() public function detach()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -55,7 +60,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function getSize() public function getSize()
{ {
return strlen($this->content?:''); return strlen($this->content ?: '');
} }
/** /**
@ -66,7 +71,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function tell() public function tell()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -76,7 +81,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function eof() public function eof()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -86,7 +91,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function isSeekable() public function isSeekable()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -103,7 +108,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function seek($offset, $whence = SEEK_SET) public function seek($offset, $whence = SEEK_SET)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -118,7 +123,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function rewind() public function rewind()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -141,6 +146,7 @@ class PsrStreamStub implements StreamInterface
public function write($string) public function write($string)
{ {
$this->content = $string; $this->content = $string;
return strlen($string); return strlen($string);
} }
@ -151,7 +157,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function isReadable() public function isReadable()
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -166,7 +172,7 @@ class PsrStreamStub implements StreamInterface
*/ */
public function read($length) public function read($length)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
/** /**
@ -195,6 +201,6 @@ class PsrStreamStub implements StreamInterface
*/ */
public function getMetadata($key = null) public function getMetadata($key = null)
{ {
throw new \Exception("Not implemented"); throw new \Exception('Not implemented');
} }
} }

View File

@ -1,11 +1,15 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Executor\ExecutionResult; use GraphQL\Executor\ExecutionResult;
use GraphQL\Server\Helper; use GraphQL\Server\Helper;
use GraphQL\Tests\Server\Psr7\PsrStreamStub;
use GraphQL\Tests\Server\Psr7\PsrResponseStub; use GraphQL\Tests\Server\Psr7\PsrResponseStub;
use GraphQL\Tests\Server\Psr7\PsrStreamStub;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function json_encode;
class PsrResponseTest extends TestCase class PsrResponseTest extends TestCase
{ {

View File

@ -1,11 +1,12 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Deferred;
use GraphQL\Error\Debug; use GraphQL\Error\Debug;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Error\UserError;
use GraphQL\Executor\ExecutionResult; use GraphQL\Executor\ExecutionResult;
use GraphQL\Language\AST\DocumentNode; use GraphQL\Language\AST\DocumentNode;
use GraphQL\Language\Parser; use GraphQL\Language\Parser;
@ -16,12 +17,12 @@ use GraphQL\Server\ServerConfig;
use GraphQL\Validator\DocumentValidator; use GraphQL\Validator\DocumentValidator;
use GraphQL\Validator\Rules\CustomValidationRule; use GraphQL\Validator\Rules\CustomValidationRule;
use GraphQL\Validator\ValidationContext; use GraphQL\Validator\ValidationContext;
use function count;
use function sprintf;
class QueryExecutionTest extends ServerTestCase class QueryExecutionTest extends ServerTestCase
{ {
/** /** @var ServerConfig */
* @var ServerConfig
*/
private $config; private $config;
public function setUp() public function setUp()
@ -36,14 +37,30 @@ class QueryExecutionTest extends ServerTestCase
$query = '{f1}'; $query = '{f1}';
$expected = [ $expected = [
'data' => [ 'data' => ['f1' => 'f1'],
'f1' => 'f1'
]
]; ];
$this->assertQueryResultEquals($expected, $query); $this->assertQueryResultEquals($expected, $query);
} }
private function assertQueryResultEquals($expected, $query, $variables = null)
{
$result = $this->executeQuery($query, $variables);
$this->assertArraySubset($expected, $result->toArray(true));
return $result;
}
private function executeQuery($query, $variables = null, $readonly = false)
{
$op = OperationParams::create(['query' => $query, 'variables' => $variables], $readonly);
$helper = new Helper();
$result = $helper->executeOperation($this->config, $op);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
public function testReturnsSyntaxErrors() : void public function testReturnsSyntaxErrors() : void
{ {
$query = '{f1'; $query = '{f1';
@ -72,15 +89,15 @@ class QueryExecutionTest extends ServerTestCase
$expected = [ $expected = [
'data' => [ 'data' => [
'fieldWithException' => null, 'fieldWithException' => null,
'f1' => 'f1' 'f1' => 'f1',
], ],
'errors' => [ 'errors' => [
[ [
'message' => 'This is the exception we want', 'message' => 'This is the exception we want',
'path' => ['fieldWithException'], 'path' => ['fieldWithException'],
'trace' => [] 'trace' => [],
] ],
] ],
]; ];
$result = $this->executeQuery($query)->toArray(); $result = $this->executeQuery($query)->toArray();
@ -102,7 +119,7 @@ class QueryExecutionTest extends ServerTestCase
} }
'; ';
$this->assertTrue(!isset($context->testedRootValue)); $this->assertTrue(! isset($context->testedRootValue));
$this->executeQuery($query); $this->executeQuery($query);
$this->assertSame($rootValue, $context->testedRootValue); $this->assertSame($rootValue, $context->testedRootValue);
} }
@ -119,8 +136,8 @@ class QueryExecutionTest extends ServerTestCase
$expected = [ $expected = [
'data' => [ 'data' => [
'a' => 'a', 'a' => 'a',
'b' => 'b' 'b' => 'b',
] ],
]; ];
$this->assertQueryResultEquals($expected, $query, $variables); $this->assertQueryResultEquals($expected, $query, $variables);
} }
@ -132,8 +149,8 @@ class QueryExecutionTest extends ServerTestCase
'; ';
$expected = [ $expected = [
'errors' => [ 'errors' => [
['message' => 'Cannot query field "nonExistentField" on type "Query".'] ['message' => 'Cannot query field "nonExistentField" on type "Query".'],
] ],
]; ];
$this->assertQueryResultEquals($expected, $query); $this->assertQueryResultEquals($expected, $query);
@ -141,15 +158,16 @@ class QueryExecutionTest extends ServerTestCase
$called = false; $called = false;
$rules = [ $rules = [
new CustomValidationRule('SomeRule', function() use (&$called) { new CustomValidationRule('SomeRule', function () use (&$called) {
$called = true; $called = true;
return []; return [];
}) }),
]; ];
$this->config->setValidationRules($rules); $this->config->setValidationRules($rules);
$expected = [ $expected = [
'data' => [] 'data' => [],
]; ];
$this->assertQueryResultEquals($expected, $query); $this->assertQueryResultEquals($expected, $query);
$this->assertTrue($called); $this->assertTrue($called);
@ -160,11 +178,12 @@ class QueryExecutionTest extends ServerTestCase
$called = false; $called = false;
$params = $doc = $operationType = null; $params = $doc = $operationType = null;
$this->config->setValidationRules(function($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) { $this->config->setValidationRules(function ($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) {
$called = true; $called = true;
$params = $p; $params = $p;
$doc = $d; $doc = $d;
$operationType = $o; $operationType = $o;
return []; return [];
}); });
@ -183,18 +202,20 @@ class QueryExecutionTest extends ServerTestCase
$called1 = false; $called1 = false;
$called2 = false; $called2 = false;
$this->config->setValidationRules(function(OperationParams $params) use ($q1, $q2, &$called1, &$called2) { $this->config->setValidationRules(function (OperationParams $params) use ($q1, $q2, &$called1, &$called2) {
if ($params->query === $q1) { if ($params->query === $q1) {
$called1 = true; $called1 = true;
return DocumentValidator::allRules(); return DocumentValidator::allRules();
} else {
$called2 = true;
return [
new CustomValidationRule('MyRule', function(ValidationContext $context) {
$context->reportError(new Error("This is the error we are looking for!"));
})
];
} }
$called2 = true;
return [
new CustomValidationRule('MyRule', function (ValidationContext $context) {
$context->reportError(new Error('This is the error we are looking for!'));
}),
];
}); });
$expected = ['data' => ['f1' => 'f1']]; $expected = ['data' => ['f1' => 'f1']];
@ -226,22 +247,28 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'message' => 'Persisted queries are not supported by this server', 'message' => 'Persisted queries are not supported by this server',
'category' => 'request' 'category' => 'request',
] ],
] ],
]; ];
$this->assertEquals($expected, $result->toArray()); $this->assertEquals($expected, $result->toArray());
} }
private function executePersistedQuery($queryId, $variables = null)
{
$op = OperationParams::create(['queryId' => $queryId, 'variables' => $variables]);
$helper = new Helper();
$result = $helper->executeOperation($this->config, $op);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
public function testBatchedQueriesAreDisabledByDefault() : void public function testBatchedQueriesAreDisabledByDefault() : void
{ {
$batch = [ $batch = [
[ ['query' => '{invalid}'],
'query' => '{invalid}' ['query' => '{f1,fieldWithException}'],
],
[
'query' => '{f1,fieldWithException}'
]
]; ];
$result = $this->executeBatchedQuery($batch); $result = $this->executeBatchedQuery($batch);
@ -251,17 +278,17 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'message' => 'Batched queries are not supported by this server', 'message' => 'Batched queries are not supported by this server',
'category' => 'request' 'category' => 'request',
] ],
] ],
], ],
[ [
'errors' => [ 'errors' => [
[ [
'message' => 'Batched queries are not supported by this server', 'message' => 'Batched queries are not supported by this server',
'category' => 'request' 'category' => 'request',
] ],
] ],
], ],
]; ];
@ -269,6 +296,31 @@ class QueryExecutionTest extends ServerTestCase
$this->assertEquals($expected[1], $result[1]->toArray()); $this->assertEquals($expected[1], $result[1]->toArray());
} }
/**
* @param mixed[][] $qs
*/
private function executeBatchedQuery(array $qs)
{
$batch = [];
foreach ($qs as $params) {
$batch[] = OperationParams::create($params);
}
$helper = new Helper();
$result = $helper->executeBatch($this->config, $batch);
$this->assertInternalType('array', $result);
$this->assertCount(count($qs), $result);
foreach ($result as $index => $entry) {
$this->assertInstanceOf(
ExecutionResult::class,
$entry,
sprintf('Result at %s is not an instance of %s', $index, ExecutionResult::class)
);
}
return $result;
}
public function testMutationsAreNotAllowedInReadonlyMode() : void public function testMutationsAreNotAllowedInReadonlyMode() : void
{ {
$mutation = 'mutation { a }'; $mutation = 'mutation { a }';
@ -277,9 +329,9 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'message' => 'GET supports only query operation', 'message' => 'GET supports only query operation',
'category' => 'request' 'category' => 'request',
] ],
] ],
]; ];
$result = $this->executeQuery($mutation, null, true); $result = $this->executeQuery($mutation, null, true);
@ -289,9 +341,10 @@ class QueryExecutionTest extends ServerTestCase
public function testAllowsPersistentQueries() : void public function testAllowsPersistentQueries() : void
{ {
$called = false; $called = false;
$this->config->setPersistentQueryLoader(function($queryId, OperationParams $params) use (&$called) { $this->config->setPersistentQueryLoader(function ($queryId, OperationParams $params) use (&$called) {
$called = true; $called = true;
$this->assertEquals('some-id', $queryId); $this->assertEquals('some-id', $queryId);
return '{f1}'; return '{f1}';
}); });
@ -299,17 +352,16 @@ class QueryExecutionTest extends ServerTestCase
$this->assertTrue($called); $this->assertTrue($called);
$expected = [ $expected = [
'data' => [ 'data' => ['f1' => 'f1'],
'f1' => 'f1'
]
]; ];
$this->assertEquals($expected, $result->toArray()); $this->assertEquals($expected, $result->toArray());
// Make sure it allows returning document node: // Make sure it allows returning document node:
$called = false; $called = false;
$this->config->setPersistentQueryLoader(function($queryId, OperationParams $params) use (&$called) { $this->config->setPersistentQueryLoader(function ($queryId, OperationParams $params) use (&$called) {
$called = true; $called = true;
$this->assertEquals('some-id', $queryId); $this->assertEquals('some-id', $queryId);
return Parser::parse('{f1}'); return Parser::parse('{f1}');
}); });
$result = $this->executePersistedQuery('some-id'); $result = $this->executePersistedQuery('some-id');
@ -324,7 +376,7 @@ class QueryExecutionTest extends ServerTestCase
'Persistent query loader must return query string or instance of GraphQL\Language\AST\DocumentNode ' . 'Persistent query loader must return query string or instance of GraphQL\Language\AST\DocumentNode ' .
'but got: {"err":"err"}' 'but got: {"err":"err"}'
); );
$this->config->setPersistentQueryLoader(function($queryId, OperationParams $params) use (&$called) { $this->config->setPersistentQueryLoader(function ($queryId, OperationParams $params) use (&$called) {
return ['err' => 'err']; return ['err' => 'err'];
}); });
$this->executePersistedQuery('some-id'); $this->executePersistedQuery('some-id');
@ -332,7 +384,7 @@ class QueryExecutionTest extends ServerTestCase
public function testPersistedQueriesAreStillValidatedByDefault() : void public function testPersistedQueriesAreStillValidatedByDefault() : void
{ {
$this->config->setPersistentQueryLoader(function() { $this->config->setPersistentQueryLoader(function () {
return '{invalid}'; return '{invalid}';
}); });
$result = $this->executePersistedQuery('some-id'); $result = $this->executePersistedQuery('some-id');
@ -340,36 +392,35 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'message' => 'Cannot query field "invalid" on type "Query".', 'message' => 'Cannot query field "invalid" on type "Query".',
'locations' => [ ['line' => 1, 'column' => 2] ], 'locations' => [['line' => 1, 'column' => 2]],
'category' => 'graphql' 'category' => 'graphql',
] ],
] ],
]; ];
$this->assertEquals($expected, $result->toArray()); $this->assertEquals($expected, $result->toArray());
} }
public function testAllowSkippingValidationForPersistedQueries() : void public function testAllowSkippingValidationForPersistedQueries() : void
{ {
$this->config $this->config
->setPersistentQueryLoader(function($queryId) { ->setPersistentQueryLoader(function ($queryId) {
if ($queryId === 'some-id') { if ($queryId === 'some-id') {
return '{invalid}'; return '{invalid}';
} else {
return '{invalid2}';
} }
return '{invalid2}';
}) })
->setValidationRules(function(OperationParams $params) { ->setValidationRules(function (OperationParams $params) {
if ($params->queryId === 'some-id') { if ($params->queryId === 'some-id') {
return []; return [];
} else {
return DocumentValidator::allRules();
} }
return DocumentValidator::allRules();
}); });
$result = $this->executePersistedQuery('some-id'); $result = $this->executePersistedQuery('some-id');
$expected = [ $expected = [
'data' => [] 'data' => [],
]; ];
$this->assertEquals($expected, $result->toArray()); $this->assertEquals($expected, $result->toArray());
@ -378,10 +429,10 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'message' => 'Cannot query field "invalid2" on type "Query".', 'message' => 'Cannot query field "invalid2" on type "Query".',
'locations' => [ ['line' => 1, 'column' => 2] ], 'locations' => [['line' => 1, 'column' => 2]],
'category' => 'graphql' 'category' => 'graphql',
] ],
] ],
]; ];
$this->assertEquals($expected, $result->toArray()); $this->assertEquals($expected, $result->toArray());
} }
@ -390,7 +441,7 @@ class QueryExecutionTest extends ServerTestCase
{ {
$this->expectException(InvariantViolation::class); $this->expectException(InvariantViolation::class);
$this->expectExceptionMessage('Expecting validation rules to be array or callable returning array, but got: instance of stdClass'); $this->expectExceptionMessage('Expecting validation rules to be array or callable returning array, but got: instance of stdClass');
$this->config->setValidationRules(function(OperationParams $params) { $this->config->setValidationRules(function (OperationParams $params) {
return new \stdClass(); return new \stdClass();
}); });
$this->executeQuery('{f1}'); $this->executeQuery('{f1}');
@ -401,12 +452,8 @@ class QueryExecutionTest extends ServerTestCase
$this->config->setQueryBatching(true); $this->config->setQueryBatching(true);
$batch = [ $batch = [
[ ['query' => '{invalid}'],
'query' => '{invalid}' ['query' => '{f1,fieldWithException}'],
],
[
'query' => '{f1,fieldWithException}'
],
[ [
'query' => ' 'query' => '
query ($a: String!, $b: String!) { query ($a: String!, $b: String!) {
@ -415,30 +462,30 @@ class QueryExecutionTest extends ServerTestCase
} }
', ',
'variables' => ['a' => 'a', 'b' => 'b'], 'variables' => ['a' => 'a', 'b' => 'b'],
] ],
]; ];
$result = $this->executeBatchedQuery($batch); $result = $this->executeBatchedQuery($batch);
$expected = [ $expected = [
[ [
'errors' => [['message' => 'Cannot query field "invalid" on type "Query".']] 'errors' => [['message' => 'Cannot query field "invalid" on type "Query".']],
], ],
[ [
'data' => [ 'data' => [
'f1' => 'f1', 'f1' => 'f1',
'fieldWithException' => null 'fieldWithException' => null,
], ],
'errors' => [ 'errors' => [
['message' => 'This is the exception we want'] ['message' => 'This is the exception we want'],
] ],
], ],
[ [
'data' => [ 'data' => [
'a' => 'a', 'a' => 'a',
'b' => 'b' 'b' => 'b',
] ],
] ],
]; ];
$this->assertArraySubset($expected[0], $result[0]->toArray()); $this->assertArraySubset($expected[0], $result[0]->toArray());
@ -449,15 +496,9 @@ class QueryExecutionTest extends ServerTestCase
public function testDeferredsAreSharedAmongAllBatchedQueries() : void public function testDeferredsAreSharedAmongAllBatchedQueries() : void
{ {
$batch = [ $batch = [
[ ['query' => '{dfd(num: 1)}'],
'query' => '{dfd(num: 1)}' ['query' => '{dfd(num: 2)}'],
], ['query' => '{dfd(num: 3)}'],
[
'query' => '{dfd(num: 2)}'
],
[
'query' => '{dfd(num: 3)}',
]
]; ];
$calls = []; $calls = [];
@ -466,13 +507,14 @@ class QueryExecutionTest extends ServerTestCase
->setQueryBatching(true) ->setQueryBatching(true)
->setRootValue('1') ->setRootValue('1')
->setContext([ ->setContext([
'buffer' => function($num) use (&$calls) { 'buffer' => function ($num) use (&$calls) {
$calls[] = "buffer: $num"; $calls[] = sprintf('buffer: %d', $num);
},
'load' => function ($num) use (&$calls) {
$calls[] = sprintf('load: %d', $num);
return sprintf('loaded: %d', $num);
}, },
'load' => function($num) use (&$calls) {
$calls[] = "load: $num";
return "loaded: $num";
}
]); ]);
$result = $this->executeBatchedQuery($batch); $result = $this->executeBatchedQuery($batch);
@ -489,19 +531,13 @@ class QueryExecutionTest extends ServerTestCase
$expected = [ $expected = [
[ [
'data' => [ 'data' => ['dfd' => 'loaded: 1'],
'dfd' => 'loaded: 1'
]
], ],
[ [
'data' => [ 'data' => ['dfd' => 'loaded: 2'],
'dfd' => 'loaded: 2'
]
], ],
[ [
'data' => [ 'data' => ['dfd' => 'loaded: 3'],
'dfd' => 'loaded: 3'
]
], ],
]; ];
@ -536,7 +572,7 @@ class QueryExecutionTest extends ServerTestCase
$called = false; $called = false;
$params = $doc = $operationType = null; $params = $doc = $operationType = null;
$this->config->setContext(function($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) { $this->config->setContext(function ($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) {
$called = true; $called = true;
$params = $p; $params = $p;
$doc = $d; $doc = $d;
@ -556,7 +592,7 @@ class QueryExecutionTest extends ServerTestCase
$called = false; $called = false;
$params = $doc = $operationType = null; $params = $doc = $operationType = null;
$this->config->setRootValue(function($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) { $this->config->setRootValue(function ($p, $d, $o) use (&$called, &$params, &$doc, &$operationType) {
$called = true; $called = true;
$params = $p; $params = $p;
$doc = $d; $doc = $d;
@ -575,9 +611,10 @@ class QueryExecutionTest extends ServerTestCase
{ {
$called = false; $called = false;
$error = null; $error = null;
$this->config->setErrorFormatter(function($e) use (&$called, &$error) { $this->config->setErrorFormatter(function ($e) use (&$called, &$error) {
$called = true; $called = true;
$error = $e; $error = $e;
return ['test' => 'formatted']; return ['test' => 'formatted'];
}); });
@ -586,8 +623,8 @@ class QueryExecutionTest extends ServerTestCase
$formatted = $result->toArray(); $formatted = $result->toArray();
$expected = [ $expected = [
'errors' => [ 'errors' => [
['test' => 'formatted'] ['test' => 'formatted'],
] ],
]; ];
$this->assertTrue($called); $this->assertTrue($called);
$this->assertArraySubset($expected, $formatted); $this->assertArraySubset($expected, $formatted);
@ -599,9 +636,9 @@ class QueryExecutionTest extends ServerTestCase
'errors' => [ 'errors' => [
[ [
'test' => 'formatted', 'test' => 'formatted',
'trace' => [] 'trace' => [],
] ],
] ],
]; ];
$this->assertArraySubset($expected, $formatted); $this->assertArraySubset($expected, $formatted);
} }
@ -611,12 +648,13 @@ class QueryExecutionTest extends ServerTestCase
$called = false; $called = false;
$errors = null; $errors = null;
$formatter = null; $formatter = null;
$this->config->setErrorsHandler(function($e, $f) use (&$called, &$errors, &$formatter) { $this->config->setErrorsHandler(function ($e, $f) use (&$called, &$errors, &$formatter) {
$called = true; $called = true;
$errors = $e; $errors = $e;
$formatter = $f; $formatter = $f;
return [ return [
['test' => 'handled'] ['test' => 'handled'],
]; ];
}); });
@ -626,8 +664,8 @@ class QueryExecutionTest extends ServerTestCase
$formatted = $result->toArray(); $formatted = $result->toArray();
$expected = [ $expected = [
'errors' => [ 'errors' => [
['test' => 'handled'] ['test' => 'handled'],
] ],
]; ];
$this->assertTrue($called); $this->assertTrue($called);
$this->assertArraySubset($expected, $formatted); $this->assertArraySubset($expected, $formatted);
@ -636,46 +674,4 @@ class QueryExecutionTest extends ServerTestCase
$this->assertInternalType('callable', $formatter); $this->assertInternalType('callable', $formatter);
$this->assertArraySubset($expected, $formatted); $this->assertArraySubset($expected, $formatted);
} }
private function executePersistedQuery($queryId, $variables = null)
{
$op = OperationParams::create(['queryId' => $queryId, 'variables' => $variables]);
$helper = new Helper();
$result = $helper->executeOperation($this->config, $op);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
private function executeQuery($query, $variables = null, $readonly = false)
{
$op = OperationParams::create(['query' => $query, 'variables' => $variables], $readonly);
$helper = new Helper();
$result = $helper->executeOperation($this->config, $op);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
private function executeBatchedQuery(array $qs)
{
$batch = [];
foreach ($qs as $params) {
$batch[] = OperationParams::create($params);
}
$helper = new Helper();
$result = $helper->executeBatch($this->config, $batch);
$this->assertInternalType('array', $result);
$this->assertCount(count($qs), $result);
foreach ($result as $index => $entry) {
$this->assertInstanceOf(ExecutionResult::class, $entry, "Result at $index is not an instance of " . ExecutionResult::class);
}
return $result;
}
private function assertQueryResultEquals($expected, $query, $variables = null)
{
$result = $this->executeQuery($query, $variables);
$this->assertArraySubset($expected, $result->toArray(true));
return $result;
}
} }

View File

@ -1,7 +1,9 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Error\Error;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Server\Helper; use GraphQL\Server\Helper;
use GraphQL\Server\OperationParams; use GraphQL\Server\OperationParams;
@ -9,6 +11,8 @@ use GraphQL\Server\RequestError;
use GraphQL\Tests\Server\Psr7\PsrRequestStub; use GraphQL\Tests\Server\Psr7\PsrRequestStub;
use GraphQL\Tests\Server\Psr7\PsrStreamStub; use GraphQL\Tests\Server\Psr7\PsrStreamStub;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function json_decode;
use function json_encode;
class RequestParsingTest extends TestCase class RequestParsingTest extends TestCase
{ {
@ -17,7 +21,7 @@ class RequestParsingTest extends TestCase
$query = '{my query}'; $query = '{my query}';
$parsed = [ $parsed = [
'raw' => $this->parseRawRequest('application/graphql', $query), 'raw' => $this->parseRawRequest('application/graphql', $query),
'psr' => $this->parsePsrRequest('application/graphql', $query) 'psr' => $this->parsePsrRequest('application/graphql', $query),
]; ];
foreach ($parsed as $source => $parsedBody) { foreach ($parsed as $source => $parsedBody) {
@ -26,6 +30,77 @@ class RequestParsingTest extends TestCase
} }
} }
/**
* @param string $contentType
* @param string $content
*
* @return OperationParams|OperationParams[]
*/
private function parseRawRequest($contentType, $content, string $method = 'POST')
{
$_SERVER['CONTENT_TYPE'] = $contentType;
$_SERVER['REQUEST_METHOD'] = $method;
$helper = new Helper();
return $helper->parseHttpRequest(function () use ($content) {
return $content;
});
}
/**
* @param string $contentType
* @param string $content
*
* @return OperationParams|OperationParams[]
*/
private function parsePsrRequest($contentType, $content, string $method = 'POST')
{
$psrRequestBody = new PsrStreamStub();
$psrRequestBody->content = $content;
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = [$contentType];
$psrRequest->method = $method;
$psrRequest->body = $psrRequestBody;
if ($contentType === 'application/json') {
$parsedBody = json_decode($content, true);
$parsedBody = $parsedBody === false ? null : $parsedBody;
} else {
$parsedBody = null;
}
$psrRequest->parsedBody = $parsedBody;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
/**
* @param OperationParams $params
* @param string $query
* @param string $queryId
* @param mixed|null $variables
* @param string $operation
*/
private function assertValidOperationParams(
$params,
$query,
$queryId = null,
$variables = null,
$operation = null,
$message = ''
) {
$this->assertInstanceOf(OperationParams::class, $params, $message);
$this->assertSame($query, $params->query, $message);
$this->assertSame($queryId, $params->queryId, $message);
$this->assertSame($variables, $params->variables, $message);
$this->assertSame($operation, $params->operation, $message);
}
public function testParsesUrlencodedRequest() : void public function testParsesUrlencodedRequest() : void
{ {
$query = '{my query}'; $query = '{my query}';
@ -35,11 +110,11 @@ class RequestParsingTest extends TestCase
$post = [ $post = [
'query' => $query, 'query' => $query,
'variables' => $variables, 'variables' => $variables,
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawFormUrlencodedRequest($post), 'raw' => $this->parseRawFormUrlencodedRequest($post),
'psr' => $this->parsePsrFormUrlEncodedRequest($post) 'psr' => $this->parsePsrFormUrlEncodedRequest($post),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
@ -48,6 +123,39 @@ class RequestParsingTest extends TestCase
} }
} }
/**
* @param mixed[] $postValue
* @return OperationParams|OperationParams[]
*/
private function parseRawFormUrlencodedRequest($postValue)
{
$_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = $postValue;
$helper = new Helper();
return $helper->parseHttpRequest(function () {
throw new InvariantViolation("Shouldn't read from php://input for urlencoded request");
});
}
/**
* @param mixed[] $postValue
* @return OperationParams[]|OperationParams
*/
private function parsePsrFormUrlEncodedRequest($postValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = ['application/x-www-form-urlencoded'];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $postValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
public function testParsesGetRequest() : void public function testParsesGetRequest() : void
{ {
$query = '{my query}'; $query = '{my query}';
@ -57,11 +165,11 @@ class RequestParsingTest extends TestCase
$get = [ $get = [
'query' => $query, 'query' => $query,
'variables' => $variables, 'variables' => $variables,
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawGetRequest($get), 'raw' => $this->parseRawGetRequest($get),
'psr' => $this->parsePsrGetRequest($get) 'psr' => $this->parsePsrGetRequest($get),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
@ -70,6 +178,37 @@ class RequestParsingTest extends TestCase
} }
} }
/**
* @param mixed[] $getValue
* @return OperationParams
*/
private function parseRawGetRequest($getValue)
{
$_SERVER['REQUEST_METHOD'] = 'GET';
$_GET = $getValue;
$helper = new Helper();
return $helper->parseHttpRequest(function () {
throw new InvariantViolation("Shouldn't read from php://input for urlencoded request");
});
}
/**
* @param mixed[] $getValue
* @return OperationParams[]|OperationParams
*/
private function parsePsrGetRequest($getValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->method = 'GET';
$psrRequest->queryParams = $getValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
public function testParsesMultipartFormdataRequest() : void public function testParsesMultipartFormdataRequest() : void
{ {
$query = '{my query}'; $query = '{my query}';
@ -79,11 +218,11 @@ class RequestParsingTest extends TestCase
$post = [ $post = [
'query' => $query, 'query' => $query,
'variables' => $variables, 'variables' => $variables,
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawMultipartFormdataRequest($post), 'raw' => $this->parseRawMultipartFormdataRequest($post),
'psr' => $this->parsePsrMultipartFormdataRequest($post) 'psr' => $this->parsePsrMultipartFormdataRequest($post),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
@ -92,6 +231,39 @@ class RequestParsingTest extends TestCase
} }
} }
/**
* @param mixed[] $postValue
* @return OperationParams|OperationParams[]
*/
private function parseRawMultipartFormDataRequest($postValue)
{
$_SERVER['CONTENT_TYPE'] = 'multipart/form-data; boundary=----FormBoundary';
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = $postValue;
$helper = new Helper();
return $helper->parseHttpRequest(function () {
throw new InvariantViolation("Shouldn't read from php://input for multipart/form-data request");
});
}
/**
* @param mixed[] $postValue
* @return OperationParams|OperationParams[]
*/
private function parsePsrMultipartFormDataRequest($postValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = ['multipart/form-data; boundary=----FormBoundary'];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $postValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
public function testParsesJSONRequest() : void public function testParsesJSONRequest() : void
{ {
$query = '{my query}'; $query = '{my query}';
@ -101,11 +273,11 @@ class RequestParsingTest extends TestCase
$body = [ $body = [
'query' => $query, 'query' => $query,
'variables' => $variables, 'variables' => $variables,
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawRequest('application/json', json_encode($body)), 'raw' => $this->parseRawRequest('application/json', json_encode($body)),
'psr' => $this->parsePsrRequest('application/json', json_encode($body)) 'psr' => $this->parsePsrRequest('application/json', json_encode($body)),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
$this->assertValidOperationParams($parsedBody, $query, null, $variables, $operation, $method); $this->assertValidOperationParams($parsedBody, $query, null, $variables, $operation, $method);
@ -122,11 +294,11 @@ class RequestParsingTest extends TestCase
$body = [ $body = [
'query' => $query, 'query' => $query,
'variables' => json_encode($variables), 'variables' => json_encode($variables),
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawRequest('application/json', json_encode($body)), 'raw' => $this->parseRawRequest('application/json', json_encode($body)),
'psr' => $this->parsePsrRequest('application/json', json_encode($body)) 'psr' => $this->parsePsrRequest('application/json', json_encode($body)),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
$this->assertValidOperationParams($parsedBody, $query, null, $variables, $operation, $method); $this->assertValidOperationParams($parsedBody, $query, null, $variables, $operation, $method);
@ -143,7 +315,7 @@ class RequestParsingTest extends TestCase
$body = [ $body = [
'query' => $query, 'query' => $query,
'variables' => $variables, 'variables' => $variables,
'operationName' => $operation 'operationName' => $operation,
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawRequest('application/json', json_encode($body)), 'raw' => $this->parseRawRequest('application/json', json_encode($body)),
@ -161,23 +333,37 @@ class RequestParsingTest extends TestCase
[ [
'query' => '{my query}', 'query' => '{my query}',
'variables' => ['test' => 1, 'test2' => 2], 'variables' => ['test' => 1, 'test2' => 2],
'operationName' => 'op' 'operationName' => 'op',
], ],
[ [
'queryId' => 'my-query-id', 'queryId' => 'my-query-id',
'variables' => ['test' => 1, 'test2' => 2], 'variables' => ['test' => 1, 'test2' => 2],
'operationName' => 'op2' 'operationName' => 'op2',
], ],
]; ];
$parsed = [ $parsed = [
'raw' => $this->parseRawRequest('application/json', json_encode($body)), 'raw' => $this->parseRawRequest('application/json', json_encode($body)),
'psr' => $this->parsePsrRequest('application/json', json_encode($body)) 'psr' => $this->parsePsrRequest('application/json', json_encode($body)),
]; ];
foreach ($parsed as $method => $parsedBody) { foreach ($parsed as $method => $parsedBody) {
$this->assertInternalType('array', $parsedBody, $method); $this->assertInternalType('array', $parsedBody, $method);
$this->assertCount(2, $parsedBody, $method); $this->assertCount(2, $parsedBody, $method);
$this->assertValidOperationParams($parsedBody[0], $body[0]['query'], null, $body[0]['variables'], $body[0]['operationName'], $method); $this->assertValidOperationParams(
$this->assertValidOperationParams($parsedBody[1], null, $body[1]['queryId'], $body[1]['variables'], $body[1]['operationName'], $method); $parsedBody[0],
$body[0]['query'],
null,
$body[0]['variables'],
$body[0]['operationName'],
$method
);
$this->assertValidOperationParams(
$parsedBody[1],
null,
$body[1]['queryId'],
$body[1]['variables'],
$body[1]['operationName'],
$method
);
} }
} }
@ -272,169 +458,13 @@ class RequestParsingTest extends TestCase
{ {
$this->expectException(RequestError::class); $this->expectException(RequestError::class);
$this->expectExceptionMessage('HTTP Method "PUT" is not supported'); $this->expectExceptionMessage('HTTP Method "PUT" is not supported');
$this->parseRawRequest('application/json', json_encode([]), "PUT"); $this->parseRawRequest('application/json', json_encode([]), 'PUT');
} }
public function testFailsOnMethodsOtherThanPostOrGetPsr() : void public function testFailsOnMethodsOtherThanPostOrGetPsr() : void
{ {
$this->expectException(RequestError::class); $this->expectException(RequestError::class);
$this->expectExceptionMessage('HTTP Method "PUT" is not supported'); $this->expectExceptionMessage('HTTP Method "PUT" is not supported');
$this->parsePsrRequest('application/json', json_encode([]), "PUT"); $this->parsePsrRequest('application/json', json_encode([]), 'PUT');
}
/**
* @param string $contentType
* @param string $content
* @param $method
*
* @return OperationParams|OperationParams[]
*/
private function parseRawRequest($contentType, $content, $method = 'POST')
{
$_SERVER['CONTENT_TYPE'] = $contentType;
$_SERVER['REQUEST_METHOD'] = $method;
$helper = new Helper();
return $helper->parseHttpRequest(function() use ($content) {
return $content;
});
}
/**
* @param string $contentType
* @param string $content
* @param $method
*
* @return OperationParams|OperationParams[]
*/
private function parsePsrRequest($contentType, $content, $method = 'POST')
{
$psrRequestBody = new PsrStreamStub();
$psrRequestBody->content = $content;
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = [$contentType];
$psrRequest->method = $method;
$psrRequest->body = $psrRequestBody;
if ($contentType === 'application/json') {
$parsedBody = json_decode($content, true);
$parsedBody = $parsedBody === false ? null : $parsedBody;
} else {
$parsedBody = null;
}
$psrRequest->parsedBody = $parsedBody;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
/**
* @param array $postValue
* @return OperationParams|OperationParams[]
*/
private function parseRawFormUrlencodedRequest($postValue)
{
$_SERVER['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = $postValue;
$helper = new Helper();
return $helper->parseHttpRequest(function() {
throw new InvariantViolation("Shouldn't read from php://input for urlencoded request");
});
}
/**
* @param $postValue
* @return array|Helper
*/
private function parsePsrFormUrlEncodedRequest($postValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = ['application/x-www-form-urlencoded'];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $postValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
/**
* @param array $postValue
* @return OperationParams|OperationParams[]
*/
private function parseRawMultipartFormDataRequest($postValue)
{
$_SERVER['CONTENT_TYPE'] = 'multipart/form-data; boundary=----FormBoundary';
$_SERVER['REQUEST_METHOD'] = 'POST';
$_POST = $postValue;
$helper = new Helper();
return $helper->parseHttpRequest(function() {
throw new InvariantViolation("Shouldn't read from php://input for multipart/form-data request");
});
}
/**
* @param $postValue
* @return array|Helper
*/
private function parsePsrMultipartFormDataRequest($postValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = ['multipart/form-data; boundary=----FormBoundary'];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $postValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
/**
* @param $getValue
* @return OperationParams
*/
private function parseRawGetRequest($getValue)
{
$_SERVER['REQUEST_METHOD'] = 'GET';
$_GET = $getValue;
$helper = new Helper();
return $helper->parseHttpRequest(function() {
throw new InvariantViolation("Shouldn't read from php://input for urlencoded request");
});
}
/**
* @param $getValue
* @return array|Helper
*/
private function parsePsrGetRequest($getValue)
{
$psrRequest = new PsrRequestStub();
$psrRequest->method = 'GET';
$psrRequest->queryParams = $getValue;
$helper = new Helper();
return $helper->parsePsrRequest($psrRequest);
}
/**
* @param OperationParams $params
* @param string $query
* @param string $queryId
* @param array $variables
* @param string $operation
*/
private function assertValidOperationParams($params, $query, $queryId = null, $variables = null, $operation = null, $message = '')
{
$this->assertInstanceOf(OperationParams::class, $params, $message);
$this->assertSame($query, $params->query, $message);
$this->assertSame($queryId, $params->queryId, $message);
$this->assertSame($variables, $params->variables, $message);
$this->assertSame($operation, $params->operation, $message);
} }
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Server\Helper; use GraphQL\Server\Helper;
@ -22,6 +25,13 @@ class RequestValidationTest extends TestCase
$this->assertValid($parsedBody); $this->assertValid($parsedBody);
} }
private function assertValid($parsedRequest)
{
$helper = new Helper();
$errors = $helper->validateOperationParams($parsedRequest);
$this->assertEmpty($errors, isset($errors[0]) ? $errors[0]->getMessage() : '');
}
public function testRequestWithQueryIdShouldValidate() : void public function testRequestWithQueryIdShouldValidate() : void
{ {
$queryId = 'some-query-id'; $queryId = 'some-query-id';
@ -50,6 +60,17 @@ class RequestValidationTest extends TestCase
); );
} }
private function assertInputError($parsedRequest, $expectedMessage)
{
$helper = new Helper();
$errors = $helper->validateOperationParams($parsedRequest);
if (! empty($errors[0])) {
$this->assertEquals($expectedMessage, $errors[0]->getMessage());
} else {
$this->fail('Expected error not returned');
}
}
public function testFailsWhenBothQueryAndQueryIdArePresent() : void public function testFailsWhenBothQueryAndQueryIdArePresent() : void
{ {
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
@ -66,7 +87,7 @@ class RequestValidationTest extends TestCase
public function testFailsWhenQueryParameterIsNotString() : void public function testFailsWhenQueryParameterIsNotString() : void
{ {
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'query' => ['t' => '{my query}'] 'query' => ['t' => '{my query}'],
]); ]);
$this->assertInputError( $this->assertInputError(
@ -78,7 +99,7 @@ class RequestValidationTest extends TestCase
public function testFailsWhenQueryIdParameterIsNotString() : void public function testFailsWhenQueryIdParameterIsNotString() : void
{ {
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'queryId' => ['t' => '{my query}'] 'queryId' => ['t' => '{my query}'],
]); ]);
$this->assertInputError( $this->assertInputError(
@ -91,7 +112,7 @@ class RequestValidationTest extends TestCase
{ {
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'query' => '{my query}', 'query' => '{my query}',
'operationName' => [] 'operationName' => [],
]); ]);
$this->assertInputError( $this->assertInputError(
@ -108,14 +129,14 @@ class RequestValidationTest extends TestCase
$query = '{my q}'; $query = '{my q}';
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'query' => $query, 'query' => $query,
'variables' => null 'variables' => null,
]); ]);
$this->assertValid($parsedBody); $this->assertValid($parsedBody);
$variables = ""; $variables = '';
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'query' => $query, 'query' => $query,
'variables' => $variables 'variables' => $variables,
]); ]);
$this->assertValid($parsedBody); $this->assertValid($parsedBody);
} }
@ -124,7 +145,7 @@ class RequestValidationTest extends TestCase
{ {
$parsedBody = OperationParams::create([ $parsedBody = OperationParams::create([
'query' => '{my query}', 'query' => '{my query}',
'variables' => 0 'variables' => 0,
]); ]);
$this->assertInputError( $this->assertInputError(
@ -132,22 +153,4 @@ class RequestValidationTest extends TestCase
'GraphQL Request parameter "variables" must be object or JSON string parsed to object, but got 0' 'GraphQL Request parameter "variables" must be object or JSON string parsed to object, but got 0'
); );
} }
private function assertValid($parsedRequest)
{
$helper = new Helper();
$errors = $helper->validateOperationParams($parsedRequest);
$this->assertEmpty($errors, isset($errors[0]) ? $errors[0]->getMessage() : '');
}
private function assertInputError($parsedRequest, $expectedMessage)
{
$helper = new Helper();
$errors = $helper->validateOperationParams($parsedRequest);
if (!empty($errors[0])) {
$this->assertEquals($expectedMessage, $errors[0]->getMessage());
} else {
$this->fail('Expected error not returned');
}
}
} }

View File

@ -1,12 +1,15 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter; use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
use GraphQL\Type\Schema;
use GraphQL\Server\ServerConfig; use GraphQL\Server\ServerConfig;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
class ServerConfigTest extends TestCase class ServerConfigTest extends TestCase
@ -70,7 +73,8 @@ class ServerConfigTest extends TestCase
{ {
$config = ServerConfig::create(); $config = ServerConfig::create();
$formatter = function() {}; $formatter = function () {
};
$config->setErrorFormatter($formatter); $config->setErrorFormatter($formatter);
$this->assertSame($formatter, $config->getErrorFormatter()); $this->assertSame($formatter, $config->getErrorFormatter());
@ -83,7 +87,8 @@ class ServerConfigTest extends TestCase
{ {
$config = ServerConfig::create(); $config = ServerConfig::create();
$handler = function() {}; $handler = function () {
};
$config->setErrorsHandler($handler); $config->setErrorsHandler($handler);
$this->assertSame($handler, $config->getErrorsHandler()); $this->assertSame($handler, $config->getErrorsHandler());
@ -113,11 +118,17 @@ class ServerConfigTest extends TestCase
$config->setValidationRules($rules); $config->setValidationRules($rules);
$this->assertSame($rules, $config->getValidationRules()); $this->assertSame($rules, $config->getValidationRules());
$rules = [function() {}]; $rules = [function () {
},
];
$config->setValidationRules($rules); $config->setValidationRules($rules);
$this->assertSame($rules, $config->getValidationRules()); $this->assertSame($rules, $config->getValidationRules());
$rules = function() {return [function() {}];}; $rules = function () {
return [function () {
},
];
};
$config->setValidationRules($rules); $config->setValidationRules($rules);
$this->assertSame($rules, $config->getValidationRules()); $this->assertSame($rules, $config->getValidationRules());
} }
@ -126,7 +137,8 @@ class ServerConfigTest extends TestCase
{ {
$config = ServerConfig::create(); $config = ServerConfig::create();
$resolver = function() {}; $resolver = function () {
};
$config->setFieldResolver($resolver); $config->setFieldResolver($resolver);
$this->assertSame($resolver, $config->getFieldResolver()); $this->assertSame($resolver, $config->getFieldResolver());
@ -139,7 +151,8 @@ class ServerConfigTest extends TestCase
{ {
$config = ServerConfig::create(); $config = ServerConfig::create();
$loader = function() {}; $loader = function () {
};
$config->setPersistentQueryLoader($loader); $config->setPersistentQueryLoader($loader);
$this->assertSame($loader, $config->getPersistentQueryLoader()); $this->assertSame($loader, $config->getPersistentQueryLoader());
@ -162,16 +175,21 @@ class ServerConfigTest extends TestCase
public function testAcceptsArray() : void public function testAcceptsArray() : void
{ {
$arr = [ $arr = [
'schema' => new \GraphQL\Type\Schema([ 'schema' => new Schema([
'query' => new ObjectType(['name' => 't', 'fields' => ['a' => Type::string()]]) 'query' => new ObjectType(['name' => 't', 'fields' => ['a' => Type::string()]]),
]), ]),
'context' => new \stdClass(), 'context' => new \stdClass(),
'rootValue' => new \stdClass(), 'rootValue' => new \stdClass(),
'errorFormatter' => function() {}, 'errorFormatter' => function () {
},
'promiseAdapter' => new SyncPromiseAdapter(), 'promiseAdapter' => new SyncPromiseAdapter(),
'validationRules' => [function() {}], 'validationRules' => [function () {
'fieldResolver' => function() {}, },
'persistentQueryLoader' => function() {}, ],
'fieldResolver' => function () {
},
'persistentQueryLoader' => function () {
},
'debug' => true, 'debug' => true,
'queryBatching' => true, 'queryBatching' => true,
]; ];
@ -192,9 +210,7 @@ class ServerConfigTest extends TestCase
public function testThrowsOnInvalidArrayKey() : void public function testThrowsOnInvalidArrayKey() : void
{ {
$arr = [ $arr = ['missingKey' => 'value'];
'missingKey' => 'value'
];
$this->expectException(InvariantViolation::class); $this->expectException(InvariantViolation::class);
$this->expectExceptionMessage('Unknown server config option "missingKey"'); $this->expectExceptionMessage('Unknown server config option "missingKey"');

View File

@ -1,6 +1,8 @@
<?php <?php
namespace GraphQL\Tests\Server;
declare(strict_types=1);
namespace GraphQL\Tests\Server;
use GraphQL\Deferred; use GraphQL\Deferred;
use GraphQL\Error\UserError; use GraphQL\Error\UserError;
@ -8,6 +10,10 @@ use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema; use GraphQL\Type\Schema;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use function trigger_error;
use const E_USER_DEPRECATED;
use const E_USER_NOTICE;
use const E_USER_WARNING;
abstract class ServerTestCase extends TestCase abstract class ServerTestCase extends TestCase
{ {
@ -19,61 +25,63 @@ abstract class ServerTestCase extends TestCase
'fields' => [ 'fields' => [
'f1' => [ 'f1' => [
'type' => Type::string(), 'type' => Type::string(),
'resolve' => function($root, $args, $context, $info) { 'resolve' => function ($root, $args, $context, $info) {
return $info->fieldName; return $info->fieldName;
} },
], ],
'fieldWithPhpError' => [ 'fieldWithPhpError' => [
'type' => Type::string(), 'type' => Type::string(),
'resolve' => function($root, $args, $context, $info) { 'resolve' => function ($root, $args, $context, $info) {
trigger_error('deprecated', E_USER_DEPRECATED); trigger_error('deprecated', E_USER_DEPRECATED);
trigger_error('notice', E_USER_NOTICE); trigger_error('notice', E_USER_NOTICE);
trigger_error('warning', E_USER_WARNING); trigger_error('warning', E_USER_WARNING);
$a = []; $a = [];
$a['test']; // should produce PHP notice $a['test']; // should produce PHP notice
return $info->fieldName; return $info->fieldName;
} },
], ],
'fieldWithException' => [ 'fieldWithException' => [
'type' => Type::string(), 'type' => Type::string(),
'resolve' => function($root, $args, $context, $info) { 'resolve' => function ($root, $args, $context, $info) {
throw new UserError("This is the exception we want"); throw new UserError('This is the exception we want');
} },
], ],
'testContextAndRootValue' => [ 'testContextAndRootValue' => [
'type' => Type::string(), 'type' => Type::string(),
'resolve' => function($root, $args, $context, $info) { 'resolve' => function ($root, $args, $context, $info) {
$context->testedRootValue = $root; $context->testedRootValue = $root;
return $info->fieldName; return $info->fieldName;
} },
], ],
'fieldWithArg' => [ 'fieldWithArg' => [
'type' => Type::string(), 'type' => Type::string(),
'args' => [ 'args' => [
'arg' => [ 'arg' => [
'type' => Type::nonNull(Type::string()) 'type' => Type::nonNull(Type::string()),
], ],
], ],
'resolve' => function($root, $args) { 'resolve' => function ($root, $args) {
return $args['arg']; return $args['arg'];
} },
], ],
'dfd' => [ 'dfd' => [
'type' => Type::string(), 'type' => Type::string(),
'args' => [ 'args' => [
'num' => [ 'num' => [
'type' => Type::nonNull(Type::int()) 'type' => Type::nonNull(Type::int()),
], ],
], ],
'resolve' => function($root, $args, $context) { 'resolve' => function ($root, $args, $context) {
$context['buffer']($args['num']); $context['buffer']($args['num']);
return new Deferred(function() use ($args, $context) { return new Deferred(function () use ($args, $context) {
return $context['load']($args['num']); return $context['load']($args['num']);
}); });
} },
] ],
] ],
]), ]),
'mutation' => new ObjectType([ 'mutation' => new ObjectType([
'name' => 'Mutation', 'name' => 'Mutation',
@ -82,13 +90,14 @@ abstract class ServerTestCase extends TestCase
'type' => new ObjectType([ 'type' => new ObjectType([
'name' => 'TestMutation', 'name' => 'TestMutation',
'fields' => [ 'fields' => [
'result' => Type::string() 'result' => Type::string(),
] ],
]) ]),
] ],
] ],
]) ]),
]); ]);
return $schema; return $schema;
} }
} }

View File

@ -1,4 +1,7 @@
<?php <?php
declare(strict_types=1);
namespace GraphQL\Tests\Server; namespace GraphQL\Tests\Server;
use GraphQL\Executor\ExecutionResult; use GraphQL\Executor\ExecutionResult;
@ -6,13 +9,11 @@ use GraphQL\Server\Helper;
use GraphQL\Server\ServerConfig; use GraphQL\Server\ServerConfig;
use GraphQL\Server\StandardServer; use GraphQL\Server\StandardServer;
use GraphQL\Tests\Server\Psr7\PsrRequestStub; use GraphQL\Tests\Server\Psr7\PsrRequestStub;
use GraphQL\Tests\Server\Psr7\PsrStreamStub; use function json_encode;
class StandardServerTest extends ServerTestCase class StandardServerTest extends ServerTestCase
{ {
/** /** @var ServerConfig */
* @var ServerConfig
*/
private $config; private $config;
public function setUp() public function setUp()
@ -24,88 +25,82 @@ class StandardServerTest extends ServerTestCase
public function testSimpleRequestExecutionWithOutsideParsing() : void public function testSimpleRequestExecutionWithOutsideParsing() : void
{ {
$body = json_encode([ $body = json_encode(['query' => '{f1}']);
'query' => '{f1}'
]);
$parsedBody = $this->parseRawRequest('application/json', $body); $parsedBody = $this->parseRawRequest('application/json', $body);
$server = new StandardServer($this->config); $server = new StandardServer($this->config);
$result = $server->executeRequest($parsedBody); $result = $server->executeRequest($parsedBody);
$expected = [ $expected = [
'data' => [ 'data' => ['f1' => 'f1'],
'f1' => 'f1',
]
]; ];
$this->assertEquals($expected, $result->toArray(true)); $this->assertEquals($expected, $result->toArray(true));
} }
public function testSimplePsrRequestExecution() : void
{
$body = [
'query' => '{f1}'
];
$expected = [
'data' => [
'f1' => 'f1'
]
];
$request = $this->preparePsrRequest('application/json', $body);
$this->assertPsrRequestEquals($expected, $request);
}
public function testMultipleOperationPsrRequestExecution() : void
{
$body = [
'query' => 'query firstOp {fieldWithPhpError} query secondOp {f1}',
'operationName' => 'secondOp'
];
$expected = [
'data' => [
'f1' => 'f1'
]
];
$request = $this->preparePsrRequest('application/json', $body);
$this->assertPsrRequestEquals($expected, $request);
}
private function executePsrRequest($psrRequest)
{
$server = new StandardServer($this->config);
$result = $server->executePsrRequest($psrRequest);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
private function assertPsrRequestEquals($expected, $request)
{
$result = $this->executePsrRequest($request);
$this->assertArraySubset($expected, $result->toArray(true));
return $result;
}
private function preparePsrRequest($contentType, $parsedBody)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = [$contentType];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $parsedBody;
return $psrRequest;
}
private function parseRawRequest($contentType, $content, $method = 'POST') private function parseRawRequest($contentType, $content, $method = 'POST')
{ {
$_SERVER['CONTENT_TYPE'] = $contentType; $_SERVER['CONTENT_TYPE'] = $contentType;
$_SERVER['REQUEST_METHOD'] = $method; $_SERVER['REQUEST_METHOD'] = $method;
$helper = new Helper(); $helper = new Helper();
return $helper->parseHttpRequest(function() use ($content) {
return $helper->parseHttpRequest(function () use ($content) {
return $content; return $content;
}); });
} }
public function testSimplePsrRequestExecution() : void
{
$body = ['query' => '{f1}'];
$expected = [
'data' => ['f1' => 'f1'],
];
$request = $this->preparePsrRequest('application/json', $body);
$this->assertPsrRequestEquals($expected, $request);
}
private function preparePsrRequest($contentType, $parsedBody)
{
$psrRequest = new PsrRequestStub();
$psrRequest->headers['content-type'] = [$contentType];
$psrRequest->method = 'POST';
$psrRequest->parsedBody = $parsedBody;
return $psrRequest;
}
private function assertPsrRequestEquals($expected, $request)
{
$result = $this->executePsrRequest($request);
$this->assertArraySubset($expected, $result->toArray(true));
return $result;
}
private function executePsrRequest($psrRequest)
{
$server = new StandardServer($this->config);
$result = $server->executePsrRequest($psrRequest);
$this->assertInstanceOf(ExecutionResult::class, $result);
return $result;
}
public function testMultipleOperationPsrRequestExecution() : void
{
$body = [
'query' => 'query firstOp {fieldWithPhpError} query secondOp {f1}',
'operationName' => 'secondOp',
];
$expected = [
'data' => ['f1' => 'f1'],
];
$request = $this->preparePsrRequest('application/json', $body);
$this->assertPsrRequestEquals($expected, $request);
}
} }