Skip to content

Commit 97afdbc

Browse files
jpnutMikk Mihkel Nurges
authored andcommitted
Conditional validation for nested nullable input fields (#185)
* Fix batching and enums sections (#183) I was reading through the docs for this and noticed the accidental opening of a code block breaking the markdown for the "batching" and "enums" sections. * Comment undefined classes in config.php (#184) * Include a pre-validation check for the existence of nullable fields. Validation is now skipped for nullable fields which are not included in the request. Tests have been updated to ensure that: - validation is skipped for nullable fields which are absent - validation is run for nullable fields when present - validation is run for non-nullable fields regardless of presence * tidy up mutation test This additional call to get the field rules isn't being used anywhere, so it can safely be removed. * Revert non-nested object tests I had thought that this change would also affect the other fields in the tests, however this change only affects nested input objects since the nullable check is run after rules have been obtained from the initial field. * Refactoring
1 parent a9212ad commit 97afdbc

File tree

5 files changed

+47
-22
lines changed

5 files changed

+47
-22
lines changed

docs/advanced.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,6 @@ If you want to change the name of a default field to fit with users expectations
552552
than 'total'), just copy the entry for the field you want to replace (they're in Rebing/GraphQL/Support/PaginationType.php)
553553
and add it to your custom class.
554554

555-
```
556555
### Batching
557556

558557
You can send multiple queries (or mutations) at once by grouping them together. Therefore, instead of creating two HTTP requests:

src/Rebing/GraphQL/Support/Field.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ public function getRules()
7373
}
7474
}
7575

76-
if (isset($arg['type'])) {
76+
if (isset($arg['type'])
77+
&& ($arg['type'] instanceof NonNull || isset(array_get($arguments, 0, [])[$name]))) {
7778
$argsRules = array_merge($argsRules, $this->inferRulesFromType($arg['type'], $name, $arguments));
7879
}
7980
}

src/config/config.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@
100100
'schemas' => [
101101
'default' => [
102102
'query' => [
103-
'example_query' => ExampleQuery::class,
103+
// 'example_query' => ExampleQuery::class,
104104
],
105105
'mutation' => [
106-
'example_mutation' => ExampleMutation::class,
106+
// 'example_mutation' => ExampleMutation::class,
107107
],
108108
'middleware' => [],
109109
'method' => ['get', 'post'],
@@ -120,8 +120,8 @@
120120
// ]
121121
//
122122
'types' => [
123-
'example' => ExampleType::class,
124-
'relation_example' => ExampleRelationType::class,
123+
// 'example' => ExampleType::class,
124+
// 'relation_example' => ExampleRelationType::class,
125125
],
126126

127127
// This callable will be passed the Error object for each errors GraphQL catch.

tests/MutationTest.php

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ public function testGetRules()
3838
$this->assertEquals($rules['test'], ['required']);
3939
$this->assertEquals($rules['test_with_rules'], ['required']);
4040
$this->assertEquals($rules['test_with_rules_closure'], ['required']);
41-
$this->assertEquals($rules['test_with_rules_input_object'], ['required']);
42-
$this->assertEquals(array_get($rules, 'test_with_rules_input_object.val'), ['required']);
43-
$this->assertEquals(array_get($rules, 'test_with_rules_input_object.nest'), ['required']);
44-
$this->assertEquals(array_get($rules, 'test_with_rules_input_object.nest.email'), ['email']);
45-
$this->assertEquals(array_get($rules, 'test_with_rules_input_object.list'), ['required']);
46-
$this->assertEquals(array_get($rules, 'test_with_rules_input_object.list.*.email'), ['email']);
41+
$this->assertEquals($rules['test_with_rules_nullable_input_object'], ['nullable']);
42+
$this->assertNull(array_get($rules, 'test_with_rules_nullable_input_object.val'));
43+
$this->assertNull(array_get($rules, 'test_with_rules_nullable_input_object.nest'));
44+
$this->assertNull(array_get($rules, 'test_with_rules_nullable_input_object.nest.email'));
45+
$this->assertNull(array_get($rules, 'test_with_rules_nullable_input_object.list'));
46+
$this->assertNull(array_get($rules, 'test_with_rules_nullable_input_object.list.*.email'));
47+
$this->assertEquals($rules['test_with_rules_non_nullable_input_object'], ['required']);
48+
$this->assertEquals(array_get($rules, 'test_with_rules_non_nullable_input_object.val'), ['required']);
49+
$this->assertEquals(array_get($rules, 'test_with_rules_non_nullable_input_object.nest'), ['required']);
50+
$this->assertEquals(array_get($rules, 'test_with_rules_non_nullable_input_object.nest.email'), ['email']);
51+
$this->assertEquals(array_get($rules, 'test_with_rules_non_nullable_input_object.list'), ['required']);
52+
$this->assertEquals(array_get($rules, 'test_with_rules_non_nullable_input_object.list.*.email'), ['email']);
4753
}
4854

4955
/**
@@ -66,7 +72,14 @@ public function testResolve()
6672
'test' => 'test',
6773
'test_with_rules' => 'test',
6874
'test_with_rules_closure' => 'test',
69-
'test_with_rules_input_object' => [
75+
'test_with_rules_nullable_input_object' => [
76+
'val' => 'test',
77+
'nest' => ['email' => 'test@test.com'],
78+
'list' => [
79+
['email' => 'test@test.com'],
80+
],
81+
],
82+
'test_with_rules_non_nullable_input_object' => [
7083
'val' => 'test',
7184
'nest' => ['email' => 'test@test.com'],
7285
'list' => [
@@ -115,9 +128,12 @@ public function testValidationError()
115128
$this->assertTrue($messages->has('test'));
116129
$this->assertTrue($messages->has('test_with_rules'));
117130
$this->assertTrue($messages->has('test_with_rules_closure'));
118-
$this->assertTrue($messages->has('test_with_rules_input_object.val'));
119-
$this->assertTrue($messages->has('test_with_rules_input_object.nest'));
120-
$this->assertTrue($messages->has('test_with_rules_input_object.list'));
131+
$this->assertFalse($messages->has('test_with_rules_nullable_input_object.val'));
132+
$this->assertFalse($messages->has('test_with_rules_nullable_input_object.nest'));
133+
$this->assertFalse($messages->has('test_with_rules_nullable_input_object.list'));
134+
$this->assertTrue($messages->has('test_with_rules_non_nullable_input_object.val'));
135+
$this->assertTrue($messages->has('test_with_rules_non_nullable_input_object.nest'));
136+
$this->assertTrue($messages->has('test_with_rules_non_nullable_input_object.list'));
121137
}
122138
}
123139

@@ -130,19 +146,22 @@ public function testCustomValidationErrorMessages()
130146
{
131147
$class = $this->getFieldClass();
132148
$field = new $class();
133-
$rules = $field->getRules();
134149
$attributes = $field->getAttributes();
135150
try {
136151
$attributes['resolve'](null, [
137-
'test_with_rules_input_object' => [
138-
'nest' => ['email' => 'invalidTestEmail.com'],
139-
],
152+
'test_with_rules_nullable_input_object' => [
153+
'nest' => ['email' => 'invalidTestEmail.com'],
154+
],
155+
'test_with_rules_non_nullable_input_object' => [
156+
'nest' => ['email' => 'invalidTestEmail.com'],
157+
],
140158
], [], null);
141159
} catch (\Rebing\GraphQL\Error\ValidationError $e) {
142160
$messages = $e->getValidatorMessages();
143161

144162
$this->assertEquals($messages->first('test'), 'The test field is required.');
145-
$this->assertEquals($messages->first('test_with_rules_input_object.nest.email'), 'The test with rules input object.nest.email must be a valid email address.');
163+
$this->assertEquals($messages->first('test_with_rules_nullable_input_object.nest.email'), 'The test with rules nullable input object.nest.email must be a valid email address.');
164+
$this->assertEquals($messages->first('test_with_rules_non_nullable_input_object.nest.email'), 'The test with rules non nullable input object.nest.email must be a valid email address.');
146165
}
147166
}
148167
}

tests/Objects/UpdateExampleMutationWithInputType.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,15 @@ public function args()
4444
},
4545
],
4646

47-
'test_with_rules_input_object' => [
47+
'test_with_rules_nullable_input_object' => [
4848
'name' => 'test',
4949
'type' => GraphQL::type('ExampleValidationInputObject'),
50+
'rules' => ['nullable'],
51+
],
52+
53+
'test_with_rules_non_nullable_input_object' => [
54+
'name' => 'test',
55+
'type' => Type::nonNull(GraphQL::type('ExampleValidationInputObject')),
5056
'rules' => ['required'],
5157
],
5258
];

0 commit comments

Comments
 (0)