Skip to content

Commit 26d9bcc

Browse files
committed
Introduce TypesInterface to be able to mock the lib in tests
Fixes #56
1 parent bc0dc76 commit 26d9bcc

File tree

3 files changed

+121
-81
lines changed

3 files changed

+121
-81
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ $schema = new Schema([
114114

115115
## Usage
116116

117-
The public API is limited to the public methods on `Types` and the annotations.
118-
So that's the constructor and:
117+
The public API is limited to the public methods on `TypesInterface`, `Types`'s constructor, and the annotations.
118+
119+
Here is a quick overview of `TypesInterface`:
119120

120121
- `$types->get()` to get custom types
121122
- `$types->getOutput()` to get an `ObjectType` to be used in queries

src/Types.php

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
*
3737
* This is the entry point for the library.
3838
*/
39-
final class Types
39+
final class Types implements TypesInterface
4040
{
4141
/**
4242
* @var null|ContainerInterface
@@ -124,23 +124,11 @@ public function __construct(EntityManager $entityManager, ?ContainerInterface $c
124124
$this->initializeInternalTypes();
125125
}
126126

127-
/**
128-
* Returns whether a type exists for the given key.
129-
*/
130127
public function has(string $key): bool
131128
{
132129
return $this->customTypes && $this->customTypes->has($key) || array_key_exists($key, $this->types);
133130
}
134131

135-
/**
136-
* Always return the same instance of `Type` for the given key.
137-
*
138-
* It will first look for the type in the custom types container, and then
139-
* use automatically generated types. This allow for custom types to override
140-
* automatic ones.
141-
*
142-
* @param string $key the key the type was registered with (eg: "Post", "PostInput", "PostPartialInput" or "PostStatus")
143-
*/
144132
public function get(string $key): Type
145133
{
146134
if ($this->customTypes && $this->customTypes->has($key)) {
@@ -173,14 +161,6 @@ private function getViaFactory(string $className, string $typeName, AbstractType
173161
return $this->types[$typeName];
174162
}
175163

176-
/**
177-
* Returns an output type for the given entity.
178-
*
179-
* All entity getter methods will be exposed, unless specified otherwise
180-
* with annotations.
181-
*
182-
* @param string $className the class name of an entity (`Post::class`)
183-
*/
184164
public function getOutput(string $className): ObjectType
185165
{
186166
/** @var ObjectType $type */
@@ -189,16 +169,6 @@ public function getOutput(string $className): ObjectType
189169
return $type;
190170
}
191171

192-
/**
193-
* Returns an input type for the given entity.
194-
*
195-
* This would typically be used in mutations to create new entities.
196-
*
197-
* All entity setter methods will be exposed, unless specified otherwise
198-
* with annotations.
199-
*
200-
* @param string $className the class name of an entity (`Post::class`)
201-
*/
202172
public function getInput(string $className): InputObjectType
203173
{
204174
/** @var InputObjectType $type */
@@ -207,18 +177,6 @@ public function getInput(string $className): InputObjectType
207177
return $type;
208178
}
209179

210-
/**
211-
* Returns a partial input type for the given entity.
212-
*
213-
* This would typically be used in mutations to update existing entities.
214-
*
215-
* All entity setter methods will be exposed, unless specified otherwise
216-
* with annotations. But they will all be marked as optional and without
217-
* default values. So this allow the API client to specify only some fields
218-
* to be updated, and not necessarily all of them at once.
219-
*
220-
* @param string $className the class name of an entity (`Post::class`)
221-
*/
222180
public function getPartialInput(string $className): InputObjectType
223181
{
224182
/** @var InputObjectType $type */
@@ -227,13 +185,6 @@ public function getPartialInput(string $className): InputObjectType
227185
return $type;
228186
}
229187

230-
/**
231-
* Returns a filter input type for the given entity.
232-
*
233-
* This would typically be used to filter queries.
234-
*
235-
* @param string $className the class name of an entity (`Post::class`)
236-
*/
237188
public function getFilter(string $className): InputObjectType
238189
{
239190
/** @var InputObjectType $type */
@@ -242,13 +193,6 @@ public function getFilter(string $className): InputObjectType
242193
return $type;
243194
}
244195

245-
/**
246-
* Returns a sorting input type for the given entity.
247-
*
248-
* This would typically be used to sort queries.
249-
*
250-
* @param string $className the class name of an entity (`Post::class`)
251-
*/
252196
public function getSorting(string $className): ListOfType
253197
{
254198
/** @var InputObjectType $type */
@@ -302,17 +246,6 @@ public function getFilterGroupCondition(string $className): InputObjectType
302246
return $type;
303247
}
304248

305-
/**
306-
* Returns an special ID type for the given entity.
307-
*
308-
* This is mostly useful for internal usage when a getter has an entity
309-
* as parameter. This type will automatically load the entity from DB, so
310-
* the resolve functions can use a real instance of entity instead of an ID.
311-
* But this can also be used to build your own schema and thus avoid
312-
* manually fetching objects from database for simple cases.
313-
*
314-
* @param string $className the class name of an entity (`Post::class`)
315-
*/
316249
public function getId(string $className): EntityIDType
317250
{
318251
/** @var EntityIDType $type */
@@ -400,17 +333,6 @@ private function throwIfNotEntity(string $className): void
400333
}
401334
}
402335

403-
/**
404-
* Create and return a query builder that is filtered and sorted for the given entity.
405-
*
406-
* Typical usage would be to call this method in your query resolver with the filter and sorting arguments directly
407-
* coming from GraphQL.
408-
*
409-
* You may apply further pagination according to your needs before executing the query.
410-
*
411-
* Filter and sorting arguments are assumed to be valid and complete as the validation should have happened when
412-
* parsing the GraphQL query.
413-
*/
414336
public function createFilteredQueryBuilder(string $className, array $filter, array $sorting): QueryBuilder
415337
{
416338
return $this->filteredQueryBuilderFactory->create($className, $filter, $sorting);

src/TypesInterface.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace GraphQL\Doctrine;
6+
7+
use Doctrine\ORM\QueryBuilder;
8+
use GraphQL\Doctrine\Definition\EntityIDType;
9+
use GraphQL\Type\Definition\InputObjectType;
10+
use GraphQL\Type\Definition\ListOfType;
11+
use GraphQL\Type\Definition\ObjectType;
12+
use GraphQL\Type\Definition\Type;
13+
14+
/**
15+
* Registry of types to manage all GraphQL types.
16+
*
17+
* This interface purpose is to be able to mock implementations in tests. It is not meant
18+
* to create alternative implementations for production use.
19+
*/
20+
interface TypesInterface
21+
{
22+
/**
23+
* Returns whether a type exists for the given key.
24+
*/
25+
public function has(string $key): bool;
26+
27+
/**
28+
* Always return the same instance of `Type` for the given key.
29+
*
30+
* It will first look for the type in the custom types container, and then
31+
* use automatically generated types. This allow for custom types to override
32+
* automatic ones.
33+
*
34+
* @param string $key the key the type was registered with (eg: "Post", "PostInput", "PostPartialInput" or "PostStatus")
35+
*/
36+
public function get(string $key): Type;
37+
38+
/**
39+
* Returns an output type for the given entity.
40+
*
41+
* All entity getter methods will be exposed, unless specified otherwise
42+
* with annotations.
43+
*
44+
* @param string $className the class name of an entity (`Post::class`)
45+
*/
46+
public function getOutput(string $className): ObjectType;
47+
48+
/**
49+
* Returns an input type for the given entity.
50+
*
51+
* This would typically be used in mutations to create new entities.
52+
*
53+
* All entity setter methods will be exposed, unless specified otherwise
54+
* with annotations.
55+
*
56+
* @param string $className the class name of an entity (`Post::class`)
57+
*/
58+
public function getInput(string $className): InputObjectType;
59+
60+
/**
61+
* Returns a partial input type for the given entity.
62+
*
63+
* This would typically be used in mutations to update existing entities.
64+
*
65+
* All entity setter methods will be exposed, unless specified otherwise
66+
* with annotations. But they will all be marked as optional and without
67+
* default values. So this allow the API client to specify only some fields
68+
* to be updated, and not necessarily all of them at once.
69+
*
70+
* @param string $className the class name of an entity (`Post::class`)
71+
*/
72+
public function getPartialInput(string $className): InputObjectType;
73+
74+
/**
75+
* Returns a filter input type for the given entity.
76+
*
77+
* This would typically be used to filter queries.
78+
*
79+
* @param string $className the class name of an entity (`Post::class`)
80+
*/
81+
public function getFilter(string $className): InputObjectType;
82+
83+
/**
84+
* Returns a sorting input type for the given entity.
85+
*
86+
* This would typically be used to sort queries.
87+
*
88+
* @param string $className the class name of an entity (`Post::class`)
89+
*/
90+
public function getSorting(string $className): ListOfType;
91+
92+
/**
93+
* Returns an special ID type for the given entity.
94+
*
95+
* This is mostly useful for internal usage when a getter has an entity
96+
* as parameter. This type will automatically load the entity from DB, so
97+
* the resolve functions can use a real instance of entity instead of an ID.
98+
* But this can also be used to build your own schema and thus avoid
99+
* manually fetching objects from database for simple cases.
100+
*
101+
* @param string $className the class name of an entity (`Post::class`)
102+
*/
103+
public function getId(string $className): EntityIDType;
104+
105+
/**
106+
* Create and return a query builder that is filtered and sorted for the given entity.
107+
*
108+
* Typical usage would be to call this method in your query resolver with the filter and sorting arguments directly
109+
* coming from GraphQL.
110+
*
111+
* You may apply further pagination according to your needs before executing the query.
112+
*
113+
* Filter and sorting arguments are assumed to be valid and complete as the validation should have happened when
114+
* parsing the GraphQL query.
115+
*/
116+
public function createFilteredQueryBuilder(string $className, array $filter, array $sorting): QueryBuilder;
117+
}

0 commit comments

Comments
 (0)