anonymous//tests/FieldsBuilderTest.php$2   A
last analyzed

Complexity

Total Complexity 1

Size/Duplication

Total Lines 4
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace TheCodingMachine\GraphQL\Controllers;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, TheCodingMachine\GraphQL...ollers\AnnotationReader. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
6
use GraphQL\Type\Definition\BooleanType;
7
use GraphQL\Type\Definition\FloatType;
8
use GraphQL\Type\Definition\IDType;
9
use GraphQL\Type\Definition\InputObjectType;
10
use GraphQL\Type\Definition\IntType;
11
use GraphQL\Type\Definition\ListOfType;
12
use GraphQL\Type\Definition\NonNull;
13
use GraphQL\Type\Definition\StringType;
14
use GraphQL\Type\Definition\ObjectType;
15
use GraphQL\Type\Definition\UnionType;
16
use Symfony\Component\Cache\Simple\ArrayCache;
17
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestController;
18
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerNoReturnType;
19
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithArrayParam;
20
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithArrayReturnType;
21
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithFailWith;
22
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithInputType;
0 ignored issues
show
Bug introduced by
The type TheCodingMachine\GraphQL...ControllerWithInputType was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithInvalidInputType;
24
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithInvalidReturnType;
25
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithIterableParam;
26
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithIterableReturnType;
27
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
28
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestType;
29
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeId;
30
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingAnnotation;
31
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingField;
32
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingReturnType;
33
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeWithFailWith;
34
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeWithSourceFieldInterface;
35
use TheCodingMachine\GraphQL\Controllers\Containers\EmptyContainer;
36
use TheCodingMachine\GraphQL\Controllers\Containers\BasicAutoWiringContainer;
37
use TheCodingMachine\GraphQL\Controllers\Mappers\CannotMapTypeException;
38
use TheCodingMachine\GraphQL\Controllers\Reflection\CachedDocBlockFactory;
39
use TheCodingMachine\GraphQL\Controllers\Security\AuthenticationServiceInterface;
40
use TheCodingMachine\GraphQL\Controllers\Security\AuthorizationServiceInterface;
41
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
42
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
43
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
44
use TheCodingMachine\GraphQL\Controllers\Types\DateTimeType;
45
use function var_dump;
46
47
class FieldsBuilderTest extends AbstractQueryProviderTest
48
{
49
    public function testQueryProvider()
50
    {
51
        $controller = new TestController();
52
53
        $queryProvider = $this->buildFieldsBuilder();
54
55
        $queries = $queryProvider->getQueries($controller);
56
57
        $this->assertCount(6, $queries);
58
        $usersQuery = $queries[0];
59
        $this->assertSame('test', $usersQuery->name);
60
61
        $this->assertCount(9, $usersQuery->args);
62
        $this->assertSame('int', $usersQuery->args[0]->name);
63
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[0]->getType());
64
        $this->assertInstanceOf(IntType::class, $usersQuery->args[0]->getType()->getWrappedType());
65
        $this->assertInstanceOf(StringType::class, $usersQuery->args[7]->getType());
66
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[1]->getType());
67
        $this->assertInstanceOf(ListOfType::class, $usersQuery->args[1]->getType()->getWrappedType());
68
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType());
69
        $this->assertInstanceOf(InputObjectType::class, $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType()->getWrappedType());
70
        $this->assertInstanceOf(BooleanType::class, $usersQuery->args[2]->getType());
71
        $this->assertInstanceOf(FloatType::class, $usersQuery->args[3]->getType());
72
        $this->assertInstanceOf(DateTimeType::class, $usersQuery->args[4]->getType());
73
        $this->assertInstanceOf(DateTimeType::class, $usersQuery->args[5]->getType());
74
        $this->assertInstanceOf(StringType::class, $usersQuery->args[6]->getType());
75
        $this->assertInstanceOf(IDType::class, $usersQuery->args[8]->getType());
76
        $this->assertSame('TestObjectInput', $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType()->getWrappedType()->name);
