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

api-platform / core / 10315659289

09 Aug 2024 07:49AM UTC coverage: 7.841% (-0.006%) from 7.847%
10315659289

push

github

soyuka
style: cs fixes

70 of 529 new or added lines in 176 files covered. (13.23%)

160 existing lines in 58 files now uncovered.

12688 of 161818 relevant lines covered (7.84%)

26.86 hits per line

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

0.0
/src/Hydra/Tests/Serializer/CollectionFiltersNormalizerTest.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\Hydra\Tests\Serializer;
15

16
use ApiPlatform\Doctrine\Orm\Filter\FilterInterface;
17
use ApiPlatform\Hydra\Serializer\CollectionFiltersNormalizer;
18
use ApiPlatform\Hydra\Serializer\CollectionNormalizer;
19
use ApiPlatform\Hydra\Tests\Fixtures\Dummy;
20
use ApiPlatform\Hydra\Tests\Fixtures\Foo;
21
use ApiPlatform\Hydra\Tests\Fixtures\NotAResource;
22
use ApiPlatform\Metadata\ApiResource;
23
use ApiPlatform\Metadata\Exception\InvalidArgumentException;
24
use ApiPlatform\Metadata\GetCollection;
25
use ApiPlatform\Metadata\Operations;
26
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
27
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
28
use ApiPlatform\Metadata\ResourceClassResolverInterface;
29
use PHPUnit\Framework\TestCase;
30
use Prophecy\Argument;
31
use Prophecy\PhpUnit\ProphecyTrait;
32
use Psr\Container\ContainerInterface;
33
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
34
use Symfony\Component\Serializer\Serializer;
35

36
/**
37
 * @author Kévin Dunglas <dunglas@gmail.com>
38
 */
39
class CollectionFiltersNormalizerTest extends TestCase
40
{
41
    use ProphecyTrait;
42

43
    public function testSupportsNormalization(): void
44
    {
45
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
46
        $decoratedProphecy->supportsNormalization('foo', 'abc', Argument::type('array'))->willReturn(true)->shouldBeCalled();
×
47

48
        $normalizer = new CollectionFiltersNormalizer(
×
49
            $decoratedProphecy->reveal(),
×
50
            $this->prophesize(ResourceMetadataCollectionFactoryInterface::class)->reveal(),
×
51
            $this->prophesize(ResourceClassResolverInterface::class)->reveal(),
×
52
            $this->prophesize(ContainerInterface::class)->reveal(),
×
53
        );
×
54

55
        $this->assertTrue($normalizer->supportsNormalization('foo', 'abc'));
×
56
    }
57

58
    public function testNormalizeNonResourceCollection(): void
59
    {
60
        $notAResourceA = new NotAResource('A', 'buzz');
×
61
        $notAResourceB = new NotAResource('B', 'bzzt');
×
62

63
        $data = [$notAResourceA, $notAResourceB];
×
64

65
        $normalizedNotAResourceA = [
×
66
            'foo' => 'A',
×
67
            'bar' => 'buzz',
×
68
        ];
×
69

70
        $normalizedNotAResourceB = [
×
71
            'foo' => 'B',
×
72
            'bar' => 'bzzt',
×
73
        ];
×
74

75
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
76
        $decoratedProphecy->normalize($data, CollectionNormalizer::FORMAT, Argument::any())->willReturn([
×
77
            $normalizedNotAResourceA,
×
78
            $normalizedNotAResourceB,
×
79
        ]);
×
80

81
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
82

83
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
84
        $resourceClassResolverProphecy->getResourceClass($data, null)->willThrow(InvalidArgumentException::class);
×
85

86
        $filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
×
87

88
        $normalizer = new CollectionFiltersNormalizer($decoratedProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), $resourceClassResolverProphecy->reveal(), $filterLocatorProphecy->reveal());
×
89

90
        $actual = $normalizer->normalize($data, CollectionNormalizer::FORMAT, [
×
91
        ]);
×
92

93
        $this->assertEquals([
×
94
            $normalizedNotAResourceA,
×
95
            $normalizedNotAResourceB,
×
96
        ], $actual);
×
97
    }
98

99
    public function testNormalizeSubLevelResourceCollection(): void
100
    {
101
        $fooOne = new Foo();
×
102
        $fooOne->id = 1;
×
103
        $fooOne->bar = 'baz';
×
104

105
        $fooThree = new Foo();
×
106
        $fooThree->id = 3;
×
107
        $fooThree->bar = 'bzz';
×
108

109
        $data = [$fooOne, $fooThree];
×
110

111
        $normalizedFooOne = [
×
112
            '@id' => '/foos/1',
×
113
            '@type' => 'Foo',
×
114
            'bar' => 'baz',
×
115
        ];
×
116

117
        $normalizedFooThree = [
×
118
            '@id' => '/foos/3',
×
119
            '@type' => 'Foo',
×
120
            'bar' => 'bzz',
×
121
        ];
×
122

123
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
124
        $decoratedProphecy->normalize($data, CollectionNormalizer::FORMAT, Argument::allOf(
×
125
            Argument::withEntry('resource_class', Foo::class),
×
126
            Argument::withEntry('api_sub_level', true)
×
127
        ))->willReturn([
×
128
            $normalizedFooOne,
×
129
            $normalizedFooThree,
×
130
        ]);
×
131

132
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
133

134
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
135

136
        $filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
×
137

138
        $normalizer = new CollectionFiltersNormalizer($decoratedProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), $resourceClassResolverProphecy->reveal(), $filterLocatorProphecy->reveal());
