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

api-platform / core / 17729190580

15 Sep 2025 09:57AM UTC coverage: 22.227% (-0.4%) from 22.578%
17729190580

push

github

web-flow
fix(metadata): compute isWritable during updates (#7383)

fixes #7382

4 of 532 new or added lines in 16 files covered. (0.75%)

167 existing lines in 22 files now uncovered.

11127 of 50061 relevant lines covered (22.23%)

23.49 hits per line

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

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

16
use ApiPlatform\Hal\Serializer\CollectionNormalizer;
17
use ApiPlatform\Metadata\ApiResource;
18
use ApiPlatform\Metadata\GetCollection;
19
use ApiPlatform\Metadata\Operations;
20
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
21
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
22
use ApiPlatform\Metadata\ResourceClassResolverInterface;
23
use ApiPlatform\State\Pagination\PaginatorInterface;
24
use ApiPlatform\State\Pagination\PartialPaginatorInterface;
25
use PHPUnit\Framework\TestCase;
26
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
27

28
/**
29
 * @author Kévin Dunglas <dunglas@gmail.com>
30
 */
31
class CollectionNormalizerTest extends TestCase
32
{
33
    #[\PHPUnit\Framework\Attributes\Group('legacy')]
34
    public function testSupportsNormalize(): void
35
    {
NEW
36
        $resourceClassResolverMock = $this->createMock(ResourceClassResolverInterface::class);
×
NEW
37
        $resourceMetadataFactoryMock = $this->createMock(ResourceMetadataCollectionFactoryInterface::class);
×
NEW
38
        $normalizer = new CollectionNormalizer($resourceClassResolverMock, 'page', $resourceMetadataFactoryMock);
×
39

40
        $this->assertTrue($normalizer->supportsNormalization([], CollectionNormalizer::FORMAT, ['resource_class' => 'Foo']));
×
41
        $this->assertTrue($normalizer->supportsNormalization([], CollectionNormalizer::FORMAT, ['resource_class' => 'Foo', 'api_sub_level' => true]));
×
42
        $this->assertTrue($normalizer->supportsNormalization([], CollectionNormalizer::FORMAT, []));
×
43
        $this->assertTrue($normalizer->supportsNormalization(new \ArrayObject(), CollectionNormalizer::FORMAT, ['resource_class' => 'Foo']));
×
44
        $this->assertFalse($normalizer->supportsNormalization([], 'xml', ['resource_class' => 'Foo']));
×
45
        $this->assertFalse($normalizer->supportsNormalization(new \ArrayObject(), 'xml', ['resource_class' => 'Foo']));
×
46

47
        $this->assertEmpty($normalizer->getSupportedTypes('json'));
×
48
        $this->assertSame([
×
49
            'native-array' => true,
×
50
            '\Traversable' => true,
×
51
        ], $normalizer->getSupportedTypes($normalizer::FORMAT));
×
52
    }
53

54
    public function testNormalizePaginator(): void
55
    {
56
        $this->assertEquals(
×
57
            [
×
58
                '_links' => [
×
59
                    'self' => ['href' => '/?page=3'],
×
60
                    'first' => ['href' => '/?page=1'],
×
61
                    'last' => ['href' => '/?page=7'],
×
62
                    'prev' => ['href' => '/?page=2'],
×
63
                    'next' => ['href' => '/?page=4'],
×
64
                    'item' => [
×
65
                        '/me',
×
66
                    ],
×
67
                ],
×
68
                '_embedded' => [
×
69
                    'item' => [
×
70
                        [
×
71
                            '_links' => [
×
72
                                'self' => '/me',
×
73
                            ],
×
74
                            'name' => 'Kévin',
×
75
                        ],
×
76
                    ],
×
77
                ],
×
78
                'totalItems' => 1312,
×
79
                'itemsPerPage' => 12,
×
80
            ],
×
81
            $this->normalizePaginator()
×
82
        );
×
83
    }
84

85
    public function testNormalizePartialPaginator(): void
86
    {
87
        $this->assertEquals(
×
88
            [
×
89
                '_links' => [
×
90
                    'self' => ['href' => '/?page=3'],
×
91
                    'prev' => ['href' => '/?page=2'],
×
92
                    'next' => ['href' => '/?page=4'],
×
93
                    'item' => [
×
94
                        '/me',
×
95
                    ],
×
96
                ],
×
97
                '_embedded' => [
×
98
                    'item' => [
×
99
                        [
×
100
                            '_links' => [
×
101
                                'self' => '/me',
×
102
                            ],
×
103
                            'name' => 'Kévin',
×
104
                        ],
×
105
                    ],
×
106
                ],
×
107
                'itemsPerPage' => 12,
×
108
            ],
×
109
            $this->normalizePaginator(true)
×
110
        );
×
111
    }
112

113
    private function normalizePaginator(bool $partial = false)
114
    {
115
        if ($partial) {
×
NEW
116
            $paginator = $this->createMock(PartialPaginatorInterface::class);
×
117
        } else {
NEW
118
            $paginator = $this->createMock(PaginatorInterface::class);
×
119
        }
120

NEW
121
        $paginator->method('getCurrentPage')->willReturn(3.);
×
NEW
122
        $paginator->method('getItemsPerPage')->willReturn(12.);
×
NEW
123
        $paginator->method('valid')->willReturnOnConsecutiveCalls(true, false); // @phpstan-ignore-line
×
NEW
124
        $paginator->method('current')->willReturn('foo'); // @phpstan-ignore-line
×
125

126
        if (!$partial) {
×
NEW
127
            $paginator->method('getLastPage')->willReturn(7.); // @phpstan-ignore-line
×
NEW
128
            $paginator->method('getTotalItems')->willReturn(1312.); // @phpstan-ignore-line
×
129
        } else {
NEW
130
            $paginator->method('count')->willReturn(12);
×
131
        }
132

NEW
133
        $resourceClassResolverMock = $this->createMock(ResourceClassResolverInterface::class);
×
NEW
134
        $resourceClassResolverMock->method('getResourceClass')->with($paginator, 'Foo')->willReturn('Foo');
×
135

NEW
136
        $resourceMetadataFactoryMock = $this->createMock(ResourceMetadataCollectionFactoryInterface::class);
×
NEW
137
        $resourceMetadataFactoryMock->method('create')->with('Foo')->willReturn(new ResourceMetadataCollection('Foo', [
×
138
            (new ApiResource())->withShortName('Foo')->withOperations(new Operations([
×
139
                'bar' => (new GetCollection())->withShortName('Foo'),
×
140
            ])),
×
141
        ]));
×
142

NEW
143
        $itemNormalizer = $this->createMock(NormalizerInterface::class);
×
NEW
144
        $itemNormalizer->method('normalize')->with('foo', CollectionNormalizer::FORMAT, [
×
145
            'resource_class' => 'Foo',
×
146
            'api_sub_level' => true,
×
147
            'root_operation_name' => 'bar',
×
148
        ])->willReturn(['_links' => ['self' => '/me'], 'name' => 'Kévin']);
×
149

NEW
150
        $normalizer = new CollectionNormalizer($resourceClassResolverMock, 'page', $resourceMetadataFactoryMock);
×
NEW
151
        $normalizer->setNormalizer($itemNormalizer);
×
152

NEW
153
        return $normalizer->normalize($paginator, CollectionNormalizer::FORMAT, [
×
154
            'resource_class' => 'Foo',
×
155
            'operation_name' => 'bar',
×
156
        ]);
×
157
    }
158
}
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