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

api-platform / core / 14648308077

24 Apr 2025 05:54PM UTC coverage: 7.021%. First build
14648308077

Pull #6904

github

web-flow
Merge e57e10524 into 7c796de0d
Pull Request #6904: feat(graphql): added support for graphql subscriptions to work for actions

55 of 188 new or added lines in 9 files covered. (29.26%)

11165 of 159026 relevant lines covered (7.02%)

6.23 hits per line

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

0.0
/src/GraphQl/Tests/Subscription/SubscriptionManagerTest.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\Subscription;
15

16
use ApiPlatform\GraphQl\Subscription\SubscriptionIdentifierGeneratorInterface;
17
use ApiPlatform\GraphQl\Subscription\SubscriptionManager;
18
use ApiPlatform\GraphQl\Tests\Fixtures\ApiResource\Dummy;
19
use ApiPlatform\Metadata\ApiResource;
20
use ApiPlatform\Metadata\Get;
21
use ApiPlatform\Metadata\GraphQl\Subscription;
22
use ApiPlatform\Metadata\IriConverterInterface;
23
use ApiPlatform\Metadata\Operations;
24
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
25
use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
26
use ApiPlatform\State\ProcessorInterface;
27
use GraphQL\Type\Definition\ResolveInfo;
28
use PHPUnit\Framework\TestCase;
29
use Prophecy\PhpUnit\ProphecyTrait;
30
use Prophecy\Prophecy\ObjectProphecy;
31
use Psr\Cache\CacheItemInterface;
32
use Psr\Cache\CacheItemPoolInterface;
33

34
/**
35
 * @author Alan Poulain <contact@alanpoulain.eu>
36
 */
