Passed
Push — master ( aa560d...df21f1 )
by Max
04:04
created

InputObjectValidationTest::setUp()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 47
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 29
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 47
rs 9.456
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQL\Tests\Type\ValidatedFieldDefinition;
6
7
use GraphQL\GraphQL;
8
use GraphQL\Tests\Utils;
9
use GraphQL\Type\Definition\InputObjectType;
10
use GraphQL\Type\Definition\ObjectType;
11
use GraphQL\Type\Definition\Type;
12
use GraphQL\Type\Definition\UserErrorsType;
13
use GraphQL\Type\Definition\ValidatedFieldDefinition;
14
use GraphQL\Type\Schema;
15
use PHPUnit\Framework\TestCase;
16
use function strlen;
17
18
final class InputObjectValidationTest extends TestCase
19
{
20
    /** @var Type */
21
    protected $bookType;
22
23
    /** @var InputObjectType */
24
    protected $bookAttributesInputType;
25
26
    /** @var Type */
27
    protected $personType;
28
29
    /** @var mixed[] */
30
    protected $data = [
31
        'people' => [
32
            1 => ['firstName' => 'Wilson'],
33
            2 => ['firstName' => 'J.D.'],
34
            3 => ['firstName' => 'Diana'],
35
        ],
36
    ];
37
38
    /** @var ObjectType */
39
    protected $query;
40
41
    /** @var Schema */
42
    protected $schema;
43
44
    protected function setUp(): void
45
    {
46
        $this->personType = new ObjectType([
47
            'name' => 'Person',
48
            'fields' => [
49
                'firstName' => [
50
                    'type' => Type::string(),
51
                    'phoneNumbers' => [
52
                        'type' => Type::listOf(Type::string()),
53
                    ],
54
                ],
55
            ],
56
        ]);
57
58
        $this->bookAttributesInputType = new InputObjectType([
59
            'name' => 'BookAttributes',
60
            'fields' => [
61
                'title' => [
62
                    'type' => Type::string(),
63
                    'description' => 'Enter a book title, no more than 10 characters in length',
64
                    'validate' => static function (string $title) {
65
                        if (strlen($title) > 10) {
66
                            return [1, 'book title must be less than 10 chaacters'];
67
                        }
68
                        return 0;
69
                    },
70
                ],
71
                'author' => [
72
                    'type' => Type::id(),
73
                    'description' => 'Provide a valid author id',
74
                    'errorCodes' => [
75
                        'unknownAuthor',
76
                        'authorDeceased',
77
                    ],
78
                    'validate' => function (string $authorId) {
79
                        if (!isset($this->data['people'][$authorId])) {
80
                            return ['unknownAuthor', 'We have no record of that author'];
81
                        }
82
                        return 0;
83
                    },
84
                ],
85
            ],
86
        ]);
87
88
        $this->query = new ObjectType(['name' => 'Query']);
89
90
        $this->schema = $this->_createSchema();
91
    }
92
93
    protected function _createSchema() {
94
        return new Schema([
95
            'query' => $this->query,
96
            'mutation' => new ObjectType([
97
                'name' => 'Mutation',
98
                'fields' => function () {
99
                    return [
100
                        'updateBook' => new ValidatedFieldDefinition([
101
                            'name' => 'updateBook',
102
                            'type' => Type::boolean(),
103
                            'args' => [
104
                                'bookAttributes' => [
105
                                    'type' => $this->bookAttributesInputType,
106
                                    'errorCodes' => ['titleOrIdRequired'],
107
                                    'validate' => static function (?array $bookAttributes) {
108
                                        if (empty($bookAttributes)) {
109
                                            return 0;
110
                                        }
111
112
                                        return isset($bookAttributes['title']) || isset($bookAttributes['author']) ? 0 : [
113
                                            'titleOrIdRequired',
114
                                            'You must supply at least one of title or author',
115
                                        ];
116
                                    },
117
                                ],
118
                            ],
119
                            'resolve' => static function ($value) : bool {
120
                                // ...
121
                                // do update
122
                                // ...
123
124
                                return !$value;
125
                            },
126
                        ]),
127
                    ];
128
                },
129
            ]),
130
        ]);
131
    }
132
    
133
    public function testValidationInputObjectFieldFail(): void
134
    {
135
        $res = GraphQL::executeQuery(
136
            $this->schema,
137
            Utils::nowdoc('
138
                mutation UpdateBook(
139
                        $bookAttributes: BookAttributes
140
                    ) {
141
                    updateBook (
142
                        bookAttributes: $bookAttributes
143
                    ) {
144
                        valid
145
                        suberrors {
146
                            bookAttributes {
147
                                suberrors {
148
                                    title {
149
                                        code
150
                                        msg
151
                                    }
152
                                    author {
153
                                        code
154
                                        msg
155
                                    }
156
                                }
157
                            }
158
                        }
159
                        result
160
                    }
161
                }
162
            '),
163
            [],
164
            null,
165
            [
166
                'bookAttributes' => [
167
                    'title' => 'The Catcher in the Rye',
168
                    'author' => 4,
169
                ],
170
            ]
171
        );
172
173
        static::assertEquals(
174
            [
175
                'valid' => false,
176
                'suberrors' =>
177
                    [
178
                        'bookAttributes' =>
179
                            [
180
                                'suberrors' =>
181
                                    [
182
                                        'title' =>
183
                                            [
184
                                                'code' => 1,
185
                                                'msg' => 'book title must be less than 10 chaacters',
186
                                            ],
187
                                        'author' =>
188
                                            [
189
                                                'code' => 'unknownAuthor',
190
                                                'msg' => 'We have no record of that author',
191
                                            ],
192
                                    ],
193
                            ],
194
                    ],
195
                'result' => null,
196
            ],
197
            $res->data['updateBook']
198
        );
199
200
        static::assertFalse($res->data['updateBook']['valid']);
201
    }
202
203
    public function testValidationInputObjectSelfFail(): void
204
    {
205
        $res = GraphQL::executeQuery(
206
            $this->schema,
207
            Utils::nowdoc('
208
                mutation UpdateBook(
209
                        $bookAttributes: BookAttributes
210
                    ) {
211
                    updateBook (
212
                        bookAttributes: $bookAttributes
213
                    ) {
214
                        valid
215
                        suberrors {
216
                            bookAttributes {
217
                                code
218
                                msg
219
                                suberrors {
220
                                    title {
221
                                        code
222
                                        msg
223
                                    }
224
                                    author {
225
                                        code
226
                                        msg
227
                                    }
228
                                }
229
                            }
230
                        }
231
                        result
232
                    }
233
                }
234
            '),
235
            [],
236
            null,
237
            [
238
                'bookAttributes' => [
239
                    'title' => null,
240
                    'author' => null,
241
                ],
242
            ]
243
        );
244
245
        static::assertEquals(
246
            [
247
                'valid' => false,
248
                'suberrors' =>
249
                    [
250
                        'bookAttributes' =>
251
                            [
252
                                'code' => 'titleOrIdRequired',
253
                                'msg' => 'You must supply at least one of title or author',
254
                                'suberrors' => null,
255
                            ],
256
                    ],
257
                'result' => null,
258
            ],
259
            $res->data['updateBook']
260
        );
261
262
        static::assertFalse($res->data['updateBook']['valid']);
263
    }
264
265
    public function testValidationSuccess(): void
266
    {
267
        $res = GraphQL::executeQuery(
268
            $this->schema,
269
            Utils::nowdoc('
270
                mutation UpdateBook(
271
                    $bookAttributes: BookAttributes
272
                ) {
273
                    updateBook (
274
                        bookAttributes: $bookAttributes
275
                    ) {
276
                        valid
277
                        suberrors {
278
                            bookAttributes {
279
                                suberrors {
280
                                    title {
281
                                        code
282
                                        msg
283
                                    }
284
                                    author {
285
                                        code
286
                                        msg
287
                                    }
288
                                }
289
                            }
290
                        }
291
                        result
292
                    }
293
                }
294
            '),
295
            [],
296
            null,
297
            [
298
                'bookAttributes' => [
299
                    'title' => 'Dogsbody',
300
                    'author' => 3,
301
                ],
302
            ]
303
        );
304
305
        static::assertEmpty($res->errors);
306
        static::assertEquals(
307
            [
308
                'valid' => true,
309
                'suberrors' => null,
310
                'result' => true,
311
            ],
312
            $res->data['updateBook']
313
        );
314
315
        static::assertTrue($res->data['updateBook']['valid']);
316
    }
317
318
    public function testValidationEmptyInput(): void
319
    {
320
        $res = GraphQL::executeQuery(
321
            $this->schema,
322
            Utils::nowdoc('
323
                mutation UpdateBook(
324
                        $bookAttributes: BookAttributes
325
                    ) {
326
                    updateBook (
327
                        bookAttributes: $bookAttributes
328
                    ) {
329
                        valid
330
                        suberrors {
331
                            bookAttributes {
332
                                suberrors {
333
                                    title {
334
                                        code
335
                                        msg
336
                                    }
337
                                    author {
338
                                        code
339
                                        msg
340
                                    }
341
                                }
342
                            }
343
                        }
344
                        result
345
                    }
346
                }
347
            '),
348
            [],
349
            null,
350
            ['bookAttributes' => null]
351
        );
352
353
        static::assertEmpty($res->errors);
354
        static::assertEquals(
355
            [
356
                'valid' => true,
357
                'suberrors' => null,
358
                'result' => true,
359
            ],
360
            $res->data['updateBook']
361
        );
362
363
        static::assertTrue($res->data['updateBook']['valid']);
364
    }
365
}
366