Completed
Push — master ( 3977d8...7ec8b3 )
by David
15s queued 11s
created

EndToEndTest::testEndToEnd()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 56
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 21
dl 0
loc 56
rs 9.584
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\Types\TypeResolver;
46
use function var_export;
47
48
class EndToEndTest extends TestCase
49
{
50
    /**
51
     * @var ContainerInterface
52
     */
53
    private $mainContainer;
54
55
    public function setUp()
56
    {
57
        $this->mainContainer = new Picotainer([
58
            Schema::class => function(ContainerInterface $container) {
59
                return new Schema($container->get(QueryProviderInterface::class), $container->get(RecursiveTypeMapperInterface::class), $container->get(TypeResolver::class));
60
            },
61
            QueryProviderInterface::class => function(ContainerInterface $container) {
62
                return new GlobControllerQueryProvider('TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\Integration\\Controllers', $container->get(FieldsBuilderFactory::class),
63
                    $container->get(RecursiveTypeMapperInterface::class), $container->get(BasicAutoWiringContainer::class), new ArrayCache());
64
            },
65
            FieldsBuilderFactory::class => function(ContainerInterface $container) {
66
                return new FieldsBuilderFactory(
67
                    $container->get(AnnotationReader::class),
68
                    $container->get(HydratorInterface::class),
69
                    $container->get(AuthenticationServiceInterface::class),
70
                    $container->get(AuthorizationServiceInterface::class),
71
                    $container->get(TypeResolver::class),
72
                    $container->get(CachedDocBlockFactory::class)
73
                );
74
            },
75
            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

75
            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...
76
                return new TypeResolver();
77
            },
78
            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

78
            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...
79
                return new BasicAutoWiringContainer(new EmptyContainer());
80
            },
81
            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

81
            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...
82
                return new VoidAuthorizationService();
83
            },
84
            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

84
            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...
85
                return new VoidAuthenticationService();
86
            },
87
            RecursiveTypeMapperInterface::class => function(ContainerInterface $container) {
88
                return new RecursiveTypeMapper($container->get(TypeMapperInterface::class), $container->get(NamingStrategyInterface::class), new ArrayCache());
89
            },
90
            TypeMapperInterface::class => function(ContainerInterface $container) {
91
                return new CompositeTypeMapper([
92
                    $container->get(GlobTypeMapper::class),
93
                    $container->get(PorpaginasTypeMapper::class),
94
                ]);
95
            },
96
            GlobTypeMapper::class => function(ContainerInterface $container) {
97
                return new GlobTypeMapper('TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\Integration\\Types',
98
                    $container->get(TypeGenerator::class),
99
                    $container->get(InputTypeGenerator::class),
100
                    $container->get(InputTypeUtils::class),
101
                    $container->get(BasicAutoWiringContainer::class),
102
                    $container->get(AnnotationReader::class),
103
                    $container->get(NamingStrategyInterface::class),
104
                    new ArrayCache()
105
                    );
106
            },
107
            PorpaginasTypeMapper::class => function() {
108
                return new PorpaginasTypeMapper();
109
            },
110
            TypeGenerator::class => function(ContainerInterface $container) {
111
                return new TypeGenerator(
112
                    $container->get(AnnotationReader::class),
113
                    $container->get(FieldsBuilderFactory::class),
114
                    $container->get(NamingStrategyInterface::class)
115
                );
116
            },
117
            InputTypeGenerator::class => function(ContainerInterface $container) {
118
                return new InputTypeGenerator(
119
                    $container->get(InputTypeUtils::class),
120
                    $container->get(FieldsBuilderFactory::class),
121
                    $container->get(HydratorInterface::class)
122
                );
123
            },
124
            InputTypeUtils::class => function(ContainerInterface $container) {
125
                return new InputTypeUtils(
126
                    $container->get(AnnotationReader::class),
127
                    $container->get(NamingStrategyInterface::class)
128
                );
129
            },
130
            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

130
            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...
131
                return new AnnotationReader(new DoctrineAnnotationReader());
132
            },
133
            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

133
            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...
134
                return new FactoryHydrator();
135
            },
136
            NamingStrategyInterface::class => function() {
137
                return new NamingStrategy();
138
            },
139
            CachedDocBlockFactory::class => function() {
140
                return new CachedDocBlockFactory(new ArrayCache());
141
            }
142
        ]);