37
class SubscriptionManagerTest extends TestCase
38
{
39
    use ProphecyTrait;
40

41
    private ObjectProphecy $subscriptionsCacheProphecy;
42
    private ObjectProphecy $subscriptionIdentifierGeneratorProphecy;
43
    private ObjectProphecy $normalizeProcessor;
44
    private ObjectProphecy $iriConverterProphecy;
45
    private SubscriptionManager $subscriptionManager;
46
    private ObjectProphecy $resourceMetadataCollectionFactory;
47

48
    /**
49
     * {@inheritdoc}
50
     */
51
    protected function setUp(): void
52
    {
53
        $this->subscriptionsCacheProphecy = $this->prophesize(CacheItemPoolInterface::class);
×
54
        $this->subscriptionIdentifierGeneratorProphecy = $this->prophesize(SubscriptionIdentifierGeneratorInterface::class);
×
55
        $this->normalizeProcessor = $this->prophesize(ProcessorInterface::class);
×
56
        $this->iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
×
57
        $this->resourceMetadataCollectionFactory = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
×
58
        $this->subscriptionManager = new SubscriptionManager($this->subscriptionsCacheProphecy->reveal(), $this->subscriptionIdentifierGeneratorProphecy->reveal(), $this->normalizeProcessor->reveal(), $this->iriConverterProphecy->reveal(), $this->resourceMetadataCollectionFactory->reveal());
×
59
    }
60

61
    public function testRetrieveSubscriptionIdNoIdentifier(): void
62
    {
63
        $info = $this->prophesize(ResolveInfo::class);
×
64
        $info->getFieldSelection(\PHP_INT_MAX)->willReturn([]);
×
65

66
        $context = ['args' => [], 'info' => $info->reveal(), 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true];
×
67

68
        $this->assertNull($this->subscriptionManager->retrieveSubscriptionId($context, null));
×
69
    }
70

71
    public function testRetrieveSubscriptionIdNoHit(): void
72
    {
73
        $infoProphecy = $this->prophesize(ResolveInfo::class);
×
74
        $fields = ['fields'];
×
75
        $infoProphecy->getFieldSelection(\PHP_INT_MAX)->willReturn($fields);
×
76

77
        $context = ['args' => ['input' => ['id' => '/foos/34']], 'info' => $infoProphecy->reveal(), 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true];
×
78
        $result = ['result', 'clientSubscriptionId' => 'client-subscription-id'];
×
79

80
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
81
        $cacheItemProphecy->isHit()->willReturn(false);
×
82
        $subscriptionId = 'subscriptionId';
×
83
        $this->subscriptionIdentifierGeneratorProphecy->generateSubscriptionIdentifier($fields)->willReturn($subscriptionId);
×
84
        $cacheItemProphecy->set([[$subscriptionId, $fields, ['result']]])->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
85
        $this->subscriptionsCacheProphecy->getItem('_foos_34')->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
86
        $this->subscriptionsCacheProphecy->save($cacheItemProphecy->reveal())->shouldBeCalled();
×
87

88
        $this->assertSame($subscriptionId, $this->subscriptionManager->retrieveSubscriptionId($context, $result));
×
89
    }
90

91
    public function testRetrieveSubscriptionIdHitNotCached(): void
92
    {
93
        $infoProphecy = $this->prophesize(ResolveInfo::class);
×
94
        $fields = ['fields'];
×
95
        $infoProphecy->getFieldSelection(\PHP_INT_MAX)->willReturn($fields);
×
96

97
        $context = ['args' => ['input' => ['id' => '/foos/34']], 'info' => $infoProphecy->reveal(), 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true];
×
98
        $result = ['result', 'clientSubscriptionId' => 'client-subscription-id'];
×
99

100
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
101
        $cacheItemProphecy->isHit()->willReturn(true);
×
102
        $cachedSubscriptions = [
×
103
            ['subscriptionIdFoo', ['fieldsFoo'], ['resultFoo']],
×
104
            ['subscriptionIdBar', ['fieldsBar'], ['resultBar']],
×
105
        ];
×
106
        $cacheItemProphecy->get()->willReturn($cachedSubscriptions);
×
107
        $subscriptionId = 'subscriptionId';
×
108
        $this->subscriptionIdentifierGeneratorProphecy->generateSubscriptionIdentifier($fields)->willReturn($subscriptionId);
×
109
        $cacheItemProphecy->set(array_merge($cachedSubscriptions, [[$subscriptionId, $fields, ['result']]]))->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
110
        $this->subscriptionsCacheProphecy->getItem('_foos_34')->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
111
        $this->subscriptionsCacheProphecy->save($cacheItemProphecy->reveal())->shouldBeCalled();
×
112

113
        $this->assertSame($subscriptionId, $this->subscriptionManager->retrieveSubscriptionId($context, $result));
×
114
    }
115

116
    public function testRetrieveSubscriptionIdHitCached(): void
117
    {
118
        $infoProphecy = $this->prophesize(ResolveInfo::class);
×
119
        $fields = ['fieldsBar'];
×
120
        $infoProphecy->getFieldSelection(\PHP_INT_MAX)->willReturn($fields);
×
121

122
        $context = ['args' => ['input' => ['id' => '/foos/34']], 'info' => $infoProphecy->reveal(), 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true];
×
123
        $result = ['result'];
×
124

125
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
126
        $cacheItemProphecy->isHit()->willReturn(true);
×
127
        $cacheItemProphecy->get()->willReturn([
×
128
            ['subscriptionIdFoo', ['fieldsFoo'], ['resultFoo']],
×
129
            ['subscriptionIdBar', ['fieldsBar'], ['resultBar']],
×
130
        ]);
×
131
        $this->subscriptionIdentifierGeneratorProphecy->generateSubscriptionIdentifier($fields)->shouldNotBeCalled();
×
132
        $this->subscriptionsCacheProphecy->getItem('_foos_34')->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
133

134
        $this->assertSame('subscriptionIdBar', $this->subscriptionManager->retrieveSubscriptionId($context, $result));
×
135
    }
136

137
    public function testRetrieveSubscriptionIdHitCachedDifferentFieldsOrder(): void
138
    {
139
        $infoProphecy = $this->prophesize(ResolveInfo::class);
×
140
        $fields = [
×
141
            'third' => true,
×
142
            'second' => [
×
143
                'second' => true,
×
144
                'third' => true,
×
145
                'first' => true,
×
146
            ],
×
147
            'first' => true,
×
148
        ];
×
149
        $infoProphecy->getFieldSelection(\PHP_INT_MAX)->willReturn($fields);
×
150

151
        $context = ['args' => ['input' => ['id' => '/foos/34']], 'info' => $infoProphecy->reveal(), 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true];
×
152
        $result = ['result'];
×
153

154
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
155
        $cacheItemProphecy->isHit()->willReturn(true);
×
156
        $cacheItemProphecy->get()->willReturn([
×
157
            ['subscriptionIdFoo', [
×
158
                'first' => true,
×
159
                'second' => [
×
160
                    'first' => true,
×
161
                    'second' => true,
×
162
                    'third' => true,
×
163
                ],
×
164
                'third' => true,
×
165
            ], ['resultFoo']],
×
166
            ['subscriptionIdBar', ['fieldsBar'], ['resultBar']],
×
167
        ]);
×
168
        $this->subscriptionIdentifierGeneratorProphecy->generateSubscriptionIdentifier($fields)->shouldNotBeCalled();
×
169
        $this->subscriptionsCacheProphecy->getItem('_foos_34')->shouldBeCalled()->willReturn($cacheItemProphecy->reveal());
×
170

171
        $this->assertSame('subscriptionIdFoo', $this->subscriptionManager->retrieveSubscriptionId($context, $result));
×
172
    }
173

174
    public function testGetPushPayloadsNoHit(): void
175
    {
176
        $object = new Dummy();
×
177

178
        $this->resourceMetadataCollectionFactory->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
×
179
            (new ApiResource())->withOperations(new Operations([(new Get())->withShortName('Dummy')])),
×
180
        ]));
