Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 208
0.00% covered (danger)
0.00%
0 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
GraphqlTestHelper
0.00% covered (danger)
0.00%
0 / 208
0.00% covered (danger)
0.00%
0 / 13
240
0.00% covered (danger)
0.00%
0 / 1
 createEmptyCall
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 createSchemaCall
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 createTypeInspectionCall
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 createIntrospectionCall
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 createEntityList
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 createExpectedListResponse
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
6
 createQueryCall
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
2
 createFileQuery
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
2
 createCreationCall
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
2
 createRemovalCall
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 createModificationCall
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
2
 createResourceMethodCall
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
2
 createFileuploadCall
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace Apie\IntegrationTests\Graphql;
3
4use Apie\Core\BoundedContext\BoundedContextId;
5use Apie\Core\FileStorage\ImageFile;
6use Apie\Core\FileStorage\StoredFile;
7use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\PrimitiveOnlyIdentifier;
8use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\UploadedFileIdentifier;
9use Apie\IntegrationTests\Apie\TypeDemo\Identifiers\UserIdentifier;
10use Apie\IntegrationTests\Apie\TypeDemo\Resources\PrimitiveOnly;
11use Apie\IntegrationTests\Apie\TypeDemo\Resources\UploadedFile;
12use Apie\IntegrationTests\Apie\TypeDemo\Resources\User;
13use Apie\IntegrationTests\IntegrationTestHelper;
14
15class GraphqlTestHelper extends IntegrationTestHelper
16{
17    public function createEmptyCall(): GraphqlProvider
18    {
19        return new GraphqlProvider(
20            new BoundedContextId('types'),
21            [
22                'query' => '{ apie_version }'
23            ],
24            [
25                "data" => [
26                    "apie_version" => \Apie\Core\ApieLib::VERSION,
27                ],
28            ]
29        );
30    }
31
32    public function createSchemaCall(): GraphqlProvider
33    {
34        return new SchemaGraphqlProvider(
35            new BoundedContextId('types'),
36            [
37                'query' => '{
38  __schema {
39    queryType {
40      fields {
41        name
42        description
43      }
44    }
45  }
46}'
47            ],
48            [
49            ]
50        );
51    }
52
53    public function createTypeInspectionCall(): GraphqlProvider
54    {
55        return new SchemaGraphqlProvider(
56            new BoundedContextId('types'),
57            [
58                'query' => 'query IntrospectionQuery {
59  __schema {
60    queryType {
61      name
62    }
63    mutationType {
64      name
65    }
66    subscriptionType {
67      name
68    }
69    types {
70      ...FullType
71    }
72    directives {
73      name
74      description
75      locations
76      args {
77        ...InputValue
78      }
79    }
80  }
81}
82
83fragment FullType on __Type {
84  kind
85  name
86  description
87  fields(includeDeprecated: true) {
88    name
89    description
90    args {
91      ...InputValue
92    }
93    type {
94      ...TypeRef
95    }
96    isDeprecated
97    deprecationReason
98  }
99  inputFields {
100    ...InputValue
101  }
102  interfaces {
103    ...TypeRef
104  }
105  enumValues(includeDeprecated: true) {
106    name
107    description
108    isDeprecated
109    deprecationReason
110  }
111  possibleTypes {
112    ...TypeRef
113  }
114}
115
116fragment InputValue on __InputValue {
117  name
118  description
119  type {
120    ...TypeRef
121  }
122  defaultValue
123}
124
125fragment TypeRef on __Type {
126  kind
127  name
128  ofType {
129    kind
130    name
131    ofType {
132      kind
133      name
134      ofType {
135        kind
136        name
137        ofType {
138          kind
139          name
140          ofType {
141            kind
142            name
143            ofType {
144              kind
145              name
146              ofType {
147                kind
148                name
149              }
150            }
151          }
152        }
153      }
154    }
155  }
156}
157'
158            ],
159            []
160        );
161    }
162
163    public function createIntrospectionCall(): GraphqlProvider
164    {
165        return new SchemaGraphqlProvider(
166            new BoundedContextId('types'),
167            [
168                'query' => '{
169  __type(name: "findPrimitiveOnly") {
170    name
171    description
172    fields {
173      name
174      description
175    }
176  }
177}'
178            ],
179            [
180            ]
181        );
182    }
183
184    /**
185     * @return array<int, PrimitiveOnly>
186     */
187    private function createEntityList(int $count): array
188    {
189        $entities = [];
190        for ($i = 0; $i < $count; $i++) {
191            $entity = new PrimitiveOnly(PrimitiveOnlyIdentifier::generateFromInteger($i));
192            $entity->stringField = 'String ' . $i;
193            $entity->integerField = $i * 10;
194            $entity->floatingPoint = $i * 1.5;
195            $entity->booleanField = $i % 2 === 0;
196            $entities[] = $entity;
197        }
198        return $entities;
199    }
200
201    /**
202     * @return array<int, array<string, mixed>>
203     */
204    private function createExpectedListResponse(int $start, int $end): array
205    {
206        $list = [];
207        for ($i = $start; $i <= $end; $i++) {
208            $list[] = [
209                'id' => (string) PrimitiveOnlyIdentifier::generateFromInteger($i),
210                'stringField' => 'String ' . $i,
211                'integerField' => $i * 10,
212                'floatingPoint' => $i * 1.5,
213                'booleanField' => $i % 2 === 0,
214            ];
215        }
216        return $list;
217    }
218
219    public function createQueryCall(): GraphqlProvider
220    {
221        $entities = $this->createEntityList(30);
222        return new GraphqlProvider(
223            new BoundedContextId('types'),
224            [
225                  'query' => '{ findPrimitiveOnly(filter: { orderBy: "+id" }) { totalCount, list { id, stringField, integerField, floatingPoint, booleanField } } }'
226              ],
227            [
228                'data' => [
229                    'findPrimitiveOnly' => [
230                        'list' => $this->createExpectedListResponse(0, 19),
231                        'totalCount' => 30,
232                    ]
233                ]
234              ],
235            $entities
236        );
237    }
238
239    public function createFileQuery(): GraphqlProvider
240    {
241        $path = __DIR__ . '/../../fixtures/apie-logo.svg';
242        $entities = [
243          new UploadedFile(
244              UploadedFileIdentifier::fromNative('821c5aca-2853-4f7a-b3bc-045a81798e24'),
245              StoredFile::createFromLocalFile($path),
246              ImageFile::createFromLocalFile($path),
247          )
248        ];
249        return new GraphqlProvider(
250            new BoundedContextId('types'),
251            [
252                  'query' => '{ findUploadedFile(id: "821c5aca-2853-4f7a-b3bc-045a81798e24") { list { id, imageFile, file } } }'
253              ],
254            [
255                'data' => [
256                    'findUploadedFile' => [
257                        'list' => [
258                          [
259                            'id' => '821c5aca-2853-4f7a-b3bc-045a81798e24',
260                            'imageFile' => '/types/UploadedFile/821c5aca-2853-4f7a-b3bc-045a81798e24/download/imageFile',
261                            'file' => '/types/UploadedFile/821c5aca-2853-4f7a-b3bc-045a81798e24/download/file',
262                          ]
263                        ]
264                    ]
265                ]
266            ],
267            $entities
268        );
269    }
270
271    public function createCreationCall(): GraphqlProvider
272    {
273        return new GraphqlProvider(
274            new BoundedContextId('types'),
275            [
276              'query' => <<<GQL
277mutation CreatePrimitiveOnly(\$id: String!, \$booleanField: Boolean!) {
278  createPrimitiveOnly(input: {
279    id: \$id,
280    booleanField: \$booleanField
281  }) { id, stringField, integerField, booleanField }
282}
283GQL,
284                'variables' => [
285                    'id' => '821c5aca-2853-4f7a-b3bc-045a81798e24',
286                    'booleanField' => false,
287                ],
288            ],
289            [
290                'data' => [
291                    'createPrimitiveOnly' => [
292                        'id' => '821c5aca-2853-4f7a-b3bc-045a81798e24',
293                        'stringField' => null,
294                        'integerField' => null,
295                        'booleanField' => false,
296                    ]
297                ]
298            ],
299            []
300        );
301    }
302
303    public function createRemovalCall(): GraphqlProvider
304    {
305        $entities = $this->createEntityList(1);
306        return new GraphqlProvider(
307            new BoundedContextId('types'),
308            [
309              'query' => <<<GQL
310mutation RemovePrimitiveOnly(\$id: String!) {
311  removePrimitiveOnly(id: \$id)
312}
313GQL,
314                'variables' => [
315                    'id' => PrimitiveOnlyIdentifier::generateFromInteger(0)->toNative(),
316                ],
317            ],
318            [
319                'data' => [
320                    'removePrimitiveOnly' => true
321                ]
322              ],
323            $entities
324        );
325    }
326
327    public function createModificationCall(): GraphqlProvider
328    {
329        $entities = $this->createEntityList(1);
330        return new GraphqlProvider(
331            new BoundedContextId('types'),
332            [
333              'query' => <<<GQL
334mutation ModifyPrimitiveOnly(\$id: String!, \$booleanField: Boolean!) {
335  modifyPrimitiveOnly(id: \$id, input: { integerField: 12, booleanField: \$booleanField }) { id, stringField, integerField, booleanField }
336}
337GQL,
338                'variables' => [
339                    'id' => PrimitiveOnlyIdentifier::generateFromInteger(0)->toNative(),
340                    'booleanField' => false,
341                ],
342            ],
343            [
344                'data' => [
345                    'modifyPrimitiveOnly' => [
346                        'id' => PrimitiveOnlyIdentifier::generateFromInteger(0)->toNative(),
347                        'stringField' => 'String 0',
348                        'integerField' => 12,
349                        'booleanField' => false,
350                    ]
351                ]
352              ],
353            $entities
354        );
355    }
356
357    public function createResourceMethodCall(): GraphqlProvider
358    {
359        $entities = [new User(UserIdentifier::fromNative('test@example.com'))];
360        return new GraphqlProvider(
361            new BoundedContextId('types'),
362            [
363              'query' => <<<GQL
364mutation RunUserBlock(\$id: String!,\$blockedReason: String!) {
365  runUserBlock(id: \$id, input: { blockedReason: \$blockedReason }) { id, blocked, blockedReason }
366}
367GQL,
368                'variables' => [
369                    'id' => 'test@example.com',
370                    'blockedReason' => 'Test reason',
371                ],
372            ],
373            [
374                'data' => [
375                    'runUserBlock' => [
376                        'id' => 'test@example.com',
377                        'blocked' => true,
378                        'blockedReason' => 'Test reason',
379                    ]
380                ]
381              ],
382            $entities
383        );
384    }
385
386    public function createFileuploadCall(): GraphqlProvider
387    {
388        return new GraphqlWithFileUpload(
389            new BoundedContextId('types'),
390            [
391              'query' => <<<GQL
392mutation CreateUploadedFile(\$id: String!, \$file: UploadedFileInterface_create!) {
393  createUploadedFile(input: {
394    id: \$id,
395    file: \$file
396  }) { id, file, stream, imageFile }
397}
398GQL,
399                'variables' => [
400                    'id' => '821c5aca-2853-4f7a-b3bc-045a81798e24',
401                ],
402            ],
403            [
404                'data' => [
405                    'createUploadedFile' => [
406                        'id' => '821c5aca-2853-4f7a-b3bc-045a81798e24',
407                        'imageFile' => null,
408                        'stream' => '/types/UploadedFile/821c5aca-2853-4f7a-b3bc-045a81798e24/download/stream',
409                        'file' => '/types/UploadedFile/821c5aca-2853-4f7a-b3bc-045a81798e24/download/file',
410                    ]
411                ]
412              ],
413            [],
414            [
415                'variables.file' => StoredFile::createFromString('test', 'test.txt'),
416              ]
417        );
418    }
419
420}