Passed
Pull Request — master (#35)
by David
01:45
created

testFromSourceFieldsInterface()

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 19
c 0
b 0
f 0
nc 1
nop 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A ControllerQueryProviderTest.php$3 ➔ isAllowed() 0 3 1
1
<?php
2
3
namespace TheCodingMachine\GraphQL\Controllers;
4
5
use Doctrine\Common\Annotations\AnnotationReader;
6
use GraphQL\Type\Definition\BooleanType;
7
use GraphQL\Type\Definition\FloatType;
8
use GraphQL\Type\Definition\InputObjectType;
9
use GraphQL\Type\Definition\IntType;
10
use GraphQL\Type\Definition\ListOfType;
11
use GraphQL\Type\Definition\NonNull;
12
use GraphQL\Type\Definition\StringType;
13
use GraphQL\Type\Definition\ObjectType;
14
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestController;
15
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
16
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestType;
17
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingAnnotation;
18
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeMissingField;
19
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestTypeWithSourceFieldInterface;
20
use TheCodingMachine\GraphQL\Controllers\Registry\EmptyContainer;
21
use TheCodingMachine\GraphQL\Controllers\Registry\Registry;
22
use TheCodingMachine\GraphQL\Controllers\Security\AuthenticationServiceInterface;
23
use TheCodingMachine\GraphQL\Controllers\Security\AuthorizationServiceInterface;
24
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
25
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
26
use TheCodingMachine\GraphQL\Controllers\Annotations\Query;
27
use TheCodingMachine\GraphQL\Controllers\Types\DateTimeType;
28
29
class ControllerQueryProviderTest extends AbstractQueryProviderTest
30
{
31
    public function testQueryProvider()
32
    {
33
        $controller = new TestController();
34
35
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
36
37
        $queries = $queryProvider->getQueries();
38
39
        $this->assertCount(3, $queries);
40
        $usersQuery = $queries[0];
41
        $this->assertSame('test', $usersQuery->name);
42
43
        $this->assertCount(8, $usersQuery->args);
44
        $this->assertSame('int', $usersQuery->args[0]->name);
45
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[0]->getType());
46
        $this->assertInstanceOf(IntType::class, $usersQuery->args[0]->getType()->getWrappedType());
47
        $this->assertInstanceOf(StringType::class, $usersQuery->args[7]->getType());
48
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[1]->getType());
49
        $this->assertInstanceOf(ListOfType::class, $usersQuery->args[1]->getType()->getWrappedType());
50
        $this->assertInstanceOf(NonNull::class, $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType());
51
        $this->assertInstanceOf(InputObjectType::class, $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType()->getWrappedType());
52
        $this->assertInstanceOf(BooleanType::class, $usersQuery->args[2]->getType());
53
        $this->assertInstanceOf(FloatType::class, $usersQuery->args[3]->getType());
54
        $this->assertInstanceOf(DateTimeType::class, $usersQuery->args[4]->getType());
55
        $this->assertInstanceOf(DateTimeType::class, $usersQuery->args[5]->getType());
56
        $this->assertInstanceOf(StringType::class, $usersQuery->args[6]->getType());
57
        $this->assertSame('TestObject', $usersQuery->args[1]->getType()->getWrappedType()->getWrappedType()->getWrappedType()->name);
58
59
        $context = ['int' => 42, 'string' => 'foo', 'list' => [
60
            ['test' => 42],
61
            ['test' => 12],
62
        ],
63
            'boolean' => true,
64
            'float' => 4.2,
65
            'dateTimeImmutable' => '2017-01-01 01:01:01',
66
            'dateTime' => '2017-01-01 01:01:01'
67
        ];
68
69
        $resolve = $usersQuery->resolveFn;
70
        $result = $resolve('foo', $context);
71
72
        $this->assertInstanceOf(TestObject::class, $result);
73
        $this->assertSame('foo424212true4.22017010101010120170101010101default', $result->getTest());
74
75
        unset($context['string']); // Testing null default value
76
        $result = $resolve('foo', $context);
77
78
        $this->assertSame('424212true4.22017010101010120170101010101default', $result->getTest());
79
    }
80
81
    public function testMutations()
82
    {
83
        $controller = new TestController();
84
85
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
86
87
        $mutations = $queryProvider->getMutations();
88
89
        $this->assertCount(1, $mutations);
90
        $mutation = $mutations[0];
91
        $this->assertSame('mutation', $mutation->name);
92
93
        $resolve = $mutation->resolveFn;
94
        $result = $resolve('foo', ['testObject' => ['test' => 42]]);
95
96
        $this->assertInstanceOf(TestObject::class, $result);
97
        $this->assertEquals('42', $result->getTest());
98
    }
99
100
    public function testErrors()
