Completed
Push — master ( 5b603d...f09253 )
by David
12s
created

getInputTestObjectType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
4
namespace TheCodingMachine\GraphQL\Controllers;
5
6
use Doctrine\Common\Annotations\Annotation;
7
use Doctrine\Common\Annotations\AnnotationReader as DoctrineAnnotationReader;
8
use GraphQL\Type\Definition\InputObjectType;
9
use GraphQL\Type\Definition\InputType;
10
use GraphQL\Type\Definition\ObjectType;
11
use GraphQL\Type\Definition\OutputType;
12
use GraphQL\Type\Definition\StringType;
13
use GraphQL\Type\Definition\Type;
14
use Mouf\Picotainer\Picotainer;
15
use PHPUnit\Framework\TestCase;
16
use Psr\Container\ContainerInterface;
17
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject;
18
use TheCodingMachine\GraphQL\Controllers\Fixtures\TestObject2;
19
use TheCodingMachine\GraphQL\Controllers\Mappers\CannotMapTypeException;
20
use TheCodingMachine\GraphQL\Controllers\Mappers\RecursiveTypeMapper;
21
use TheCodingMachine\GraphQL\Controllers\Mappers\RecursiveTypeMapperInterface;
22
use TheCodingMachine\GraphQL\Controllers\Mappers\TypeMapperInterface;
23
use TheCodingMachine\GraphQL\Controllers\Containers\EmptyContainer;
24
use TheCodingMachine\GraphQL\Controllers\Containers\BasicAutoWiringContainer;
25
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthenticationService;
26
use TheCodingMachine\GraphQL\Controllers\Security\VoidAuthorizationService;
27
28
abstract class AbstractQueryProviderTest extends TestCase
29
{
30
    private $testObjectType;
31
    private $testObjectType2;
32
    private $inputTestObjectType;
33
    private $typeMapper;
34
    private $hydrator;
35
    private $registry;
36
    private $typeGenerator;
37
    private $controllerQueryProviderFactory;
38
    private $annotationReader;
39
40
    protected function getTestObjectType()
41
    {
42
        if ($this->testObjectType === null) {
43
            $this->testObjectType = new ObjectType([
44
                'name'    => 'TestObject',
45
                'fields'  => [
46
                    'test'   => Type::string(),
47
                ],
48
            ]);
49
        }
50
        return $this->testObjectType;
51
    }
52
53
    protected function getTestObjectType2()
54
    {
55
        if ($this->testObjectType2 === null) {
56
            $this->testObjectType2 = new ObjectType([
57
                'name'    => 'TestObject2',
58
                'fields'  => [
59
                    'test'   => Type::string(),
60
                ],
61
            ]);
62
        }
63
        return $this->testObjectType2;
64
    }
65
66
    protected function getInputTestObjectType()
67
    {
68
        if ($this->inputTestObjectType === null) {
69
            $this->inputTestObjectType = new InputObjectType([
70
                'name'    => 'TestObject',
71
                'fields'  => [
72
                    'test'   => Type::string(),
73
                ],
74
            ]);
75
        }
76
        return $this->inputTestObjectType;
77
    }
78
79
    protected function getTypeMapper()
80
    {
81
        if ($this->typeMapper === null) {
82
            $this->typeMapper = new RecursiveTypeMapper(new class($this->getTestObjectType(), $this->getTestObjectType2(), $this->getInputTestObjectType()) implements TypeMapperInterface {
83
                /**
84
                 * @var ObjectType
85
                 */
86
                private $testObjectType;
87
                /**
88
                 * @var ObjectType
89
                 */
90
                private $testObjectType2;
91
                /**
92
                 * @var InputObjectType
93
                 */
94
                private $inputTestObjectType;
95
96
                public function __construct(ObjectType $testObjectType, ObjectType $testObjectType2, InputObjectType $inputTestObjectType)
97
                {
98
                    $this->testObjectType = $testObjectType;
99
                    $this->testObjectType2 = $testObjectType2;
100
                    $this->inputTestObjectType = $inputTestObjectType;
101
                }
102
103
                public function mapClassToType(string $className, RecursiveTypeMapperInterface $recursiveTypeMapper): ObjectType
104
                {
105
                    if ($className === TestObject::class) {
106
                        return $this->testObjectType;
107
                    } elseif ($className === TestObject2::class) {
108
                        return $this->testObjectType2;
109
                    } else {
110
                        throw CannotMapTypeException::createForType($className);
111
                    }
112
                }
113
114
                public function mapClassToInputType(string $className): InputType
115
                {
116
                    if ($className === TestObject::class) {
117
                        return $this->inputTestObjectType;
118
                    } else {
119
                        throw CannotMapTypeException::createForInputType($className);
120
                    }
121
                }
122
123
                public function canMapClassToType(string $className): bool
124
                {
125
                    return $className === TestObject::class || $className === TestObject2::class;
126
                }
127
128
                /**
129
                 * Returns true if this type mapper can map the $className FQCN to a GraphQL input type.
130
                 *
131
                 * @param string $className
132
                 * @return bool
133
                 */
134
                public function canMapClassToInputType(string $className): bool
135
                {
136
                    return $className === TestObject::class || $className === TestObject2::class;
137
                }
138
139
                /**
140
                 * Returns the list of classes that have matching input GraphQL types.
141
                 *
142
                 * @return string[]
143
                 */
144
                public function getSupportedClasses(): array
145
                {
146
                    return [TestObject::class, TestObject2::class];
147
                }
148
            });
149
        }
150
        return $this->typeMapper;
151
    }
152
153
    protected function getHydrator()
154
    {
155
        if ($this->hydrator === null) {
156
            $this->hydrator = new class implements HydratorInterface {
157
                public function hydrate(array $data, InputType $type)
158
                {
159
                    return new TestObject($data['test']);
160
                }
161
            };
162
        }
163
        return $this->hydrator;
164
    }
165
166
    protected function getRegistry()
167
    {
168
        if ($this->registry === null) {
169
            $this->registry = $this->buildAutoWiringContainer(new Picotainer([
170
                'customOutput' => function() {
171
                    return new StringType();
172
                }
173
            ]));
174
        }
175
        return $this->registry;
176
    }
177
178
    protected function buildAutoWiringContainer(ContainerInterface $container): BasicAutoWiringContainer
179
    {
180
        return new BasicAutoWiringContainer($container);
181
    }
182
183
    protected function getAnnotationReader(): AnnotationReader
184
    {
185
        if ($this->annotationReader === null) {
186
            $this->annotationReader = new AnnotationReader(new DoctrineAnnotationReader());
187
        }
188
        return $this->annotationReader;
189
    }
190
191
    protected function buildControllerQueryProvider($controller)
192
    {
193
        return new ControllerQueryProvider(
194
            $controller,
195
            $this->getAnnotationReader(),
196
            $this->getTypeMapper(),
197
            $this->getHydrator(),
198
            new VoidAuthenticationService(),
199
            new VoidAuthorizationService(),
200
            $this->getRegistry()
201
        );
202
    }
203
204
    protected function getTypeGenerator(): TypeGenerator
205
    {
206
        if ($this->typeGenerator === null) {
207
            $this->typeGenerator = new TypeGenerator($this->getAnnotationReader(), $this->getControllerQueryProviderFactory());
208
        }
209
        return $this->typeGenerator;
210
    }
211
212
    protected function getControllerQueryProviderFactory(): ControllerQueryProviderFactory
213
    {
214
        if ($this->controllerQueryProviderFactory === null) {
215
            $this->controllerQueryProviderFactory = new ControllerQueryProviderFactory($this->getAnnotationReader(),
216
                $this->getHydrator(),
217
                new VoidAuthenticationService(),
218
                new VoidAuthorizationService(),
219
                $this->getRegistry());
220
        }
221
        return $this->controllerQueryProviderFactory;
222
    }
223
}
224