Skip to content

Commit 6ba4e6d

Browse files
committed
Adding unit tests for new security features
1 parent 70e8c44 commit 6ba4e6d

File tree

5 files changed

+154
-6
lines changed

5 files changed

+154
-6
lines changed

Tests/Fixtures/Entities/Contact.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,12 @@ public function prefetchData(iterable $iterable, stdClass $someOtherService = nu
6666
}
6767
return 'OK';
6868
}
69+
70+
/**
71+
* @Field()
72+
*/
73+
public function getManager(): ?Contact
74+
{
75+
return null;
76+
}
6977
}

Tests/Fixtures/Entities/Product.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
namespace TheCodingMachine\Graphqlite\Bundle\Tests\Fixtures\Entities;
55

66

7+
use TheCodingMachine\GraphQLite\Annotations\Field;
8+
79
class Product
810
{
911
/**
@@ -36,6 +38,4 @@ public function getPrice(): float
3638
{
3739
return $this->price;
3840
}
39-
40-
41-
}
41+
}

Tests/Fixtures/Types/ProductType.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
namespace TheCodingMachine\Graphqlite\Bundle\Tests\Fixtures\Types;
55

6+
use TheCodingMachine\GraphQLite\Annotations\Field;
67
use TheCodingMachine\GraphQLite\Annotations\SourceField;
78
use TheCodingMachine\GraphQLite\Annotations\Type;
9+
use TheCodingMachine\Graphqlite\Bundle\Tests\Fixtures\Entities\Contact;
810
use TheCodingMachine\Graphqlite\Bundle\Tests\Fixtures\Entities\Product;
911

1012

@@ -15,5 +17,12 @@
1517
*/
1618
class ProductType
1719
{
20+
/**
21+
* @Field()
22+
*/
23+
public function getSeller(Product $product): ?Contact
24+
{
25+
return null;
26+
}
1827

19-
}
28+
}

Tests/FunctionalTest.php

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,110 @@ public function testValidation(): void
422422
$this->assertSame('Validate', $errors[0]['extensions']['category']);
423423
}
424424

