• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 10884379752

16 Sep 2024 01:01PM UTC coverage: 7.281% (-0.4%) from 7.672%
10884379752

push

github

soyuka
Merge 3.4

0 of 100 new or added lines in 7 files covered. (0.0%)

5332 existing lines in 181 files now uncovered.

11994 of 164725 relevant lines covered (7.28%)

9.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/GraphQl/Tests/Serializer/SerializerContextBuilderTest.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\GraphQl\Tests\Serializer;
15

16
use ApiPlatform\GraphQl\Serializer\SerializerContextBuilder;
17
use ApiPlatform\GraphQl\Tests\Fixtures\Serializer\NameConverter\CustomConverter;
18
use ApiPlatform\Metadata\GraphQl\Mutation;
19
use ApiPlatform\Metadata\GraphQl\Operation;
20
use ApiPlatform\Metadata\GraphQl\Query;
21
use ApiPlatform\Metadata\GraphQl\Subscription;
22
use GraphQL\Type\Definition\ResolveInfo;
23
use PHPUnit\Framework\TestCase;
24
use Prophecy\Argument;
25
use Prophecy\PhpUnit\ProphecyTrait;
26
use Symfony\Component\Serializer\NameConverter\AdvancedNameConverterInterface;
27

28
/**
29
 * @author Alan Poulain <contact@alanpoulain.eu>
30
 */
