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

api-platform / core / 7142557150

08 Dec 2023 02:28PM UTC coverage: 36.003% (-1.4%) from 37.36%
7142557150

push

github

web-flow
fix(jsonld): remove link to ApiDocumentation when doc is disabled (#6029)

0 of 1 new or added line in 1 file covered. (0.0%)

2297 existing lines in 182 files now uncovered.

9992 of 27753 relevant lines covered (36.0%)

147.09 hits per line

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

0.0
/src/HttpCache/Tests/VarnishXKeyPurgerTest.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\HttpCache\Tests;
15

16
use ApiPlatform\HttpCache\VarnishXKeyPurger;
17
use GuzzleHttp\ClientInterface;
18
use GuzzleHttp\Promise\PromiseInterface;
19
use GuzzleHttp\Psr7\Response;
20
use PHPUnit\Framework\TestCase;
21
use Prophecy\PhpUnit\ProphecyTrait;
22
use Psr\Http\Message\RequestInterface;
23
use Psr\Http\Message\ResponseInterface;
24
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
25
use Symfony\Contracts\HttpClient\HttpClientInterface;
26

27
/**
28
 * @author Kévin Dunglas <dunglas@gmail.com>
29
 */
30
class VarnishXKeyPurgerTest extends TestCase
31
{
32
    use ProphecyTrait;
33

34
    public function testPurge(): void
35
    {
36
        $clientProphecy1 = $this->prophesize(ClientInterface::class);
×
37
        $clientProphecy1->request('PURGE', '', ['headers' => ['xkey' => '/foo']])->willReturn(new Response())->shouldBeCalled();
×
38
        $clientProphecy1->request('PURGE', '', ['headers' => ['xkey' => '/foo /bar']])->willReturn(new Response())->shouldBeCalled();
×
39

40
        $clientProphecy2 = $this->prophesize(ClientInterface::class);
×
41
        $clientProphecy2->request('PURGE', '', ['headers' => ['xkey' => '/foo']])->willReturn(new Response())->shouldBeCalled();
×
42
        $clientProphecy2->request('PURGE', '', ['headers' => ['xkey' => '/foo /bar']])->willReturn(new Response())->shouldBeCalled();
×
43

44
        $clientProphecy3 = $this->prophesize(ClientInterface::class);
×
45
        $clientProphecy3->request('PURGE', '', ['headers' => ['xkey' => '/foo /bar']])->willReturn(new Response())->shouldBeCalled();
×
46

47
        $clientProphecy4 = $this->prophesize(ClientInterface::class);
×
48
        $clientProphecy4->request('PURGE', '', ['headers' => ['xkey' => '/foo /bar']])->willReturn(new Response())->shouldBeCalled();
×
49

50
        /** @var HttpClientInterface $client1 */
51
        $client1 = $clientProphecy1->reveal();
×
52
        /** @var HttpClientInterface $client2 */
53
        $client2 = $clientProphecy2->reveal();
×
54
        $purger = new VarnishXKeyPurger([$client1, $client2]);
×
55
        $purger->purge(['/foo']);
×
56
        $purger->purge(['/foo' => '/foo', '/bar' => '/bar']);
×
57

58
        /** @var HttpClientInterface $client3 */
59
        $client3 = $clientProphecy3->reveal();
×
60
        /** @var HttpClientInterface $client4 */
61
        $client4 = $clientProphecy4->reveal();
×
62
        $purger = new VarnishXKeyPurger([$client3, $client4], 12);
×
63
        $purger->purge(['/foo' => '/foo', '/bar' => '/bar']);
×
64
    }
65

66
    public function testEmptyTags(): void
67
    {
68
        $clientProphecy1 = $this->prophesize(ClientInterface::class);
×
69
        $clientProphecy1->request()->shouldNotBeCalled();
×
70

71
        /** @var HttpClientInterface $client1 */
72
        $client1 = $clientProphecy1->reveal();
×
73
        $purger = new VarnishXKeyPurger([$client1]);
×
74
        $purger->purge([]);
×
75
    }
76

77
    public function testHeaderTooLong(): void
78
    {
79
        $this->expectExceptionMessage('IRI "/foobar-long-foobar-toolong-foofoo-barbar" is too long to fit current max header length (currently set to "20"). You can increase it using the "api_platform.http_cache.invalidation.max_header_length" parameter.');
×
80

81
        $clientProphecy1 = $this->prophesize(ClientInterface::class);
×
82
        $clientProphecy1->request('PURGE', '', ['headers' => ['xkey' => '/foobar-long-foobar-toolong-foofoo-barbar']])->willReturn(new Response())->shouldNotBeCalled();
×
83

84
        /** @var HttpClientInterface $client1 */
85
        $client1 = $clientProphecy1->reveal();
×
86
        $purger = new VarnishXKeyPurger([$client1], 20);
×
87
        $purger->purge(['/foobar-long-foobar-toolong-foofoo-barbar']);
×
88
    }
89

90
    public function testCustomGlue(): void
91
    {
92
        $clientProphecy1 = $this->prophesize(ClientInterface::class);
×
93
        $clientProphecy1->request('PURGE', '', ['headers' => ['xkey' => '/foo,/bar,/baz']])->willReturn(new Response())->shouldBeCalled();
×
94

95
        /** @var HttpClientInterface $client1 */
96
        $client1 = $clientProphecy1->reveal();
×
97
        $purger = new VarnishXKeyPurger([$client1], 50, ',');
×
98
        $purger->purge(['/foo', '/bar', '/baz']);
×
99
    }
100

101
    /**
102
     * @dataProvider provideChunkHeaderCases
103
     */
104
    public function testItChunksHeaderToAvoidHittingVarnishLimit(int $maxHeaderLength, array $iris, array $keysToSend): void
105
    {
106
        /** @var HttpClientInterface $client */
107
        $client = new class() implements ClientInterface {
×
108
            public array $sentKeys = [];
109

UNCOV
110
            public function send(RequestInterface $request, array $options = []): ResponseInterface
×
111
            {
112
                throw new \LogicException('Not implemented');
×
113
            }
114

UNCOV
115
            public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface
×
116
            {
117
                throw new \LogicException('Not implemented');
×
118
            }
119

UNCOV
120
            public function request($method, $uri, array $options = []): ResponseInterface
×
121
            {
122
                $this->sentKeys[] = $options['headers']['xkey'];
×
123

124
                return new Response();
×
125
            }
126

UNCOV
127
            public function requestAsync($method, $uri, array $options = []): PromiseInterface
×
128
            {
129
                throw new \LogicException('Not implemented');
×
130
            }
131

132
            public function getConfig($option = null): void
133
            {
134
                throw new \LogicException('Not implemented');
×
135
            }
136
        };
×
137

138
        $purger = new VarnishXKeyPurger([$client], $maxHeaderLength);
×
139
        $purger->purge($iris);
×
140

141
        self::assertSame($keysToSend, $client->sentKeys); // @phpstan-ignore-line
×
142
    }
143

144
    public static function provideChunkHeaderCases(): \Generator
145
    {
146
        yield 'no iri' => [
×
147
            50,
×
148
            [],
×
149
            [],
×
150
        ];
×
151

152
        yield 'one iri' => [
×
153
            50,
×
154
            ['/foo'],
×
155
            ['/foo'],
×
156
        ];
×
157

158
        yield 'few iris' => [
×
159
            50,
×
160
            ['/foo', '/bar', '/ab', '/cd'],
×
161
            ['/foo /bar /ab /cd'],
×
162
        ];
×
163

164
        yield 'iris to generate a header with exactly the maximum length' => [
×
165
            27,
×
166
            ['/foofoofoofoo', '/barbarbarbar'],
×
167
            ['/foofoofoofoo /barbarbarbar'],
×
168
        ];
×
169

170
        yield 'iris to generate a header with exactly the maximum length and a smaller one' => [
×
171
            21,
×
172
            ['/foobarfoo', '/barfoobar', '/baz'],
×
173
            [
×
174
                '/foobarfoo /barfoobar',
×
175
                '/baz',
×
176
            ],
×
177
        ];
×
178

179
        yield 'with last iri too long to be part of the same header' => [
×
180
            18,
×
181
            ['/foo', '/bar', '/some-longer-tag'],
×
182
            [
×
183
                '/foo /bar',
×
184
                '/some-longer-tag',
×
185
            ],
×
186
        ];
×
187

188
        yield 'iris to have five headers' => [
×
189
            13,
×
190
            ['/foo/1', '/foo/2', '/foo/3', '/foo/4', '/foo/5', '/foo/6', '/foo/7', '/foo/8', '/foo/9', '/foo/a'],
×
191
            ['/foo/1 /foo/2', '/foo/3 /foo/4', '/foo/5 /foo/6', '/foo/7 /foo/8', '/foo/9 /foo/a'],
×
192
        ];
×
193

194
        yield 'iris to have three headers of same size and one bigger' => [
×
195
            13,
×
196
            ['/foo/1', '/foo/2', '/foo/3', '/foo/4', '/foo/5', '/foo/6', '/foo/8910'],
×
197
            ['/foo/1 /foo/2', '/foo/3 /foo/4', '/foo/5 /foo/6', '/foo/8910'],
×
198
        ];
×
199

200
        yield 'with varnish default limit' => [
×
201
            8000,
×
202
            array_fill(0, 3002, '/foo'),
×
203
            [
×
204
                implode(' ', array_fill(0, 1600, '/foo')),
×
205
                implode(' ', array_fill(0, 1402, '/foo')),
×
206
            ],
×
207
        ];
×
208
    }
209

210
    public function testConstructor(): void
211
    {
212
        $clientProphecy = $this->prophesize(ClientInterface::class);
×
213
        $clientProphecy->request('PURGE', '', ['headers' => ['xkey' => '/foo']])->willReturn(new Response())->shouldBeCalled();
×
214
        $purger = new VarnishXKeyPurger(new RewindableGenerator(static function () use ($clientProphecy) {
×
215
            yield $clientProphecy->reveal();
×
216
        }, 1));
×
217

218
        $purger->purge(['/foo']);
×
219
    }
220
}
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