77
78
        $context = ['int' => 42, 'string' => 'foo', 'list' => [
79
            ['test' => 42],
80
            ['test' => 12],
81
        ],
82
            'boolean' => true,
83
            'float' => 4.2,
84
            'dateTimeImmutable' => '2017-01-01 01:01:01',
85
            'dateTime' => '2017-01-01 01:01:01',
86
            'id' => 42
87
        ];
88
89
        $resolve = $usersQuery->resolveFn;
90
        $result = $resolve('foo', $context);
91
92
        $this->assertInstanceOf(TestObject::class, $result);
93
        $this->assertSame('foo424212true4.22017010101010120170101010101default42', $result->getTest());
94
95
        unset($context['string']); // Testing null default value
96
        $result = $resolve('foo', $context);
97
98
        $this->assertSame('424212true4.22017010101010120170101010101default42', $result->getTest());
99
    }
100
101
    public function testMutations()
102
    {
103
        $controller = new TestController();
104
105
        $queryProvider = $this->buildFieldsBuilder();
106
107
        $mutations = $queryProvider->getMutations($controller);
108
109
        $this->assertCount(1, $mutations);
110
        $mutation = $mutations[0];
111
        $this->assertSame('mutation', $mutation->name);
112
113
        $resolve = $mutation->resolveFn;
114
        $result = $resolve('foo', ['testObject' => ['test' => 42]]);
115
116
        $this->assertInstanceOf(TestObject::class, $result);
117
        $this->assertEquals('42', $result->getTest());
118
    }
119
120
    public function testErrors()
121
    {
122
        $controller = new class
123
        {
124
            /**
125
             * @Query
126
             * @return string
127
             */
128
            public function test($noTypeHint): string
0 ignored issues
show
Unused Code introduced by
The parameter $noTypeHint 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

128
            public function test(/** @scrutinizer ignore-unused */ $noTypeHint): string

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...
129
            {
130
                return 'foo';
131
            }
132
        };
133
134
        $queryProvider = $this->buildFieldsBuilder();
135
136
        $this->expectException(MissingTypeHintException::class);
137
        $queryProvider->getQueries($controller);
138
    }
139
140
    public function testQueryProviderWithFixedReturnType()
141
    {
142
        $controller = new TestController();
143
144
        $queryProvider = $this->buildFieldsBuilder();
145
146
        $queries = $queryProvider->getQueries($controller);
147
148
        $this->assertCount(6, $queries);
149
        $fixedQuery = $queries[1];
150
151
        $this->assertInstanceOf(IDType::class, $fixedQuery->getType());
152
    }
153
154
    public function testNameFromAnnotation()
155
    {
156
        $controller = new TestController();
157
158
        $queryProvider = $this->buildFieldsBuilder();
159
160
        $queries = $queryProvider->getQueries($controller);
161
162
        $query = $queries[2];
163
164
        $this->assertSame('nameFromAnnotation', $query->name);
165
    }
166
167
    public function testSourceField()