31
class SerializerContextBuilderTest extends TestCase
32
{
33
    use ProphecyTrait;
34

35
    private SerializerContextBuilder $serializerContextBuilder;
36

37
    /**
38
     * {@inheritdoc}
39
     */
40
    protected function setUp(): void
41
    {
42
        $this->serializerContextBuilder = $this->buildSerializerContextBuilder();
×
43
    }
44

45
    private function buildSerializerContextBuilder(?AdvancedNameConverterInterface $advancedNameConverter = null): SerializerContextBuilder
46
    {
47
        return new SerializerContextBuilder($advancedNameConverter ?? new CustomConverter());
×
48
    }
49

50
    private function buildOperationFromContext(bool $isMutation, bool $isSubscription, array $expectedContext, bool $isNormalization = true, ?string $resourceClass = null): Operation
51
    {
52
        $operation = !$isMutation && !$isSubscription ? new Query() : new Mutation();
×
53
        if ($isSubscription) {
×
54
            $operation = new Subscription();
×
55
        }
56

57
        $operation = $operation->withShortName('shortName');
×
58
        if (isset($expectedContext['operation_name'])) {
×
59
            $operation = $operation->withName($expectedContext['operation_name']);
×
60
        }
61

62
        if ($resourceClass) {
×
63
            if (isset($expectedContext['groups'])) {
×
64
                if ($isNormalization) {
×
65
                    $operation = $operation->withNormalizationContext(['groups' => $expectedContext['groups']]);
×
66
                } else {
67
                    $operation = $operation->withDenormalizationContext(['groups' => $expectedContext['groups']]);
×
68
                }
69
            }
70

71
            if (isset($expectedContext['input'])) {
×
72
                $operation = $operation->withInput($expectedContext['input']);
×
73
            }
74

75
            if (isset($expectedContext['input'])) {
×
76
                $operation = $operation->withOutput($expectedContext['output']);
×
77
            }
78
        }
79

80
        \assert($operation instanceof Operation);
×
81

82
        return $operation;
×
83
    }
84

85
    #[\PHPUnit\Framework\Attributes\DataProvider('createNormalizationContextProvider')]
86
    public function testCreateNormalizationContext(?string $resourceClass, string $operationName, array $fields, bool $isMutation, bool $isSubscription, bool $noInfo, array $expectedContext, ?callable $advancedNameConverter = null, ?string $expectedExceptionClass = null, ?string $expectedExceptionMessage = null): void
87
    {
88
        $resolverContext = [];
×
89

90
        $operation = $this->buildOperationFromContext($isMutation, $isSubscription, $expectedContext, true, $resourceClass);
×
91
        if ($noInfo) {
×
92
            $resolverContext['fields'] = $fields;
×
93
        } else {
94
            $resolveInfoProphecy = $this->prophesize(ResolveInfo::class);
×
95
            $resolveInfoProphecy->getFieldSelection(\PHP_INT_MAX)->willReturn($fields);
×
96
            $resolverContext['info'] = $resolveInfoProphecy->reveal();
×
97
        }
98

99
        if ($expectedExceptionClass) {
×
100
            $this->expectException($expectedExceptionClass);
×
101
            $this->expectExceptionMessage($expectedExceptionMessage);
×
102
        }
103

104
        $serializerContextBuilder = $this->serializerContextBuilder;
×
105
        if ($advancedNameConverter) {
×
106
            $serializerContextBuilder = $this->buildSerializerContextBuilder($advancedNameConverter($this));
×
107
        }
108

109
        $context = $serializerContextBuilder->create($resourceClass, $operation, $resolverContext, true);
×
110

111
        unset($context['operation']);
×
112
        $this->assertEquals($expectedContext, $context);
×
113
    }
114

115
    public static function createNormalizationContextProvider(): iterable
116
    {
117
        $advancedNameConverterFactory = function (self $that): AdvancedNameConverterInterface {
×
118
            $advancedNameConverterProphecy = $that->prophesize(AdvancedNameConverterInterface::class);
×
119
            $advancedNameConverterProphecy->denormalize('field', 'myResource', null, Argument::type('array'))->willReturn('denormalizedField');
×
120

121
            return $advancedNameConverterProphecy->reveal();
×
122
        };
×
123

124
        yield 'nominal' => [
×
125
            $resourceClass = 'myResource',
×
126
            $operationName = 'item_query',
×
127
            ['_id' => 3, 'field' => 'foo'],
×
128
            false,
×
129
            false,
×
130
            false,
×
131
            [
×
132
                'groups' => ['normalization_group'],
×
133
                'resource_class' => $resourceClass,
×
134
                'operation_name' => $operationName,
×
135
                'graphql_operation_name' => $operationName,
×
136
                'input' => ['class' => 'inputClass'],
×
137
                'output' => ['class' => 'outputClass'],
×
138
                'attributes' => [
×
139
                    'id' => 3,
×
140
                    'field' => 'foo',
×
141
                ],
×
NEW
142
                'exclude_from_cache_key' => [
×
NEW
143
                    'root_operation',
×
NEW
144
                    'operation',
×
NEW
145
                    'object',
×
NEW
146
                    'data',
×
NEW
147
                    'property_metadata',
×
NEW
148
                    'circular_reference_limit_counters',
×
NEW
149
                    'debug_trace_id',
×
NEW
150
                ],
×
151
            ],
×
152
        ];
×
153
        yield 'nominal with advanced name converter' => [
×
154
            $resourceClass = 'myResource',
×
155
            $operationName = 'item_query',
×
156
            ['_id' => 3, 'field' => 'foo'],
×
157
            false,
×
158
            false,
×
159
            false,
×
160
            [
×
161
                'groups' => ['normalization_group'],
×
162
                'resource_class' => $resourceClass,
×
163
                'operation_name' => $operationName,
×
164
                'graphql_operation_name' => $operationName,
×
165
                'input' => ['class' => 'inputClass'],
×
166
                'output' => ['class' => 'outputClass'],
×
167
                'attributes' => [
×
168
                    'id' => 3,
×
169
                    'denormalizedField' => 'foo',
×
170
                ],
×
NEW
171
                'exclude_from_cache_key' => [
×
NEW
172
                    'root_operation',
×
NEW
173
                    'operation',
×
NEW
174
                    'object',
×
NEW
175
                    'data',
×
NEW
176
                    'property_metadata',
×
NEW
177
                    'circular_reference_limit_counters',
×
NEW
178
                    'debug_trace_id',
×
NEW
179
                ],
×
180
            ],
×
181
            $advancedNameConverterFactory,
×
182
        ];
×
183
        yield 'nominal collection' => [
×
184
            $resourceClass = 'myResource',
×
185
            $operationName = 'collection_query',
×
186
            ['edges' => ['node' => ['nodeField' => 'baz']]],
×
187
            false,
×
188
            false,
×
189
            false,
×
190
            [
×
191
                'groups' => ['normalization_group'],
×
192
                'resource_class' => $resourceClass,
×
193
                'operation_name' => $operationName,
×
194
                'graphql_operation_name' => $operationName,
×
195
                'input' => ['class' => 'inputClass'],
×
196
                'output' => ['class' => 'outputClass'],
×
197
                'attributes' => [
×
198
                    'nodeField' => 'baz',
×
199
                ],
×
NEW
200
                'exclude_from_cache_key' => [
×
NEW
201
                    'root_operation',
×
NEW
202
                    'operation',
×
NEW
203
                    'object',
×
NEW
204
                    'data',
×
NEW
205
                    'property_metadata',
×
NEW
206
                    'circular_reference_limit_counters',
×
NEW
207
                    'debug_trace_id',
×
NEW
208
                ],
×
209
            ],
×
210
        ];
×
211
        yield 'no resource class' => [
×
212
            $resourceClass = null,
×
213
            $operationName = 'item_query',
×
214
            ['related' => ['_id' => 9]],
×
215
            false,
×
216
            false,
×
217
            false,
×
218
            [
×
219
                'resource_class' => $resourceClass,
×
220
                'operation_name' => $operationName,
×
221
                'graphql_operation_name' => $operationName,
×
222
                'attributes' => [
×
223
                    'related' => ['id' => 9],
×
224
                ],
×
NEW
225
                'exclude_from_cache_key' => [
×
NEW
226
                    'root_operation',
×
NEW
227
                    'operation',
×
NEW
228
                    'object',
×
NEW
229
                    'data',
×
NEW
230
                    'property_metadata',
×
NEW
231
                    'circular_reference_limit_counters',
×
NEW
232
                    'debug_trace_id',
×
NEW
233
                ],
×
234
            ],
×
235
        ];
×
236
        yield 'mutation' => [
×
237
            $resourceClass = 'myResource',
×
238
            $operationName = 'create',
×
239
            ['shortName' => ['_id' => 7, 'related' => ['field' => 'bar']]],
×
240
            true,
×
241
            false,
×
242
            false,
×
243
            [
×
244
                'groups' => ['normalization_group'],
×
245
                'resource_class' => $resourceClass,
×
246
                'operation_name' => $operationName,
×
247
                'graphql_operation_name' => $operationName,
×
248
                'input' => ['class' => 'inputClass'],
×
249
                'output' => ['class' => 'outputClass'],
×
250
                'attributes' => [
×
251
                    'id' => 7,
×
252
                    'related' => ['field' => 'bar'],
×
253
                ],
×
NEW
254
                'exclude_from_cache_key' => [
×
NEW
255
                    'root_operation',
×
NEW
256
                    'operation',
×
NEW
257
                    'object',
×
NEW
258
                    'data',
×
NEW
259
                    'property_metadata',
×
NEW
260
                    'circular_reference_limit_counters',
×
NEW
261
                    'debug_trace_id',
×
NEW
262
                ],
×
263
            ],
×
264
        ];
×
265
        yield 'subscription (using fields in context)' => [
×
266
            $resourceClass = 'myResource',
×
267
            $operationName = 'update',
×
268
            ['shortName' => ['_id' => 7, 'related' => ['field' => 'bar']]],
×
269
            false,
×
270
            true,
×
271
            true,
×
272
            [
×
273
                'groups' => ['normalization_group'],
×
274
                'resource_class' => $resourceClass,
×
275
                'operation_name' => $operationName,
×
276
                'graphql_operation_name' => $operationName,
×
277
                'no_resolver_data' => true,
×
278
                'input' => ['class' => 'inputClass'],
×
279
                'output' => ['class' => 'outputClass'],
×
280
                'attributes' => [
×
281
                    'id' => 7,
×
282
                    'related' => ['field' => 'bar'],
×
283
                ],
×
NEW
284
                'exclude_from_cache_key' => [
×
NEW
285
                    'root_operation',
×
NEW
286
                    'operation',
×
NEW
287
                    'object',
×
NEW
288
                    'data',
×
NEW
289
                    'property_metadata',
×
NEW
290
                    'circular_reference_limit_counters',
×
NEW
291
                    'debug_trace_id',
×
NEW
292
                ],
×
293
            ],
×
294
        ];
×
295
    }
296

297
    #[\PHPUnit\Framework\Attributes\DataProvider('createDenormalizationContextProvider')]
298
    public function testCreateDenormalizationContext(?string $resourceClass, string $operationName, array $expectedContext): void
299
    {
300
        $operation = $this->buildOperationFromContext(true, false, $expectedContext, false, $resourceClass);
×
301

302
        $context = $this->serializerContextBuilder->create($resourceClass, $operation, [], false);
×
303

304
        unset($context['operation']);
×
305
        $this->assertEquals($expectedContext, $context);
×
306
    }
307

308
    public static function createDenormalizationContextProvider(): array
309
    {
310
        return [
×
311
            'nominal' => [
×
312
                $resourceClass = 'myResource',
×
313
                $operationName = 'item_query',
×
314
                [
×
315
                    'groups' => ['denormalization_group'],
×
316
                    'resource_class' => $resourceClass,
×
317
                    'operation_name' => $operationName,
×
318
                    'graphql_operation_name' => $operationName,
×
319
                    'input' => ['class' => 'inputClass'],
×
320
                    'output' => ['class' => 'outputClass'],
×
NEW
321
                    'exclude_from_cache_key' => [
×
NEW
322
                        'root_operation',
×
NEW
323
                        'operation',
×
NEW
324
                        'object',
×
NEW
325
                        'data',
×
NEW
326
                        'property_metadata',
×
NEW
327
                        'circular_reference_limit_counters',
×
NEW
328
                        'debug_trace_id',
×
NEW
329
                    ],
×
330
                ],
×
331
            ],
×
332
            'no resource class' => [
×
333
                $resourceClass = null,
×
334
                $operationName = 'item_query',
×
335
                [
×
336
                    'resource_class' => $resourceClass,
×
337
                    'operation_name' => $operationName,
×
338
                    'graphql_operation_name' => $operationName,
×
NEW
339
                    'exclude_from_cache_key' => [
×
NEW
340
                        'root_operation',
×
NEW
341
                        'operation',
×
NEW
342
                        'object',
×
NEW
343
                        'data',
×
NEW
344
                        'property_metadata',
×
NEW
345
                        'circular_reference_limit_counters',
×
NEW
346
                        'debug_trace_id',
×
NEW
347
                    ],
×
348
                ],
×
349
            ],
×
350
        ];
×
351
    }
352
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc