EndToEndTest::setUp()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 113
Code Lines 81

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 81
dl 0
loc 113
rs 8.4145
c 0
b 0
f 0
cc 1
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace TheCodingMachine\GraphQL\Controllers\Integration;
4
5
use function class_exists;
6
use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader;
7
use Exception;
8
use GraphQL\Error\Debug;
9
use GraphQL\GraphQL;
10
use GraphQL\Type\Definition\InputType;
11
use Mouf\Picotainer\Picotainer;
12
use PhpParser\Comment\Doc;
13
use PHPUnit\Framework\TestCase;
14
use PHPUnit\Util\Type;
15
use function print_r;
16
use Psr\Container\ContainerInterface;
17
use Psr\Container\NotFoundExceptionInterface;
18
use Symfony\Component\Cache\Simple\ArrayCache;
19
use TheCodingMachine\GraphQL\Controllers\AnnotationReader;
20
use TheCodingMachine\GraphQL\Controllers\FieldsBuilderFactory;
21
use TheCodingMachine\GraphQL\Controllers\Fixtures\Integration\Models\Contact;
22
use TheCodingMachine\GraphQL\Controllers\GlobControllerQueryProvider;
23
use TheCodingMachine\GraphQL\Controllers\Hydrators\HydratorInterface;
24
use TheCodingMachine\GraphQL\Controllers\Hydrators\FactoryHydrator;
25
use TheCodingMachine\GraphQL\Controllers\InputTypeGenerator;
26
use TheCodingMachine\GraphQL\Controllers\InputTypeUtils;
27
use TheCodingMachine\GraphQL\Controllers\Mappers\CompositeTypeMapper;
28
use TheCodingMachine\GraphQL\Controllers\Mappers\GlobTypeMapper;
29
use TheCodingMachine\GraphQL\Controllers\Mappers\PorpaginasTypeMapper;
30
use TheCodingMachine\GraphQL\Controllers\Mappers\RecursiveTypeMapper;
31
use TheCodingMachine\GraphQL\Controllers\Mappers\RecursiveTypeMapperInterface;
32
use TheCodingMachine\GraphQL\Controllers\Mappers\TypeMapperInterface;
33
use TheCodingMachine\GraphQL\Controllers\NamingStrategy;
34
use TheCodingMachine\GraphQL\Controllers\NamingStrategyInterface;
35
use TheCodingMachine\GraphQL\Controllers\QueryProviderInterface;
36
use TheCodingMachine\GraphQL\Controllers\Containers\BasicAutoWiringContainer;
37
use TheCodingMachine\GraphQL\Controllers\Containers\EmptyContainer;
38
use TheCodingMachine\GraphQL\Controllers\Reflection\CachedDocBlockFactory;
39
use TheCodingMachine\GraphQL\Controllers\Schema;
40
use TheCodingMachine\GraphQL\Controllers\Security\AuthenticationServiceInterface;
41
use TheCodingMachine\GraphQL\Controllers\Security\AuthorizationServiceInterface;
42
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
43
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
44
use TheCodingMachine\GraphQL\Controllers\TypeGenerator;
45
use TheCodingMachine\GraphQL\Controllers\TypeRegistry;
46
use TheCodingMachine\GraphQL\Controllers\Types\TypeResolver;
47
use function var_dump;
48
use function var_export;
49
50
class EndToEndTest extends TestCase
51
{
52
    /**
53
     * @var ContainerInterface
54
     */
55
    private $mainContainer;
56
57
    public function setUp()
58
    {
59
        $this->mainContainer = new Picotainer([
60
            Schema::class => function(ContainerInterface $container) {
61
                return new Schema($container->get(QueryProviderInterface::class), $container->get(RecursiveTypeMapperInterface::class), $container->get(TypeResolver::class));
62
            },
63
            QueryProviderInterface::class => function(ContainerInterface $container) {
64
                return new GlobControllerQueryProvider('TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\Integration\\Controllers', $container->get(FieldsBuilderFactory::class),
65
                    $container->get(RecursiveTypeMapperInterface::class), $container->get(BasicAutoWiringContainer::class), new ArrayCache());
66
            },
67
            FieldsBuilderFactory::class => function(ContainerInterface $container) {
68
                return new FieldsBuilderFactory(
69
                    $container->get(AnnotationReader::class),
70
                    $container->get(HydratorInterface::class),
71
                    $container->get(AuthenticationServiceInterface::class),
72
                    $container->get(AuthorizationServiceInterface::class),
73
                    $container->get(TypeResolver::class),
74
                    $container->get(CachedDocBlockFactory::class),
75
                    $container->get(NamingStrategyInterface::class)
76
                );
77
            },
78
            TypeResolver::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

78
            TypeResolver::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
79
                return new TypeResolver();
80
            },
81
            BasicAutoWiringContainer::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

81
            BasicAutoWiringContainer::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
82
                return new BasicAutoWiringContainer(new EmptyContainer());
83
            },
84
            AuthorizationServiceInterface::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

84
            AuthorizationServiceInterface::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
85
                return new VoidAuthorizationService();
86
            },
87
            AuthenticationServiceInterface::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

87
            AuthenticationServiceInterface::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
88
                return new VoidAuthenticationService();
89
            },
