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

api-platform / core / 16414174899

21 Jul 2025 10:10AM UTC coverage: 22.039%. Remained the same
16414174899

Pull #7307

github

web-flow
Merge 66cefee02 into d3b4b7b40
Pull Request #7307: Use class-string param type for Metadata::getClass

0 of 191 new or added lines in 19 files covered. (0.0%)

1 existing line in 1 file now uncovered.

11533 of 52331 relevant lines covered (22.04%)

23.45 hits per line

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

0.0
/src/GraphQl/Tests/State/Processor/NormalizeProcessorTest.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\State\Processor;
15

16
use ApiPlatform\GraphQl\Serializer\SerializerContextBuilderInterface;
17
use ApiPlatform\GraphQl\State\Processor\NormalizeProcessor;
18
use ApiPlatform\Metadata\GraphQl\Mutation;
19
use ApiPlatform\Metadata\GraphQl\Query;
20
use ApiPlatform\Metadata\GraphQl\QueryCollection;
21
use ApiPlatform\Metadata\GraphQl\Subscription;
22
use ApiPlatform\State\Pagination\ArrayPaginator;
23
use ApiPlatform\State\Pagination\Pagination;
24
use ApiPlatform\State\Pagination\PartialPaginatorInterface;
25
use GraphQL\Type\Definition\ResolveInfo;
26
use PHPUnit\Framework\TestCase;
27
use Prophecy\PhpUnit\ProphecyTrait;
28
use Prophecy\Prophecy\ObjectProphecy;
29
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
30

31
class NormalizeProcessorTest extends TestCase
32
{
33
    use ProphecyTrait;
34

35
    private ObjectProphecy $resolveInfoProphecy;
36

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

45
    #[\PHPUnit\Framework\Attributes\DataProvider('processItems')]
46
    public function testProcess($body, $operation): void
47
    {
48
        $context = ['args' => []];
×
49
        $serializerContext = ['resource_class' => $operation->getClass()];
×
50
        $normalizer = $this->createMock(NormalizerInterface::class);
×
51
        $serializerContextBuilder = $this->createMock(SerializerContextBuilderInterface::class);
×
52
        $serializerContextBuilder->expects($this->once())->method('create')->with($operation->getClass(), $operation, $context, true)->willReturn($serializerContext);
×
53
        $normalizer->expects($this->once())->method('normalize')->with($body, 'graphql', $serializerContext);
×
54
        $processor = new NormalizeProcessor($normalizer, $serializerContextBuilder, new Pagination());
×
55
        $processor->process($body, $operation, [], $context);
×
56
    }
57

58
    public static function processItems(): array
59
    {
60
        return [
×
NEW
61
            [new \stdClass(), new Query(class: \stdClass::class)],
×
NEW
62
            [new \stdClass(), new Mutation(class: \stdClass::class, shortName: 'Foo')],
×
NEW
63
            [new \stdClass(), new Subscription(class: \stdClass::class, shortName: 'Foo')],
×
UNCOV
64
        ];
×
65
    }
66

67
    #[\PHPUnit\Framework\Attributes\DataProvider('processCollection')]
68
    public function testProcessCollection($collection, $operation, $args, ?array $expectedResult, array $getFieldSelection, ?string $expectedExceptionClass = null, ?string $expectedExceptionMessage = null): void
69
    {
70
        $this->resolveInfoProphecy->getFieldSelection(1)->willReturn($getFieldSelection);
×
71
        $context = ['args' => $args, 'info' => $this->resolveInfoProphecy->reveal()];
×
72
        $serializerContext = ['resource_class' => $operation->getClass()];
×
73
        $normalizer = $this->prophesize(NormalizerInterface::class);
×
74

75
        $serializerContextBuilder = $this->createMock(SerializerContextBuilderInterface::class);
×
76
        $serializerContextBuilder->expects($this->once())->method('create')->with($operation->getClass(), $operation, $context, true)->willReturn($serializerContext);
×
77
        foreach ($collection as $v) {
×
78
            $normalizer->normalize($v, 'graphql', $serializerContext)->willReturn(['normalized_item'])->shouldBeCalledOnce();
×
79
        }
80

81
        if ($expectedExceptionClass) {
×
82
            $this->expectException($expectedExceptionClass);
×
83
            $this->expectExceptionMessage($expectedExceptionMessage);
×
84
        }
85

86
        $processor = new NormalizeProcessor($normalizer->reveal(), $serializerContextBuilder, new Pagination());
×
87
        $result = $processor->process(\is_callable($collection) ? $collection($this) : $collection, $operation, [], $context);
×
88
        $this->assertSame($expectedResult, $result);
×
89
    }
90

91
    public static function processCollection(): iterable
92
    {
93
        $partialPaginatorFactory = function (self $that): PartialPaginatorInterface {
×
94
            $partialPaginatorProphecy = $that->prophesize(PartialPaginatorInterface::class);
×
95
            $partialPaginatorProphecy->count()->willReturn(2);
×
96
            $partialPaginatorProphecy->valid()->willReturn(false);
×
97
            $partialPaginatorProphecy->getItemsPerPage()->willReturn(2.0);
×
98
            $partialPaginatorProphecy->rewind();
×
99

100
            return $partialPaginatorProphecy->reveal();
×
101
        };
×
102

NEW
103
        yield 'cursor - not paginator' => [[], new QueryCollection(class: \stdClass::class), [], null, [], \LogicException::class, 'Collection returned by the collection data provider must implement ApiPlatform\State\Pagination\PaginatorInterface or ApiPlatform\State\Pagination\PartialPaginatorInterface.'];
×
NEW
104
        yield 'cursor - empty paginator' => [new ArrayPaginator([], 0, 0), new QueryCollection(class: \stdClass::class), [], ['totalCount' => 0., 'edges' => [], 'pageInfo' => ['startCursor' => null, 'endCursor' => null, 'hasNextPage' => false, 'hasPreviousPage' => false]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
105
        yield 'cursor - paginator' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 0, 2), new QueryCollection(class: \stdClass::class), [],  ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MA=='], ['node' => ['normalized_item'], 'cursor' => 'MQ==']], 'pageInfo' => ['startCursor' => 'MA==', 'endCursor' => 'MQ==', 'hasNextPage' => true, 'hasPreviousPage' => false]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
106
        yield 'cursor - paginator with after cursor' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 1, 2), new QueryCollection(class: \stdClass::class), ['after' => 'MA=='], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ=='], ['node' => ['normalized_item'], 'cursor' => 'Mg==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'Mg==', 'hasNextPage' => false, 'hasPreviousPage' => true]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
107
        yield 'cursor - paginator with bad after cursor' => [new ArrayPaginator([], 0, 0), new QueryCollection(class: \stdClass::class), ['after' => '-'], null, ['edges' => ['cursor' => []]], \UnexpectedValueException::class, 'Cursor - is invalid'];
×
NEW
108
        yield 'cursor - paginator with empty after cursor' => [new ArrayPaginator([], 0, 0), new QueryCollection(class: \stdClass::class), ['after' => ''], null, ['edges' => ['cursor' => []]], \UnexpectedValueException::class, 'Empty cursor is invalid'];
×
NEW
109
        yield 'cursor - paginator with before cursor' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 1, 1), new QueryCollection(class: \stdClass::class), ['before' => 'Mg=='], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'MQ==', 'hasNextPage' => true, 'hasPreviousPage' => true]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
