Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #311 from digiaonline/fix-empty-bug
Browse files Browse the repository at this point in the history
Fix "Cannot use false as value for non-null booleans in input types"
  • Loading branch information
Jalle19 authored Oct 22, 2018
2 parents 4c1d466 + fce30f3 commit 1a8dd86
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Execution/ValuesHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ protected function coerceValueForInputObjectType(
foreach ($fields as $field) {
$fieldType = $field->getType();

if (empty($value[$field->getName()])) {
if (!isset($value[$field->getName()])) {
if (!empty($field->getDefaultValue())) {
$coercedValue[$field->getName()] = $field->getDefaultValue();
} elseif ($fieldType instanceof NonNullType) {
Expand Down
130 changes: 130 additions & 0 deletions tests/Functional/Execution/ValuesHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
namespace Digia\GraphQL\Test\Functional\Execution;

use Digia\GraphQL\Execution\ExecutionContext;
use Digia\GraphQL\Execution\ValuesHelper;
use Digia\GraphQL\Language\Node\ArgumentsAwareInterface;
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
use Digia\GraphQL\Language\Node\StringValueNode;
use Digia\GraphQL\Test\TestCase;
use function Digia\GraphQL\Execution\coerceArgumentValues;
use function Digia\GraphQL\Execution\coerceVariableValues;
use function Digia\GraphQL\parse;
use function Digia\GraphQL\Type\booleanType;
use function Digia\GraphQL\Type\newInputObjectType;
use function Digia\GraphQL\Type\newNonNull;
use function Digia\GraphQL\Type\newObjectType;
use function Digia\GraphQL\Type\newSchema;
Expand Down Expand Up @@ -97,4 +100,131 @@ public function testCoerceVariableValues(): void
$this->assertEquals([], $coercedValue->getValue());
$this->assertTrue($coercedValue->hasErrors());
}

public function testCoerceValuesForInputObjectTypes(): void
{
// Test input object types
/** @noinspection PhpUnhandledExceptionInspection */
$schema = newSchema([
'query' => newObjectType([
'name' => 'Query',
'fields' => [
'inputObjectField' => [
'type' => booleanType(),
'args' => [
'inputObject' => [
'type' => newInputObjectType([
'name' => 'InputObject',
'fields' => [
'a' => ['type' => stringType()],
'b' => ['type' => newNonNull(stringType())]
]
]
)
],
],
],
],
]),
]);

/** @noinspection PhpUnhandledExceptionInspection */
$documentNode = parse('
query ($inputObject: InputObject!) {
inputObjectField(inputObject: $inputObject)
}
');

/** @var OperationDefinitionNode $operation */
$operation = $documentNode->getDefinitions()[0];
$variableDefinitions = $operation->getVariableDefinitions();

// Test with a missing non-null string
$coercedValue = coerceVariableValues($schema, $variableDefinitions, [
'inputObject' => [
'a' => 'some string'
]
]);

$this->assertTrue($coercedValue->hasErrors());
$this->assertEquals('Variable "$inputObject" got invalid value {"a":"some string"}; Field value.b of required type String! was not provided.',
$coercedValue->getErrors()[0]->getMessage());

// Test again with all variables, no errors expected
$coercedValue = coerceVariableValues($schema, $variableDefinitions, [
'inputObject' => [
'a' => 'some string',
'b' => 'some other required string',
]
]);

$this->assertFalse($coercedValue->hasErrors());

// Test with non-nullable boolean input fields
/** @noinspection PhpUnhandledExceptionInspection */
$schema = newSchema([
'query' => newObjectType([
'name' => 'Query',
'fields' => [
'inputObjectField' => [
'type' => booleanType(),
'args' => [
'inputObject' => [
'type' => newInputObjectType([
'name' => 'InputObject',
'fields' => [
'a' => ['type' => booleanType()],
'b' => ['type' => newNonNull(booleanType())]
]
]
)
],
],
],
],
]),
]);

/** @noinspection PhpUnhandledExceptionInspection */
$documentNode = parse('
query ($inputObject: InputObject!) {
inputObjectField(inputObject: $inputObject)
}
');

/** @var OperationDefinitionNode $operation */
$operation = $documentNode->getDefinitions()[0];
$variableDefinitions = $operation->getVariableDefinitions();

// Test with a missing non-null string
$coercedValue = coerceVariableValues($schema, $variableDefinitions, [
'inputObject' => [
'a' => true
]
]);

$this->assertTrue($coercedValue->hasErrors());
$this->assertEquals('Variable "$inputObject" got invalid value {"a":true}; Field value.b of required type Boolean! was not provided.',
$coercedValue->getErrors()[0]->getMessage());

// Test again with all fields present, all booleans true
$coercedValue = coerceVariableValues($schema, $variableDefinitions, [
'inputObject' => [
'a' => true,
'b' => true,
]
]);

$this->assertFalse($coercedValue->hasErrors());

// Test again with all fields present, all booleans false (this has been problematic before)
$coercedValue = coerceVariableValues($schema, $variableDefinitions, [
'inputObject' => [
'a' => false,
'b' => false,
]
]);

$this->assertFalse($coercedValue->hasErrors());
}
}

0 comments on commit 1a8dd86

Please sign in to comment.