143
144
        $this->mainContainer->get(TypeResolver::class)->registerSchema($this->mainContainer->get(Schema::class));
145
    }
146
147
    public function testEndToEnd()
148
    {
149
        /**
150
         * @var Schema $schema
151
         */
152
        $schema = $this->mainContainer->get(Schema::class);
153
154
        $schema->assertValid();
155
156
        $queryString = '
157
        query {
158
            getContacts {
159
                name
160
                ... on User {
161
                    email
162
                }
163
            }
164
        }
165
        ';
166
167
        $result = GraphQL::executeQuery(
168
            $schema,
169
            $queryString
170
        );
171
172
        $this->assertSame([
173
            'getContacts' => [
174
                [
175
                    'name' => 'Joe'
176
                ],
177
                [
178
                    'name' => 'Bill',
179
                    'email' => '[email protected]'
180
                ]
181
182
            ]
183
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
184
185
        // Let's redo this to test cache.
186
        $result = GraphQL::executeQuery(
187
            $schema,
188
            $queryString
189
        );
190
191
        $this->assertSame([
192
            'getContacts' => [
193
                [
194
                    'name' => 'Joe'
195
                ],
196
                [
197
                    'name' => 'Bill',
198
                    'email' => '[email protected]'
199
                ]
200
201
            ]
202
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
203
    }
204
205
    public function testEndToEndInputType()
206
    {
207
        /**
208
         * @var Schema $schema
209
         */
210
        $schema = $this->mainContainer->get(Schema::class);
211
        $queryString = '
212
        mutation {
213
          saveContact(
214
            contact: {
215
                name: "foo",
216
                birthDate: "1942-12-24 00:00:00",
217
                relations: [
218
                    {
219
                        name: "bar"
220
                        birthDate: "1942-12-24 00:00:00",
221
                    }
222
                ]
223
            }
224
          ) {
225
            name,
226
            birthDate,
227
            relations {
228
              name,
229
              birthDate
230
            }
231
          }
232
        }
233
        ';
234
235
        $result = GraphQL::executeQuery(
236
            $schema,
237
            $queryString
238
        );
239
240
        $this->assertSame([
241
            'saveContact' => [
242
                'name' => 'foo',
243
                'birthDate' => '1942-12-24T00:00:00+00:00',
244
                'relations' => [
245
                    [
246
                        'name' => 'bar',
247
                        'birthDate' => '1942-12-24T00:00:00+00:00'
248
                    ]
249
                ]
250
            ]
251
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
252
    }
253
254
    public function testEndToEndPorpaginas()
255
    {
256
        /**
257
         * @var Schema $schema
258
         */
259
        $schema = $this->mainContainer->get(Schema::class);
260
261
        $schema->assertValid();
262
263
        $queryString = '
264
        query {
265
            getContactsIterator {
266
                items(limit: 1, offset: 1) {
267
                    name
268
                    ... on User {
269
                        email
270
                    }
271
                }
272
                count
273
            }
274
        }
275
        ';
276
277
        $result = GraphQL::executeQuery(
278
            $schema,
279
            $queryString
280
        );
281
282
        $this->assertSame([
283
            'getContactsIterator' => [
284
                'items' => [
285
                    [
286
                        'name' => 'Bill',
287
                        'email' => '[email protected]'
288
                    ]
289
                ],
290
                'count' => 2
291
            ]
292
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
293
294
        // Let's redo this to test cache.
295
        $result = GraphQL::executeQuery(
296
            $schema,
297
            $queryString
298
        );
299
300
        $this->assertSame([
301
            'getContactsIterator' => [
302
                'items' => [
303
                    [
304
                        'name' => 'Bill',
305
                        'email' => '[email protected]'
306
                    ]
307
                ],
308
                'count' => 2
309
            ]
310
        ], $result->toArray(Debug::RETHROW_INTERNAL_EXCEPTIONS)['data']);
311
312
        // Let's run a query with no limit but an offset
313
        $invalidQueryString = '
314
        query {
315
            getContactsIterator {
316
                items(offset: 1) {
317
                    name
318
                    ... on User {
319
                        email
320
                    }
321
                }
322
                count
323
            }
324
        }
325
        ';
326
327
        $result = GraphQL::executeQuery(
328
            $schema,
329
            $invalidQueryString
330
        );
331
332
        $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']);
333
    }
334
}
335