110
        yield 'cursor - paginator with bad before cursor' => [new ArrayPaginator([], 0, 0), new QueryCollection(class: \stdClass::class), ['before' => '-'], null, ['pageInfo' => ['endCursor' => true]], \UnexpectedValueException::class, 'Cursor - is invalid'];
×
NEW
111
        yield 'cursor - paginator with empty before cursor' => [new ArrayPaginator([], 0, 0), new QueryCollection(class: \stdClass::class), ['before' => ''], null, ['pageInfo' => ['endCursor' => true]], \UnexpectedValueException::class, 'Empty cursor is invalid'];
×
NEW
112
        yield 'cursor - paginator with last' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 1, 2), new QueryCollection(class: \stdClass::class), ['last' => 2], ['totalCount' => 3., 'edges' => [['node' => ['normalized_item'], 'cursor' => 'MQ=='], ['node' => ['normalized_item'], 'cursor' => 'Mg==']], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'Mg==', 'hasNextPage' => false, 'hasPreviousPage' => true]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
113
        yield 'cursor - partial paginator' => [$partialPaginatorFactory, new QueryCollection(class: \stdClass::class), [], ['totalCount' => 0., 'edges' => [], 'pageInfo' => ['startCursor' => 'MA==', 'endCursor' => 'MQ==', 'hasNextPage' => false, 'hasPreviousPage' => false]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
NEW
114
        yield 'cursor - partial paginator with after cursor' => [$partialPaginatorFactory, new QueryCollection(class: \stdClass::class), ['after' => 'MA=='], ['totalCount' => 0., 'edges' => [], 'pageInfo' => ['startCursor' => 'MQ==', 'endCursor' => 'Mg==', 'hasNextPage' => false, 'hasPreviousPage' => true]], ['totalCount' => true, 'edges' => ['cursor' => true], 'pageInfo' => ['startCursor' => true, 'endCursor' => true, 'hasNextPage' => true, 'hasPreviousPage' => true]]];
×
115

NEW
116
        yield 'page - not paginator, itemsPerPage requested' => [[], (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], [], ['paginationInfo' => ['itemsPerPage' => true]], \LogicException::class, 'Collection returned by the collection data provider must implement ApiPlatform\State\Pagination\PartialPaginatorInterface to return itemsPerPage field.'];
×
NEW
117
        yield 'page - not paginator, lastPage requested' => [[], (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], [], ['paginationInfo' => ['lastPage' => true]], \LogicException::class, 'Collection returned by the collection data provider must implement ApiPlatform\State\Pagination\PaginatorInterface to return lastPage field.'];
×
NEW
118
        yield 'page - not paginator, totalCount requested' => [[], (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], [], ['paginationInfo' => ['totalCount' => true]], \LogicException::class, 'Collection returned by the collection data provider must implement ApiPlatform\State\Pagination\PaginatorInterface to return totalCount field.'];
×
NEW
119
        yield 'page - not paginator, hasNextPage requested' => [[], (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], [], ['paginationInfo' => ['hasNextPage' => true]], \LogicException::class, 'Collection returned by the collection data provider must implement ApiPlatform\State\Pagination\HasNextPagePaginatorInterface to return hasNextPage field.'];
×
NEW
120
        yield 'page - empty paginator - itemsPerPage requested' => [new ArrayPaginator([], 0, 0), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [], 'paginationInfo' => ['itemsPerPage' => .0]], ['paginationInfo' => ['itemsPerPage' => true]]];
×
NEW
121
        yield 'page - empty paginator - lastPage requested' => [new ArrayPaginator([], 0, 0), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [], 'paginationInfo' => ['lastPage' => 1.0]], ['paginationInfo' => ['lastPage' => true]]];