168
    {
169
        $controller = new TestType();
170
171
        $queryProvider = $this->buildFieldsBuilder();
172
173
        $fields = $queryProvider->getFields($controller, true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

173
        /** @scrutinizer ignore-call */ 
174
        $fields = $queryProvider->getFields($controller, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
174
175
        $this->assertCount(3, $fields);
176
177
        $this->assertSame('customField', $fields['customField']->name);
178
        $this->assertSame('test', $fields['test']->name);
179
        // Test the "self" name resolution
180
        $this->assertSame('sibling', $fields['sibling']->name);
181
        $this->assertInstanceOf(NonNull::class, $fields['sibling']->getType());
182
        $this->assertInstanceOf(ObjectType::class, $fields['sibling']->getType()->getWrappedType());
183
        $this->assertSame('TestObject', $fields['sibling']->getType()->getWrappedType()->name);
184
    }
185
186
    public function testLoggedInSourceField()
187
    {
188
        $queryProvider = new FieldsBuilder(
189
            $this->getAnnotationReader(),
190
            $this->getTypeMapper(),
191
            $this->getHydrator(),
192
            new class implements AuthenticationServiceInterface {
193
                public function isLogged(): bool
194
                {
195
                    return true;
196
                }
197
            },
198
            new VoidAuthorizationService(),
199
            $this->getTypeResolver(),
200
            new CachedDocBlockFactory(new ArrayCache()),
201
            new NamingStrategy()
202
        );
203
204
        $fields = $queryProvider->getFields(new TestType(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

204
        /** @scrutinizer ignore-call */ 
205
        $fields = $queryProvider->getFields(new TestType(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
205
        $this->assertCount(4, $fields);
206
207
        $this->assertSame('testBool', $fields['testBool']->name);
208
209
    }
210
211
    public function testRightInSourceField()
212
    {
213
        $queryProvider = new FieldsBuilder(
214
            $this->getAnnotationReader(),
215
            $this->getTypeMapper(),
216
            $this->getHydrator(),
217
            new VoidAuthenticationService(),
218
            new class implements AuthorizationServiceInterface {
219
                public function isAllowed(string $right): bool
220
                {
221
                    return true;
222
                }
223
            },
224
            $this->getTypeResolver(),
225
            new CachedDocBlockFactory(new ArrayCache()),
226
            new NamingStrategy()
227
        );
228
229
        $fields = $queryProvider->getFields(new TestType(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

229
        /** @scrutinizer ignore-call */ 
230
        $fields = $queryProvider->getFields(new TestType(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
230
        $this->assertCount(4, $fields);
231
232
        $this->assertSame('testRight', $fields['testRight']->name);
233
234
    }
235
236
    public function testMissingTypeAnnotation()
237
    {
238
        $queryProvider = $this->buildFieldsBuilder();
239
240
        $this->expectException(MissingAnnotationException::class);
241
        $queryProvider->getFields(new TestTypeMissingAnnotation(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

241
        $queryProvider->/** @scrutinizer ignore-call */ 
242
                        getFields(new TestTypeMissingAnnotation(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
242
    }
243
244
    public function testSourceFieldDoesNotExists()
245
    {
246
        $queryProvider = $this->buildFieldsBuilder();
247
248
        $this->expectException(FieldNotFoundException::class);
249
        $this->expectExceptionMessage("There is an issue with a @SourceField annotation in class \"TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingField\": Could not find a getter or a isser for field \"notExists\". Looked for: \"TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject::notExists()\", \"TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject::getNotExists()\", \"TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject::isNotExists()");
250
        $queryProvider->getFields(new TestTypeMissingField(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

250
        $queryProvider->/** @scrutinizer ignore-call */ 
251
                        getFields(new TestTypeMissingField(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
251
    }
252
253
    public function testSourceFieldHasMissingReturnType()
254
    {
255
        $queryProvider = $this->buildFieldsBuilder();
256
257
        $this->expectException(TypeMappingException::class);
258
        $this->expectExceptionMessage("Return type in TheCodingMachine\\GraphQL\\Controllers\\Fixtures\\TestObjectMissingReturnType::getTest is missing a type-hint (or type-hinted to \"mixed\"). Please provide a better type-hint.");
259
        $queryProvider->getFields(new TestTypeMissingReturnType(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

259
        $queryProvider->/** @scrutinizer ignore-call */ 
260
                        getFields(new TestTypeMissingReturnType(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
260
    }
261
262
    public function testSourceFieldIsId()
263
    {
264
        $queryProvider = $this->buildFieldsBuilder();
265
        $fields = $queryProvider->getFields(new TestTypeId(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

265
        /** @scrutinizer ignore-call */ 
266
        $fields = $queryProvider->getFields(new TestTypeId(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
266
        $this->assertCount(1, $fields);
267
268
        $this->assertSame('test', $fields['test']->name);
269
        $this->assertInstanceOf(NonNull::class, $fields['test']->getType());
270
        $this->assertInstanceOf(IDType::class, $fields['test']->getType()->getWrappedType());
271
    }
272
273
    public function testFromSourceFieldsInterface()
274
    {
275
        $queryProvider = new FieldsBuilder(
276
            $this->getAnnotationReader(),
277
            $this->getTypeMapper(),
278
            $this->getHydrator(),
279
            new VoidAuthenticationService(),
280
            new VoidAuthorizationService(),
281
            $this->getTypeResolver(),
282
            new CachedDocBlockFactory(new ArrayCache()),
283
            new NamingStrategy()
284
        );
285
        $fields = $queryProvider->getFields(new TestTypeWithSourceFieldInterface(), true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

285
        /** @scrutinizer ignore-call */ 
286
        $fields = $queryProvider->getFields(new TestTypeWithSourceFieldInterface(), true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
286
        $this->assertCount(1, $fields);
287
288
        $this->assertSame('test', $fields['test']->name);
289
290
    }
291
292
    public function testQueryProviderWithIterableClass()
293
    {
294
        $controller = new TestController();
295
296
        $queryProvider = $this->buildFieldsBuilder();
297
298
        $queries = $queryProvider->getQueries($controller);
299
300
        $this->assertCount(6, $queries);
301
        $iterableQuery = $queries[3];
302
303
        $this->assertInstanceOf(NonNull::class, $iterableQuery->getType());
304
        $this->assertInstanceOf(ListOfType::class, $iterableQuery->getType()->getWrappedType());
305
        $this->assertInstanceOf(NonNull::class, $iterableQuery->getType()->getWrappedType()->getWrappedType());
306
        $this->assertInstanceOf(ObjectType::class, $iterableQuery->getType()->getWrappedType()->getWrappedType()->getWrappedType());
307
        $this->assertSame('TestObject', $iterableQuery->getType()->getWrappedType()->getWrappedType()->getWrappedType()->name);
308
    }
309
310
    public function testQueryProviderWithIterable()
311
    {
312
        $queryProvider = $this->buildFieldsBuilder();
313
314
        $queries = $queryProvider->getQueries(new TestController());
315
316
        $this->assertCount(6, $queries);
317
        $iterableQuery = $queries[4];
318
319
        $this->assertInstanceOf(NonNull::class, $iterableQuery->getType());
320
        $this->assertInstanceOf(ListOfType::class, $iterableQuery->getType()->getWrappedType());
321
        $this->assertInstanceOf(NonNull::class, $iterableQuery->getType()->getWrappedType()->getWrappedType());
322
        $this->assertInstanceOf(ObjectType::class, $iterableQuery->getType()->getWrappedType()->getWrappedType()->getWrappedType());
323
        $this->assertSame('TestObject', $iterableQuery->getType()->getWrappedType()->getWrappedType()->getWrappedType()->name);
324
    }
325
326
    public function testNoReturnTypeError()
327
    {
328
        $queryProvider = $this->buildFieldsBuilder();
329
        $this->expectException(TypeMappingException::class);
330
        $queryProvider->getQueries(new TestControllerNoReturnType());
331
    }
332
333
    public function testQueryProviderWithUnion()
334
    {
335
        $controller = new TestController();
336
337
        $queryProvider = $this->buildFieldsBuilder();
338
339
        $queries = $queryProvider->getQueries($controller);
340
341
        $this->assertCount(6, $queries);
342
        $unionQuery = $queries[5];
343
344
        $this->assertInstanceOf(NonNull::class, $unionQuery->getType());
345
        $this->assertInstanceOf(UnionType::class, $unionQuery->getType()->getWrappedType());
346
        $this->assertInstanceOf(ObjectType::class, $unionQuery->getType()->getWrappedType()->getTypes()[0]);
347
        $this->assertSame('TestObject', $unionQuery->getType()->getWrappedType()->getTypes()[0]->name);
348
        $this->assertInstanceOf(ObjectType::class, $unionQuery->getType()->getWrappedType()->getTypes()[1]);
349
        $this->assertSame('TestObject2', $unionQuery->getType()->getWrappedType()->getTypes()[1]->name);
350
    }
351
352
    public function testQueryProviderWithInvalidInputType()
353
    {
354
        $controller = new TestControllerWithInvalidInputType();
355
356
        $queryProvider = $this->buildFieldsBuilder();
357
358
        $this->expectException(CannotMapTypeException::class);
359
        $this->expectExceptionMessage('For parameter $foo, in TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithInvalidInputType::test, cannot map class "Exception" to a known GraphQL input type. Check your TypeMapper configuration.');
360
        $queryProvider->getQueries($controller);
361
    }
362
363
    public function testQueryProviderWithInvalidReturnType()
364
    {
365
        $controller = new TestControllerWithInvalidReturnType();
366
367
        $queryProvider = $this->buildFieldsBuilder();
368
369
        $this->expectException(CannotMapTypeException::class);
370
        $this->expectExceptionMessage('For return type of TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithInvalidReturnType::test, cannot map class "Exception" to a known GraphQL type. Check your TypeMapper configuration.');
371
        $queryProvider->getQueries($controller);
372
    }
373
374
    public function testQueryProviderWithIterableReturnType()
375
    {
376
        $controller = new TestControllerWithIterableReturnType();
377
378
        $queryProvider = $this->buildFieldsBuilder();
379
380
        $this->expectException(TypeMappingException::class);
381
        $this->expectExceptionMessage('Return type in TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithIterableReturnType::test is type-hinted to "\ArrayObject", which is iterable. Please provide an additional @param in the PHPDoc block to further specify the type. For instance: @return \ArrayObject|User[]');
382
        $queryProvider->getQueries($controller);
383
    }
384
385
    public function testQueryProviderWithArrayReturnType()
386
    {
387
        $controller = new TestControllerWithArrayReturnType();
388
389
        $queryProvider = $this->buildFieldsBuilder();
390
391
        $this->expectException(TypeMappingException::class);
392
        $this->expectExceptionMessage('Return type in TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithArrayReturnType::test is type-hinted to array. Please provide an additional @return in the PHPDoc block to further specify the type of the array. For instance: @return string[]');
393
        $queryProvider->getQueries($controller);
394
    }
395
396
    public function testQueryProviderWithArrayParams()
397
    {
398
        $controller = new TestControllerWithArrayParam();
399
400
        $queryProvider = $this->buildFieldsBuilder();
401
402
        $this->expectException(TypeMappingException::class);
403
        $this->expectExceptionMessage('Parameter $params in TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithArrayParam::test is type-hinted to array. Please provide an additional @param in the PHPDoc block to further specify the type of the array. For instance: @param string[] $params.');
404
        $queryProvider->getQueries($controller);
405
    }
406
407
    public function testQueryProviderWithIterableParams()
408
    {
409
        $controller = new TestControllerWithIterableParam();
410
411
        $queryProvider = $this->buildFieldsBuilder();
412
413
        $this->expectException(TypeMappingException::class);
414
        $this->expectExceptionMessage('Parameter $params in TheCodingMachine\GraphQL\Controllers\Fixtures\TestControllerWithIterableParam::test is type-hinted to "\ArrayObject", which is iterable. Please provide an additional @param in the PHPDoc block to further specify the type. For instance: @param \ArrayObject|User[] $params.');
415
        $queryProvider->getQueries($controller);
416
    }
417
418
    public function testFailWith()
419
    {
420
        $controller = new TestControllerWithFailWith();
421
422
        $queryProvider = $this->buildFieldsBuilder();
423
424
        $queries = $queryProvider->getQueries($controller);
425
426
        $this->assertCount(1, $queries);
427
        $query = $queries[0];
428
        $this->assertSame('testFailWith', $query->name);
429
430
        $resolve = $query->resolveFn;
431
        $result = $resolve('foo', []);
432
433
        $this->assertNull($result);
434
435
        $this->assertInstanceOf(ObjectType::class, $query->getType());
436
    }
437
438
    public function testSourceFieldWithFailWith()
439
    {
440
        $controller = new TestTypeWithFailWith();
441
442
        $queryProvider = $this->buildFieldsBuilder();
443
444
        $fields = $queryProvider->getFields($controller, true);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...ldsBuilder::getFields() has too many arguments starting with true. ( Ignorable by Annotation )

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

444
        /** @scrutinizer ignore-call */ 
445
        $fields = $queryProvider->getFields($controller, true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
445
446
        $this->assertCount(1, $fields);
447
448
        $this->assertSame('test', $fields['test']->name);
449
        $this->assertInstanceOf(StringType::class, $fields['test']->getType());
450
451
452
        $resolve = $fields['test']->resolveFn;
453
        $result = $resolve('foo', []);
454
455
        $this->assertNull($result);
456
457
        $this->assertInstanceOf(StringType::class, $fields['test']->getType());
458
    }
459
}
460