Skip to content

Commit

Permalink
Prevent crashes with explicit nulls on arg directives
Browse files Browse the repository at this point in the history
  • Loading branch information
MissaelAnda committed Sep 18, 2023
1 parent d2fdb8f commit de25722
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Schema/Directives/NotInDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public static function definition(): string

public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, $value): QueryBuilder|EloquentBuilder|Relation
{
if ($value === null) {
return $builder;
}

return $builder->whereNotIn(
$this->directiveArgValue('key', $this->nodeName()),
$value,
Expand Down
4 changes: 4 additions & 0 deletions src/Schema/Directives/WhereBetweenDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public static function definition(): string

public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, $value): QueryBuilder|EloquentBuilder|Relation
{
if ($value === null) {
return $builder;
}

return $builder->whereBetween(
$this->directiveArgValue('key', $this->nodeName()),
$value,
Expand Down
4 changes: 4 additions & 0 deletions src/Schema/Directives/WhereNotBetweenDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public static function definition(): string

public function handleBuilder(QueryBuilder|EloquentBuilder|Relation $builder, $value): QueryBuilder|EloquentBuilder|Relation
{
if ($value === null) {
return $builder;
}

return $builder->whereNotBetween(
$this->directiveArgValue('key', $this->nodeName()),
$value,
Expand Down
132 changes: 132 additions & 0 deletions tests/Integration/Schema/Directives/NotInDirectiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php declare(strict_types=1);

namespace Schema\Directives;

use Tests\DBTestCase;
use Tests\Utils\Models\User;

final class NotInDirectiveTest extends DBTestCase
{
public function testNotInIDs(): void
{
$user1 = factory(User::class)->create();
assert($user1 instanceof User);

$user2 = factory(User::class)->create();
assert($user2 instanceof User);

$this->schema = /** @lang GraphQL */ '
type User {
id: ID!
}
type Query {
users(notIDs: [ID!] @notIn(key: "id")): [User!]! @all
}
';

$user1ID = (string) $user1->id;
$user2ID = (string) $user2->id;

$this
->graphQL(/** @lang GraphQL */ '
query ($notIDs: [ID!]) {
users(notIDs: $notIDs) {
id
}
}
', [
'notIDs' => [$user1ID],
])
->assertJson([
'data' => [
'users' => [
[
'id' => $user2ID,
],
],
],
]);
}

public function testExplicitNull(): void
{
$users = factory(User::class, 2)->create();

$this->schema = /** @lang GraphQL */ '
type User {
id: ID!
}
type Query {
users(notIDs: [ID!] @notIn(key: "id")): [User!]! @all
}
';

$this
->graphQL(/** @lang GraphQL */ '
query ($notIDs: [ID!]) {
users(notIDs: $notIDs) {
id
}
}
', [
'notIDs' => null,
])
->assertJsonCount($users->count(), 'data.users');
}

public function testExplicitNullInArray(): void
{
factory(User::class, 2)->create();

$this->schema = /** @lang GraphQL */ '
type User {
id: ID!
}
type Query {
users(notIDs: [ID] @notIn(key: "id")): [User!]! @all
}
';

$this
->graphQL(/** @lang GraphQL */ '
query ($notIDs: [ID]) {
users(notIDs: $notIDs) {
id
}
}
', [
'notIDs' => [null],
])
->assertJsonCount(0, 'data.users');
}

public function testEmptyArray(): void
{
$users = factory(User::class, 2)->create();

$this->schema = /** @lang GraphQL */ '
type User {
id: ID!
}
type Query {
users(notIDs: [ID!] @notIn(key: "id")): [User!]! @all
}
';

$this
->graphQL(/** @lang GraphQL */ '
query ($notIDs: [ID!]) {
users(notIDs: $notIDs) {
id
}
}
', [
'notIDs' => [],
])
->assertJsonCount($users->count(), 'data.users');
}
}
43 changes: 43 additions & 0 deletions tests/Integration/Schema/Directives/WhereBetweenDirectiveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types=1);

namespace Schema\Directives;

use Tests\DBTestCase;
use Tests\Utils\Models\User;

final class WhereBetweenDirectiveTest extends DBTestCase
{
public function testExplicitNull(): void
{
$users = factory(User::class, 2)->create();

$this->schema = /** @lang GraphQL */'
scalar DateTime @scalar(class: "Nuwave\\\Lighthouse\\\Schema\\\Types\\\Scalars\\\DateTime")
type User {
id: ID!
created_at: DateTime!
}
type Query {
users(createdBetween: DateTimeRange @whereBetween(key: "created_at")): [User!]! @all
}
input DateTimeRange {
from: DateTime!
to: DateTime!
}
';

$this
->graphQL(/** @lang GraphQL */'
{
users(createdBetween: null) {
id
}
}
')
->assertGraphQLErrorFree()
->assertJsonCount($users->count(), 'data.users');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php declare(strict_types=1);

namespace Schema\Directives;

use Tests\DBTestCase;
use Tests\Utils\Models\User;

final class WhereNotBetweenDirectiveTest extends DBTestCase
{
public function testExplicitNull(): void
{
$users = factory(User::class, 2)->create();

$this->schema = /** @lang GraphQL */'
scalar DateTime @scalar(class: "Nuwave\\\Lighthouse\\\Schema\\\Types\\\Scalars\\\DateTime")
type User {
id: ID!
created_at: DateTime!
}
type Query {
users(notCreatedBetween: DateTimeRange @whereNotBetween(key: "created_at")): [User!]! @all
}
input DateTimeRange {
from: DateTime!
to: DateTime!
}
';

$this
->graphQL(/** @lang GraphQL */'
{
users(notCreatedBetween: null) {
id
}
}
')
->assertGraphQLErrorFree()
->assertJsonCount($users->count(), 'data.users');
}
}

0 comments on commit de25722

Please sign in to comment.