graphql-php/tests/Validator/QueryDepthTest.php

159 lines
4.1 KiB
PHP
Raw Normal View History

<?php
2018-09-02 14:08:49 +03:00
declare(strict_types=1);
namespace GraphQL\Tests\Validator;
use GraphQL\Validator\Rules\QueryDepth;
2018-09-02 14:08:49 +03:00
use function sprintf;
use function str_replace;
2018-07-29 18:43:10 +03:00
class QueryDepthTest extends QuerySecurityTestCase
{
/**
2018-09-02 14:08:49 +03:00
* @param int $queryDepth
* @param int $maxQueryDepth
* @param string[][] $expectedErrors
2018-09-26 12:07:23 +03:00
*
2018-09-02 14:08:49 +03:00
* @dataProvider queryDataProvider
*/
2018-09-02 14:08:49 +03:00
public function testSimpleQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
{
2018-09-02 14:08:49 +03:00
$this->assertDocumentValidator($this->buildRecursiveQuery($queryDepth), $maxQueryDepth, $expectedErrors);
}
2018-09-02 14:08:49 +03:00
private function buildRecursiveQuery($depth)
{
2018-09-26 12:07:23 +03:00
return sprintf('query MyQuery { human%s }', $this->buildRecursiveQueryPart($depth));
}
2018-09-02 14:08:49 +03:00
private function buildRecursiveQueryPart($depth)
{
2018-09-02 14:08:49 +03:00
$templates = [
'human' => ' { firstName%s } ',
'dog' => ' dogs { name%s } ',
];
$part = $templates['human'];
for ($i = 1; $i <= $depth; ++$i) {
2018-09-26 12:07:23 +03:00
$key = $i % 2 === 1 ? 'human' : 'dog';
2018-09-02 14:08:49 +03:00
$template = $templates[$key];
$part = sprintf($part, ($key === 'human' ? ' owner ' : '') . $template);
}
$part = str_replace('%s', '', $part);
return $part;
}
/**
2018-09-02 14:08:49 +03:00
* @param int $queryDepth
* @param int $maxQueryDepth
* @param string[][] $expectedErrors
2018-09-26 12:07:23 +03:00
*
* @dataProvider queryDataProvider
*/
public function testFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
{
2018-09-02 14:08:49 +03:00
$this->assertDocumentValidator(
$this->buildRecursiveUsingFragmentQuery($queryDepth),
$maxQueryDepth,
$expectedErrors
);
}
private function buildRecursiveUsingFragmentQuery($depth)
{
2018-09-26 12:07:23 +03:00
return sprintf(
2018-09-02 14:08:49 +03:00
'query MyQuery { human { ...F1 } } fragment F1 on Human %s',
$this->buildRecursiveQueryPart($depth)
);
}
/**
2018-09-02 14:08:49 +03:00
* @param int $queryDepth
* @param int $maxQueryDepth
* @param string[][] $expectedErrors
2018-09-26 12:07:23 +03:00
*
* @dataProvider queryDataProvider
*/
public function testInlineFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
{
2018-09-02 14:08:49 +03:00
$this->assertDocumentValidator(
$this->buildRecursiveUsingInlineFragmentQuery($queryDepth),
$maxQueryDepth,
$expectedErrors
);
}
private function buildRecursiveUsingInlineFragmentQuery($depth)
{
2018-09-26 12:07:23 +03:00
return sprintf(
2018-09-02 14:08:49 +03:00
'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)
];
}
2018-09-02 14:08:49 +03:00
/**
* @param int $max
* @param int $count
*
* @return string
*/
protected function getErrorMessage($max, $count)
{
2018-09-02 14:08:49 +03:00
return QueryDepth::maxQueryDepthErrorMessage($max, $count);
}
2018-09-02 14:08:49 +03:00
/**
* @param int $maxDepth
*
* @return QueryDepth
*/
protected function getRule($maxDepth)
{
2018-09-02 14:08:49 +03:00
return new QueryDepth($maxDepth);
}
}