425+
public function testWithIntrospection(): void
426+
{
427+
$kernel = new GraphqliteTestingKernel(true, null, true, null);
428+
$kernel->boot();
429+
430+
$request = Request::create('/graphql', 'POST', ['query' => '
431+
{
432+
__schema {
433+
queryType {
434+
name
435+
}
436+
}
437+
}
438+
']);
439+
440+
$response = $kernel->handle($request);
441+
442+
$result = json_decode($response->getContent(), true);
443+
$data = $result['data'];
444+
445+
$this->assertArrayHasKey('__schema', $data);
446+
}
447+
448+
public function testDisableIntrospection(): void
449+
{
450+
$kernel = new GraphqliteTestingKernel(true, null, true, null, false, 2, 2);
451+
$kernel->boot();
452+
453+
$request = Request::create('/graphql', 'POST', ['query' => '
454+
{
455+
__schema {
456+
queryType {
457+
name
458+
}
459+
}
460+
}
461+
']);
462+
463+
$response = $kernel->handle($request);
464+
465+
$result = json_decode($response->getContent(), true);
466+
$errors = $result['errors'];
467+
468+
$this->assertSame('GraphQL introspection is not allowed, but the query contained __schema or __type', $errors[0]['message']);
469+
}
470+
471+
public function testMaxQueryComplexity(): void
472+
{
473+
$kernel = new GraphqliteTestingKernel(true, null, true, null, false, 2, null);
474+
$kernel->boot();
475+
476+
$request = Request::create('/graphql', 'POST', ['query' => '
477+
{
478+
products
479+
{
480+
name,
481+
price,
482+
seller {
483+
name
484+
}
485+
}
486+
}
487+
']);
488+
489+
$response = $kernel->handle($request);
490+
491+
$result = json_decode($response->getContent(), true);
492+
$errors = $result['errors'];
493+
494+
$this->assertSame('Max query complexity should be 2 but got 5.', $errors[0]['message']);
495+
}
496+
497+
public function testMaxQueryDepth(): void
498+
{
499+
$kernel = new GraphqliteTestingKernel(true, null, true, null, false, null, 1);
500+
$kernel->boot();
501+
502+
$request = Request::create('/graphql', 'POST', ['query' => '
503+
{
504+
products
505+
{
506+
name,
507+
price,
508+
seller {
509+
name
510+
manager {
511+
name
512+
manager {
513+
name
514+
}
515+
}
516+
}
517+
}
518+
}
519+
']);
520+
521+
$response = $kernel->handle($request);
522+
523+
$result = json_decode($response->getContent(), true);
524+
$errors = $result['errors'];
525+
526+
$this->assertSame('Max query depth should be 1 but got 3.', $errors[0]['message']);
527+
}
528+
425529
private function logIn(ContainerInterface $container)
426530
{
427531
// put a token into the storage so the final calls can function

Tests/GraphqliteTestingKernel.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,29 @@ class GraphqliteTestingKernel extends Kernel
3737
* @var string|null
3838
*/
3939
private $enableMe;
40+
/**
41+
* @var bool
42+
*/
43+
private $introspection;
44+
/**
45+
* @var int|null
46+
*/
47+
private $maximumQueryComplexity;
48+
/**
49+
* @var int|null
50+
*/
51+
private $maximumQueryDepth;
4052

41-
public function __construct(bool $enableSession = true, ?string $enableLogin = null, bool $enableSecurity = true, ?string $enableMe = null)
53+
public function __construct(bool $enableSession = true, ?string $enableLogin = null, bool $enableSecurity = true, ?string $enableMe = null, bool $introspection = true, ?int $maximumQueryComplexity = null, ?int $maximumQueryDepth = null)
4254
{
4355
parent::__construct('test', true);
4456
$this->enableSession = $enableSession;
4557
$this->enableLogin = $enableLogin;
4658
$this->enableSecurity = $enableSecurity;
4759
$this->enableMe = $enableMe;
60+
$this->introspection = $introspection;
61+
$this->maximumQueryComplexity = $maximumQueryComplexity;
62+
$this->maximumQueryDepth = $maximumQueryDepth;
4863
}
4964

5065
public function registerBundles()
@@ -126,6 +141,18 @@ public function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
126141
$graphqliteConf['security']['enable_me'] = $this->enableMe;
127142
}
128143

144+
if ($this->introspection === false) {
145+
$graphqliteConf['security']['introspection'] = false;
146+
}
147+
148+
if ($this->maximumQueryComplexity !== null) {
149+
$graphqliteConf['security']['maximum_query_complexity'] = $this->maximumQueryComplexity;
150+
}
151+
152+
if ($this->maximumQueryDepth !== null) {
153+
$graphqliteConf['security']['maximum_query_depth'] = $this->maximumQueryDepth;
154+
}
155+
129156
$container->loadFromExtension('graphqlite', $graphqliteConf);
130157
});
131158
$confDir = $this->getProjectDir().'/Tests/Fixtures/config';
@@ -143,6 +170,6 @@ protected function configureRoutes(RouteCollectionBuilder $routes)
143170

144171
public function getCacheDir()
145172
{
146-
return __DIR__.'/../cache/'.($this->enableSession?'withSession':'withoutSession').$this->enableLogin.($this->enableSecurity?'withSecurity':'withoutSecurity').$this->enableMe;
173+
return __DIR__.'/../cache/'.($this->enableSession?'withSession':'withoutSession').$this->enableLogin.($this->enableSecurity?'withSecurity':'withoutSecurity').$this->enableMe.'_'.($this->introspection?'withIntrospection':'withoutIntrospection').'_'.$this->maximumQueryComplexity.'_'.$this->maximumQueryDepth;
147174
}
148175
}

0 commit comments

Comments
 (0)