101
    {
102
        $controller = new class
103
        {
104
            /**
105
             * @Query
106
             * @return string
107
             */
108
            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

108
            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...
109
            {
110
                return 'foo';
111
            }
112
        };
113
114
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
115
116
        $this->expectException(MissingTypeHintException::class);
117
        $queryProvider->getQueries();
118
    }
119
120
    public function testQueryProviderWithFixedReturnType()
121
    {
122
        $controller = new TestController();
123
124
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
125
126
        $queries = $queryProvider->getQueries();
127
128
        $this->assertCount(3, $queries);
129
        $fixedQuery = $queries[1];
130
131
        $this->assertInstanceOf(ObjectType::class, $fixedQuery->getType());
132
        $this->assertSame('Test', $fixedQuery->getType()->name);
133
    }
134
135
    public function testNameFromAnnotation()
136
    {
137
        $controller = new TestController();
138
139
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
140
141
        $queries = $queryProvider->getQueries();
142
143
        $query = $queries[2];
144
145
        $this->assertSame('nameFromAnnotation', $query->name);
146
    }
147
148
    public function testSourceField()
149
    {
150
        $controller = new TestType($this->getRegistry());
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...TestType::__construct() has too many arguments starting with $this->getRegistry(). ( Ignorable by Annotation )

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

150
        $controller = /** @scrutinizer ignore-call */ new TestType($this->getRegistry());

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...
151
152
        $queryProvider = new ControllerQueryProvider($controller, $this->getRegistry());
153
154
        $fields = $queryProvider->getFields();
155
156
        $this->assertCount(2, $fields);
157
158
        $this->assertSame('customField', $fields[0]->name);
159
        $this->assertSame('test', $fields[1]->name);
160
    }
161
162
    public function testLoggedInSourceField()
163
    {
164
        $registry = new Registry(new EmptyContainer(),
165
            new VoidAuthorizationService(),
166
            new class implements AuthenticationServiceInterface {
167
                public function isLogged(): bool
168
                {
169
                    return true;
170
                }
171
            },
172
            new AnnotationReader(),
173
            $this->getTypeMapper(),
174
            $this->getHydrator());
175
176
        $queryProvider = new ControllerQueryProvider(new TestType($this->getRegistry()), $registry);
0 ignored issues
show
Unused Code introduced by
The call to TheCodingMachine\GraphQL...TestType::__construct() has too many arguments starting with $this->getRegistry(). ( Ignorable by Annotation )

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

176
        $queryProvider = new ControllerQueryProvider(/** @scrutinizer ignore-call */ new TestType($this->getRegistry()), $registry);

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...
177
        $fields = $queryProvider->getFields();
178
        $this->assertCount(3, $fields);
179
180
        $this->assertSame('testBool', $fields[2]->name);
181
182
    }
183
184
    public function testRightInSourceField()
185
    {
186
        $registry = new Registry(new EmptyContainer(),
187
            new class implements AuthorizationServiceInterface {
188
                public function isAllowed(string $right): bool
189
                {
190
                    return true;
191
                }
192
            },
193
            new VoidAuthenticationService(),
194
            new AnnotationReader(),
195
            $this->getTypeMapper(),
196
            $this->getHydrator());
197
198
        $queryProvider = new ControllerQueryProvider(new TestType(), $registry);
199
        $fields = $queryProvider->getFields();
200
        $this->assertCount(3, $fields);
201
202
        $this->assertSame('testRight', $fields[2]->name);
203
204
    }
205
206
    public function testMissingTypeAnnotation()
207
    {
208
        $queryProvider = new ControllerQueryProvider(new TestTypeMissingAnnotation(), $this->getRegistry());
209
210
        $this->expectException(MissingAnnotationException::class);
211
        $queryProvider->getFields();
212
    }
213
214
    public function testSourceFieldDoesNotExists()
215
    {
216
        $queryProvider = new ControllerQueryProvider(new TestTypeMissingField(), $this->getRegistry());
217
218
        $this->expectException(FieldNotFoundException::class);
219
        $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::getNotExists()\", \"TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject::isNotExists()");
220
        $queryProvider->getFields();
221
    }
222
223
    public function testFromSourceFieldsInterface()
224
    {
225
        $registry = new Registry(new EmptyContainer(),
226
            new class implements AuthorizationServiceInterface {
227
                public function isAllowed(string $right): bool
228
                {
229
                    return true;
230
                }
231
            },
232
            new VoidAuthenticationService(),
233
            new AnnotationReader(),
234
            $this->getTypeMapper(),
235
            $this->getHydrator());
236
237
        $queryProvider = new ControllerQueryProvider(new TestTypeWithSourceFieldInterface(), $registry);
238
        $fields = $queryProvider->getFields();
239
        $this->assertCount(1, $fields);
240
241
        $this->assertSame('test', $fields[0]->name);
242
243
    }
244
245
}
246