×
NEW
122
        yield 'page - empty paginator - totalCount requested' => [new ArrayPaginator([], 0, 0), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [], 'paginationInfo' => ['totalCount' => .0]], ['paginationInfo' => ['totalCount' => true]]];
×
NEW
123
        yield 'page - empty paginator - hasNextPage requested' => [new ArrayPaginator([], 0, 0), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [], 'paginationInfo' => ['hasNextPage' => false]], ['paginationInfo' => ['hasNextPage' => true]]];
×
NEW
124
        yield 'page - paginator page 1 - itemsPerPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 0, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item'], ['normalized_item']], 'paginationInfo' => ['itemsPerPage' => 2.0]], ['paginationInfo' => ['itemsPerPage' => true]]];
×
NEW
125
        yield 'page - paginator page 1 - lastPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 0, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item'], ['normalized_item']], 'paginationInfo' => ['lastPage' => 2.0]], ['paginationInfo' => ['lastPage' => true]]];
×
NEW
126
        yield 'page - paginator page 1 - totalCount requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 0, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item'], ['normalized_item']], 'paginationInfo' => ['totalCount' => 3.0]], ['paginationInfo' => ['totalCount' => true]]];
×
NEW
127
        yield 'page - paginator page 1 - hasNextPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 0, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item'], ['normalized_item']], 'paginationInfo' => ['hasNextPage' => true]], ['paginationInfo' => ['hasNextPage' => true]]];
×
NEW
128
        yield 'page - paginator with page - itemsPerPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 2, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item']], 'paginationInfo' => ['itemsPerPage' => 2.0]], ['paginationInfo' => ['itemsPerPage' => true]]];
×
NEW
129
        yield 'page - paginator with page - lastPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 2, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item']], 'paginationInfo' => ['lastPage' => 2.0]], ['paginationInfo' => ['lastPage' => true]]];
×
NEW
130
        yield 'page - paginator with page - totalCount requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 2, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item']], 'paginationInfo' => ['totalCount' => 3.0]], ['paginationInfo' => ['totalCount' => true]]];
×
NEW
131
        yield 'page - paginator with page - hasNextPage requested' => [new ArrayPaginator([(object) ['test' => 'a'], (object) ['test' => 'b'], (object) ['test' => 'c']], 2, 2), (new QueryCollection(class: \stdClass::class))->withPaginationType('page'), [], ['collection' => [['normalized_item']], 'paginationInfo' => ['hasNextPage' => false]], ['paginationInfo' => ['hasNextPage' => true]]];
×
132
    }
133
}
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