90
            RecursiveTypeMapperInterface::class => function(ContainerInterface $container) {
91
                return new RecursiveTypeMapper(
92
                    $container->get(TypeMapperInterface::class),
93
                    $container->get(NamingStrategyInterface::class),
94
                    new ArrayCache(),
95
                    $container->get(TypeRegistry::class)
96
                );
97
            },
98
            TypeMapperInterface::class => function(ContainerInterface $container) {
99
                return new CompositeTypeMapper([
100
                    $container->get(GlobTypeMapper::class),
101
                    $container->get(GlobTypeMapper::class.'2'),
102
                    $container->get(PorpaginasTypeMapper::class),
103
                ]);
104
            },
105
            GlobTypeMapper::class => function(ContainerInterface $container) {
106
                return new GlobTypeMapper('TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\Integration\\Types',
107
                    $container->get(TypeGenerator::class),
108
                    $container->get(InputTypeGenerator::class),
109
                    $container->get(InputTypeUtils::class),
110
                    $container->get(BasicAutoWiringContainer::class),
111
                    $container->get(AnnotationReader::class),
112
                    $container->get(NamingStrategyInterface::class),
113
                    new ArrayCache()
114
                    );
115
            },
116
            GlobTypeMapper::class.'2' => function(ContainerInterface $container) {
117
                return new GlobTypeMapper('TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\Integration\\Models',
118
                    $container->get(TypeGenerator::class),
119
                    $container->get(InputTypeGenerator::class),
120
                    $container->get(InputTypeUtils::class),
121
                    $container->get(BasicAutoWiringContainer::class),
122
                    $container->get(AnnotationReader::class),
123
                    $container->get(NamingStrategyInterface::class),
124
                    new ArrayCache()
125
                );
126
            },
127
            PorpaginasTypeMapper::class => function() {
128
                return new PorpaginasTypeMapper();
129
            },
130
            TypeGenerator::class => function(ContainerInterface $container) {
131
                return new TypeGenerator(
132
                    $container->get(AnnotationReader::class),
133
                    $container->get(FieldsBuilderFactory::class),
134
                    $container->get(NamingStrategyInterface::class),
135
                    $container->get(TypeRegistry::class),
136
                    $container->get(BasicAutoWiringContainer::class)
137
                );
138
            },
139
            TypeRegistry::class => function() {
140
                return new TypeRegistry();
141
            },
142
            InputTypeGenerator::class => function(ContainerInterface $container) {
143
                return new InputTypeGenerator(
144
                    $container->get(InputTypeUtils::class),
145
                    $container->get(FieldsBuilderFactory::class),
146
                    $container->get(HydratorInterface::class)
147
                );
148
            },