×
139

140
        $actual = $normalizer->normalize($data, CollectionNormalizer::FORMAT, [
×
141
            'operation_name' => 'get',
×
142
            'resource_class' => Foo::class,
×
143
            'api_sub_level' => true,
×
144
        ]);
×
145

146
        $this->assertEquals([
×
147
            $normalizedFooOne,
×
148
            $normalizedFooThree,
×
149
        ], $actual);
×
150
    }
151

152
    public function testNormalizeSubLevelNonResourceCollection(): void
153
    {
154
        $notAResourceA = new NotAResource('A', 'buzz');
×
155
        $notAResourceB = new NotAResource('B', 'bzzt');
×
156

157
        $data = [$notAResourceA, $notAResourceB];
×
158

159
        $normalizedNotAResourceA = [
×
160
            'foo' => 'A',
×
161
            'bar' => 'buzz',
×
162
        ];
×
163

164
        $normalizedNotAResourceB = [
×
165
            'foo' => 'B',
×
166
            'bar' => 'bzzt',
×
167
        ];
×
168

169
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
170
        $decoratedProphecy->normalize($data, CollectionNormalizer::FORMAT, Argument::any())->willReturn([
×
171
            $normalizedNotAResourceA,
×
172
            $normalizedNotAResourceB,
×
173
        ]);
×
174

175
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
176

177
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
178
        $resourceClassResolverProphecy->getResourceClass($data, null)->willThrow(InvalidArgumentException::class);
×
179

180
        $filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
×
181

182
        $normalizer = new CollectionFiltersNormalizer($decoratedProphecy->reveal(), $resourceMetadataFactoryProphecy->reveal(), $resourceClassResolverProphecy->reveal(), $filterLocatorProphecy->reveal());
×
183

184
        $actual = $normalizer->normalize($data, CollectionNormalizer::FORMAT, [
×
185
            'api_sub_level' => true,
×
186
        ]);
×
187

188
        $this->assertEquals([
×
189
            $normalizedNotAResourceA,
×
190
            $normalizedNotAResourceB,
×
191
        ], $actual);
×
192
    }
193

194
    public function testDoNothingIfNoFilter(): void
195
    {
196
        $dummy = new Dummy();
×
197

198
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
199
        $decoratedProphecy->normalize($dummy, CollectionNormalizer::FORMAT, [
×
200
            'operation_name' => 'get',
×
201
            'resource_class' => Dummy::class,
×
202
        ])->willReturn(['name' => 'foo']);
×
203

204
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
205
        $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
×
206
            (new ApiResource(Dummy::class))
×
207
                ->withShortName('Dummy')
×
208
                ->withOperations(new Operations([
×
209
                    'get' => (new GetCollection())->withShortName('Dummy'),
×
210
                ])),
×
211
        ]));
×
212

213
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
214
        $resourceClassResolverProphecy->getResourceClass($dummy, Dummy::class)->willReturn(Dummy::class);
×
215

216
        $normalizer = new CollectionFiltersNormalizer(
×
217
            $decoratedProphecy->reveal(),
×
218
            $resourceMetadataFactoryProphecy->reveal(),
×
219
            $resourceClassResolverProphecy->reveal(),
×
220
            $this->prophesize(ContainerInterface::class)->reveal()
×
221
        );
×
222

223
        $this->assertEquals(['name' => 'foo'], $normalizer->normalize($dummy, CollectionNormalizer::FORMAT, [
×
224
            'operation_name' => 'get',
×
225
            'resource_class' => Dummy::class,
×
226
        ]));
×
227
    }
228

229
    public function testDoNothingIfNoRequestUri(): void
230
    {
231
        $dummy = new Dummy();
×
232

233
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
234
        $decoratedProphecy->normalize($dummy, CollectionNormalizer::FORMAT, [
×
235
            'resource_class' => Dummy::class,
×
236
            'operation_name' => 'get',
×
237
        ])->willReturn(['name' => 'foo']);
×
238

239
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
240
        $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
×
241
            (new ApiResource(Dummy::class))
×
242
                ->withShortName('Dummy')
×
243
                ->withOperations(new Operations([
×
244
                    'get' => (new GetCollection())->withShortName('Dummy')->withFilters(['foo']),
×
245
                ])),
×
246
        ]));
×
247

