mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-30 00:46:02 +03:00
159 lines
4.1 KiB
PHP
159 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace GraphQL\Tests\Validator;
|
|
|
|
use GraphQL\Validator\Rules\QueryDepth;
|
|
use function sprintf;
|
|
use function str_replace;
|
|
|
|
class QueryDepthTest extends QuerySecurityTestCase
|
|
{
|
|
/**
|
|
* @param int $queryDepth
|
|
* @param int $maxQueryDepth
|
|
* @param string[][] $expectedErrors
|
|
*
|
|
* @dataProvider queryDataProvider
|
|
*/
|
|
public function testSimpleQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
|
{
|
|
$this->assertDocumentValidator($this->buildRecursiveQuery($queryDepth), $maxQueryDepth, $expectedErrors);
|
|
}
|
|
|
|
private function buildRecursiveQuery($depth)
|
|
{
|
|
return sprintf('query MyQuery { human%s }', $this->buildRecursiveQueryPart($depth));
|
|
}
|
|
|
|
private function buildRecursiveQueryPart($depth)
|
|
{
|
|
$templates = [
|
|
'human' => ' { firstName%s } ',
|
|
'dog' => ' dogs { name%s } ',
|
|
];
|
|
|
|
$part = $templates['human'];
|
|
|
|
for ($i = 1; $i <= $depth; ++$i) {
|
|
$key = $i % 2 === 1 ? 'human' : 'dog';
|
|
$template = $templates[$key];
|
|
|
|
$part = sprintf($part, ($key === 'human' ? ' owner ' : '') . $template);
|
|
}
|
|
$part = str_replace('%s', '', $part);
|
|
|
|
return $part;
|
|
}
|
|
|
|
/**
|
|
* @param int $queryDepth
|
|
* @param int $maxQueryDepth
|
|
* @param string[][] $expectedErrors
|
|
*
|
|
* @dataProvider queryDataProvider
|
|
*/
|
|
public function testFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
|
{
|
|
$this->assertDocumentValidator(
|
|
$this->buildRecursiveUsingFragmentQuery($queryDepth),
|
|
$maxQueryDepth,
|
|
$expectedErrors
|
|
);
|
|
}
|
|
|
|
private function buildRecursiveUsingFragmentQuery($depth)
|
|
{
|
|
return sprintf(
|
|
'query MyQuery { human { ...F1 } } fragment F1 on Human %s',
|
|
$this->buildRecursiveQueryPart($depth)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param int $queryDepth
|
|
* @param int $maxQueryDepth
|
|
* @param string[][] $expectedErrors
|
|
*
|
|
* @dataProvider queryDataProvider
|
|
*/
|
|
public function testInlineFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
|
{
|
|
$this->assertDocumentValidator(
|
|
$this->buildRecursiveUsingInlineFragmentQuery($queryDepth),
|
|
$maxQueryDepth,
|
|
$expectedErrors
|
|
);
|
|
}
|
|
|
|
private function buildRecursiveUsingInlineFragmentQuery($depth)
|
|
{
|
|
return sprintf(
|
|
'query MyQuery { human { ...on Human %s } }',
|
|
$this->buildRecursiveQueryPart($depth)
|
|
);
|
|
}
|
|
|
|
public function testComplexityIntrospectionQuery() : void
|
|
{
|
|
$this->assertIntrospectionQuery(11);
|
|
}
|
|
|
|
public function testIntrospectionTypeMetaFieldQuery() : void
|
|
{
|
|
$this->assertIntrospectionTypeMetaFieldQuery(1);
|
|
}
|
|
|
|
public function testTypeNameMetaFieldQuery() : void
|
|
{
|
|
$this->assertTypeNameMetaFieldQuery(1);
|
|
}
|
|
|
|
public function queryDataProvider()
|
|
{
|
|
return [
|
|
[1], // Valid because depth under default limit (7)
|
|
[2],
|
|
[3],
|
|
[4],
|
|
[5],
|
|
[6],
|
|
[7],
|
|
[8, 9], // Valid because depth under new limit (9)
|
|
[10, 0], // Valid because 0 depth disable limit
|
|
[
|
|
10,
|
|
8,
|
|
[$this->createFormattedError(8, 10)],
|
|
], // failed because depth over limit (8)
|
|
[
|
|
20,
|
|
15,
|
|
[$this->createFormattedError(15, 20)],
|
|
], // failed because depth over limit (15)
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param int $max
|
|
* @param int $count
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function getErrorMessage($max, $count)
|
|
{
|
|
return QueryDepth::maxQueryDepthErrorMessage($max, $count);
|
|
}
|
|
|
|
/**
|
|
* @param int $maxDepth
|
|
*
|
|
* @return QueryDepth
|
|
*/
|
|
protected function getRule($maxDepth)
|
|
{
|
|
return new QueryDepth($maxDepth);
|
|
}
|
|
}
|