149
            InputTypeUtils::class => function(ContainerInterface $container) {
150
                return new InputTypeUtils(
151
                    $container->get(AnnotationReader::class),
152
                    $container->get(NamingStrategyInterface::class)
153
                );
154
            },
155
            AnnotationReader::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

155
            AnnotationReader::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
156
                return new AnnotationReader(new DoctrineAnnotationReader());
157
            },
158
            HydratorInterface::class => function(ContainerInterface $container) {
0 ignored issues
show
Unused Code introduced by
The parameter $container is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

158
            HydratorInterface::class => function(/** @scrutinizer ignore-unused */ ContainerInterface $container) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
159
                return new FactoryHydrator();
160
            },
161
            NamingStrategyInterface::class => function() {
162
                return new NamingStrategy();
163
            },
164
            CachedDocBlockFactory::class => function() {
165
                return new CachedDocBlockFactory(new ArrayCache());
166
            }
167
        ]);
168
169
        $this->mainContainer->get(TypeResolver::class)->registerSchema($this->mainContainer->get(Schema::class));
170
    }
171
172
    public function testEndToEnd()
173
    {
174
        /**
175
         * @var Schema $schema
176
         */
177
        $schema = $this->mainContainer->get(Schema::class);
178
179
        $schema->assertValid();
180
181
        $queryString = '
182
        query {
183
            contacts {
184
                name
185
                uppercaseName
186
                ... on User {
187
                    email
188
                }
189
            }
190
        }
191
        ';
192
193
        $result = GraphQL::executeQuery(
194
            $schema,
195
            $queryString
196
        );
197
198
        $this->assertSame([
199
            'contacts' => [
200
                [
201
                    'name' => 'Joe',
202
                    'uppercaseName' => 'JOE'
203
                ],
204
                [
205
                    'name' => 'Bill',
206
                    'uppercaseName' => 'BILL',
207
                    'email' => '[email protected]'
208
                ]
209
210
            ]
211
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
212
213
        // Let's redo this to test cache.
214
        $result = GraphQL::executeQuery(
215
            $schema,
216
            $queryString
217
        );
218
219
        $this->assertSame([
220
            'contacts' => [
221
                [
222
                    'name' => 'Joe',
223
                    'uppercaseName' => 'JOE'
224
                ],
225
                [
226
                    'name' => 'Bill',
227
                    'uppercaseName' => 'BILL',
228
                    'email' => '[email protected]'
229
                ]
230
231
            ]
232
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
233
    }
234
235
    public function testEndToEndInputType()
236
    {
237
        /**
238
         * @var Schema $schema
239
         */
240
        $schema = $this->mainContainer->get(Schema::class);
241
        $queryString = '
242
        mutation {
243
          saveContact(
244
            contact: {
245
                name: "foo",
246
                birthDate: "1942-12-24 00:00:00",
247
                relations: [
248
                    {
249
                        name: "bar"
250
                        birthDate: "1942-12-24 00:00:00",
251
                    }
252
                ]
253
            }
254
          ) {
255
            name,
256
            birthDate,
257
            relations {
258
              name,
259
              birthDate
260
            }
261
          }
262
        }
263
        ';
264
265
        $result = GraphQL::executeQuery(
266
            $schema,
267
            $queryString
268
        );
269
270
        $this->assertSame([
271
            'saveContact' => [
272
                'name' => 'foo',
273
                'birthDate' => '1942-12-24T00:00:00+00:00',
274
                'relations' => [
275
                    [
276
                        'name' => 'bar',
277
                        'birthDate' => '1942-12-24T00:00:00+00:00'
278
                    ]
279
                ]
280
            ]
281
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
282
    }
283
284
    public function testEndToEndPorpaginas()
285
    {
286
        /**
287
         * @var Schema $schema
288
         */
289
        $schema = $this->mainContainer->get(Schema::class);
290
291
        $queryString = '
292
        query {
293
            contactsIterator {
294
                items(limit: 1, offset: 1) {
295
                    name
296
                    uppercaseName
297
                    ... on User {
298
                        email
299
                    }
300
                }
301
                count
302
            }
303
        }
304
        ';
305
306
        $result = GraphQL::executeQuery(
307
            $schema,
308
            $queryString
309
        );
310
311
        $this->assertSame([
312
            'contactsIterator' => [
313
                'items' => [
314
                    [
315
                        'name' => 'Bill',
316
                        'uppercaseName' => 'BILL',
317
                        'email' => '[email protected]'
318
                    ]
319
                ],
320
                'count' => 2
321
            ]
322
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
323
324
        // Let's redo this to test cache.
325
        $result = GraphQL::executeQuery(
326
            $schema,
327
            $queryString
328
        );
329
330
        $this->assertSame([
331
            'contactsIterator' => [
332
                'items' => [
333
                    [
334
                        'name' => 'Bill',
335
                        'uppercaseName' => 'BILL',
336
                        'email' => '[email protected]'
337
                    ]
338
                ],
339
                'count' => 2
340
            ]
341
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
342
343
        // Let's run a query with no limit but an offset
344
        $invalidQueryString = '
345
        query {
346
            contactsIterator {
347
                items(offset: 1) {
348
                    name
349
                    ... on User {
350
                        email
351
                    }
352
                }
353
                count
354
            }
355
        }
356
        ';
357
358
        $result = GraphQL::executeQuery(
359
            $schema,
360
            $invalidQueryString
361
        );
362
363
        $this->assertSame('In the items field of a result set, you cannot add a "offset" without also adding a "limit"', $result->toArray(Debug::RETHROW_UNSAFE_EXCEPTIONS)['errors'][0]['message']);
364
365
366
        // Let's run a query with no limit offset
367
        $invalidQueryString = '
368
        query {
369
            contactsIterator {
370
                items {
371
                    name
372
                    ... on User {
373
                        email
374
                    }
375
                }
376
                count
377
            }
378
        }
379
        ';
380
381
        $result = GraphQL::executeQuery(
382
            $schema,
383
            $invalidQueryString
384
        );
385
386
        $this->assertSame([
387
            'contactsIterator' => [
388
                'items' => [
389
                    [
390
                        'name' => 'Joe',
391
                    ],
392
                    [
393
                        'name' => 'Bill',
394
                        'email' => '[email protected]'
395
                    ]
396
                ],
397
                'count' => 2
398
            ]
399
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
400
    }
401
402
    /**
403
     * This tests is used to be sure that the PorpaginasIterator types are not mixed up when cached (because it has a subtype)
404
     */
405
    public function testEndToEnd2Iterators()
406
    {
407
        /**
408
         * @var Schema $schema
409
         */
410
        $schema = $this->mainContainer->get(Schema::class);
411
412
        $queryString = '
413
        query {
414
            contactsIterator {
415
                items(limit: 1, offset: 1) {
416
                    name
417
                    uppercaseName
418
                    ... on User {
419
                        email
420
                    }
421
                }
422
                count
423
            }
424
            
425
            products {
426
                items {
427
                    name
428
                    price
429
                }
430
                count            
431
            }
432
        }
433
        ';
434
435
        $result = GraphQL::executeQuery(
436
            $schema,
437
            $queryString
438
        );
439
440
        $this->assertSame([
441
            'contactsIterator' => [
442
                'items' => [
443
                    [
444
                        'name' => 'Bill',
445
                        'uppercaseName' => 'BILL',
446
                        'email' => '[email protected]'
447
                    ]
448
                ],
449
                'count' => 2
450
            ],
451
            'products' => [
452
                'items' => [
453
                    [
454
                        'name' => 'Foo',
455
                        'price' => 42.0,
456
                    ]
457
                ],
458
                'count' => 1
459
            ]
460
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
461
462
    }
463
}
464