×
181

182
        $this->iriConverterProphecy->getIriFromResource($object)->willReturn('/dummies/2');
×
183

184
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
185
        $cacheItemProphecy->isHit()->willReturn(false);
×
NEW
186
        $cacheItemProphecy->isHit()->willReturn(false);
×
187
        $this->subscriptionsCacheProphecy->getItem('_dummies_2')->willReturn($cacheItemProphecy->reveal());
×
NEW
188
        $this->subscriptionsCacheProphecy->getItem('_dummies')->willReturn($cacheItemProphecy->reveal());
×
189

NEW
190
        $this->assertEquals([], $this->subscriptionManager->getPushPayloads($object, 'update'));
×
191
    }
192

193
    public function testGetPushPayloadsHit(): void
194
    {
195
        $object = new Dummy();
×
196

197
        $this->resourceMetadataCollectionFactory->create(Dummy::class)->willReturn(new ResourceMetadataCollection(Dummy::class, [
×
198
            (new ApiResource())->withOperations(new Operations([(new Get())->withShortName('Dummy')])),
×
199
        ]));
×
200

201
        $this->iriConverterProphecy->getIriFromResource($object)->willReturn('/dummies/2');
×
202

203
        $cacheItemProphecy = $this->prophesize(CacheItemInterface::class);
×
NEW
204
        $cacheItemProphecy->isHit()->willReturn(true)->shouldBeCalledTimes(2);
×
205
        $cacheItemProphecy->get()->willReturn([
×
206
            ['subscriptionIdFoo', ['fieldsFoo'], ['resultFoo']],
×
207
            ['subscriptionIdBar', ['fieldsBar'], ['resultBar']],
×
208
        ]);
×
209
        $this->subscriptionsCacheProphecy->getItem('_dummies_2')->willReturn($cacheItemProphecy->reveal());
×
NEW
210
        $this->subscriptionsCacheProphecy->getItem('_dummies')->willReturn($cacheItemProphecy->reveal());
×
211

212
        $this->normalizeProcessor->process(
×
213
            $object,
×
NEW
214
            (new Subscription())->withName('mercure_subscription')->withShortName('Dummy'),
×
215
            [],
×
216
            ['fields' => ['fieldsFoo'], 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true]
×
217
        )->willReturn(
×
218
            ['newResultFoo', 'clientSubscriptionId' => 'client-subscription-id']
×
219
        );
×
220

221
        $this->normalizeProcessor->process(
×
222
            $object,
×
NEW
223
            (new Subscription())->withName('mercure_subscription')->withShortName('Dummy'),
×
224
            [],
×
225
            ['fields' => ['fieldsBar'], 'is_collection' => false, 'is_mutation' => false, 'is_subscription' => true]
×
226
        )->willReturn(
×
227
            ['resultBar', 'clientSubscriptionId' => 'client-subscription-id']
×
228
        );
×
229

NEW
230
        $this->assertEquals([['subscriptionIdFoo', ['newResultFoo']]], $this->subscriptionManager->getPushPayloads($object, 'update'));
×
231
    }
232
}
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