248
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
249
        $resourceClassResolverProphecy->getResourceClass($dummy, Dummy::class)->willReturn(Dummy::class);
×
250

251
        $filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
×
252
        $filterLocatorProphecy->has('foo')->willReturn(false);
×
253

254
        $normalizer = new CollectionFiltersNormalizer(
×
255
            $decoratedProphecy->reveal(),
×
256
            $resourceMetadataFactoryProphecy->reveal(),
×
257
            $resourceClassResolverProphecy->reveal(),
×
258
            $filterLocatorProphecy->reveal()
×
259
        );
×
260

261
        $this->assertEquals(['name' => 'foo'], $normalizer->normalize($dummy, CollectionNormalizer::FORMAT, [
×
262
            'resource_class' => Dummy::class,
×
263
            'operation_name' => 'get',
×
264
        ]));
×
265
    }
266

267
    public function testNormalize(): void
268
    {
269
        $filterProphecy = $this->prophesize(FilterInterface::class);
×
270
        $filterProphecy->getDescription(Dummy::class)->willReturn(['a' => ['property' => 'name', 'required' => true]])->shouldBeCalled();
×
271

272
        $filterLocatorProphecy = $this->prophesize(ContainerInterface::class);
×
273
        $filterLocatorProphecy->has('foo')->willReturn(true)->shouldBeCalled();
×
274
        $filterLocatorProphecy->get('foo')->willReturn($filterProphecy->reveal())->shouldBeCalled();
×
275

276
        $dummy = new Dummy();
×
277

278
        $decoratedProphecy = $this->prophesize(NormalizerInterface::class);
×
279
        $decoratedProphecy->normalize($dummy, CollectionNormalizer::FORMAT, [
×
280
            'request_uri' => '/foo?bar=baz',
×
281
            'resource_class' => Dummy::class,
×
282
            'operation_name' => 'get',
×
283
        ])->willReturn(['name' => 'foo']);
×
284

285
        $resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
286
        $resourceMetadataFactoryProphecy->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
×
287
            (new ApiResource(Dummy::class))
×
288
                ->withShortName('Dummy')
×
289
                ->withOperations(new Operations([
×
290
                    'get' => (new GetCollection())->withShortName('Dummy')->withFilters(['foo']),
×
291
                ])),
×
292
        ]));
×
293

294
        $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
×
295
        $resourceClassResolverProphecy->getResourceClass($dummy, Dummy::class)->willReturn(Dummy::class);
×
296

297
        $normalizer = new CollectionFiltersNormalizer(
×
298
            $decoratedProphecy->reveal(),
×
299
            $resourceMetadataFactoryProphecy->reveal(),
×
300
            $resourceClassResolverProphecy->reveal(),
×
301
            $filterLocatorProphecy->reveal()
×
302
        );
×
303

304
        $this->assertEquals([
×
305
            'name' => 'foo',
×
306
            'hydra:search' => [
×
307
                '@type' => 'hydra:IriTemplate',
×
308
                'hydra:template' => '/foo{?a}',
×
309
                'hydra:variableRepresentation' => 'BasicRepresentation',
×
310
                'hydra:mapping' => [
×
311
                    [
×
312
                        '@type' => 'IriTemplateMapping',
×
313
                        'variable' => 'a',
×
314
                        'property' => 'name',
×
315
                        'required' => true,
×
316
                    ],
×
317
                ],
×
318
            ],
×
319
        ], $normalizer->normalize($dummy, CollectionNormalizer::FORMAT, [
×
320
            'request_uri' => '/foo?bar=baz',
×
321
            'resource_class' => Dummy::class,
×
322
            'operation_name' => 'get',
×
323
        ]));
×
324
    }
325

326
    public function testGetSupportedTypes(): void
327
    {
328
        if (!method_exists(Serializer::class, 'getSupportedTypes')) {
×
329
            $this->markTestSkipped('Symfony Serializer < 6.3');
×
330
        }
331

332
        // TODO: use prophecy when getSupportedTypes() will be added to the interface
333
        $normalizer = new CollectionFiltersNormalizer(
×
NEW
334
            new class implements NormalizerInterface {
×
335
                public function normalize(mixed $object, ?string $format = null, array $context = []): \ArrayObject|array|string|int|float|bool|null
336
                {
337
                    return null;
×
338
                }
339

340
                public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
341
                {
342
                    return true;
×
343
                }
344

345
                public function getSupportedTypes(?string $format): array
346
                {
347
                    return ['*' => true];
×
348
                }
349
            },
×
350
            $this->prophesize(ResourceMetadataCollectionFactoryInterface::class)->reveal(),
×
351
            $this->prophesize(ResourceClassResolverInterface::class)->reveal(),
×
352
            $this->prophesize(ContainerInterface::class)->reveal(),
×
353
        );
×
354

355
        $this->assertSame(['*' => true], $normalizer->getSupportedTypes('jsonld'));
×
356
    }
357
}
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

© 2025 Coveralls, Inc