HttpClientFactoryTest::provideConfig()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 22
nc 1
nop 0
dl 0
loc 32
rs 9.568
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ShlinkioTest\Shlink\Common\Http;
6
7
use GuzzleHttp\HandlerStack;
8
use PHPUnit\Framework\TestCase;
9
use Prophecy\PhpUnit\ProphecyTrait;
10
use Prophecy\Prophecy\ObjectProphecy;
11
use Psr\Container\ContainerInterface;
12
use ReflectionObject;
13
use Shlinkio\Shlink\Common\Http\Exception\InvalidHttpMiddlewareException;
14
use Shlinkio\Shlink\Common\Http\HttpClientFactory;
15
use stdClass;
16
17
use function fopen;
18
19
class HttpClientFactoryTest extends TestCase
20
{
21
    use ProphecyTrait;
22
23
    private const BASE_HANDLERS_COUNT = 4;
24
25
    private HttpClientFactory $factory;
26
    private ObjectProphecy $container;
27
28
    public function setUp(): void
29
    {
30
        $this->factory = new HttpClientFactory();
31
        $this->container = $this->prophesize(ContainerInterface::class);
32
    }
33
34
    /**
35
     * @test
36
     * @dataProvider provideConfig
37
     */
38
    public function properlyCreatesAFactoryWithExpectedNumberOfMiddlewares(
39
        array $config,
40
        int $expectedMiddlewaresAmount
41
    ): void {
42
        $this->container->get('some_middleware')->willReturn(static function (): void {
43
        });
44
        $getConfig = $this->container->get('config')->willReturn(['http_client' => $config]);
45
46
        $client = ($this->factory)($this->container->reveal());
47
        /** @var HandlerStack $handler */
48
        $handler = $client->getConfig('handler');
49
        $ref = new ReflectionObject($handler);
50
        $stack = $ref->getProperty('stack');
51
        $stack->setAccessible(true);
52
53
        $this->assertCount($expectedMiddlewaresAmount + self::BASE_HANDLERS_COUNT, $stack->getValue($handler));
54
        $getConfig->shouldHaveBeenCalledOnce();
55
    }
56
57
    public function provideConfig(): iterable
58
    {
59
        $staticMiddleware = static function (): void {
60
        };
61
62
        yield [[], 0];
63
        yield [['request_middlewares' => []], 0];
64
        yield [['response_middlewares' => []], 0];
65
        yield [[
66
            'request_middlewares' => [],
67
            'response_middlewares' => [],
68
        ], 0];
69
        yield [[
70
            'request_middlewares' => ['some_middleware'],
71
            'response_middlewares' => [],
72
        ], 1];
73
        yield [[
74
            'request_middlewares' => [],
75
            'response_middlewares' => ['some_middleware'],
76
        ], 1];
77
        yield [[
78
            'request_middlewares' => ['some_middleware'],
79
            'response_middlewares' => ['some_middleware'],
80
        ], 2];
81
        yield [[
82
            'request_middlewares' => [$staticMiddleware],
83
            'response_middlewares' => ['some_middleware'],
84
        ], 2];
85
        yield [[
86
            'request_middlewares' => ['some_middleware', $staticMiddleware],
87
            'response_middlewares' => [$staticMiddleware, 'some_middleware'],
88
        ], 4];
89
    }
90
91
    /**
92
     * @param mixed $middleware
93
     * @test
94
     * @dataProvider provideInvalidMiddlewares
95
     */
96
    public function exceptionIsThrownWhenNonCallableStaticMiddlewaresAreProvided($middleware): void
97
    {
98
        $getService = $this->container->get('some_middleware')->willReturn(static function (): void {
99
        });
100
        $getConfig = $this->container->get('config')->willReturn(['http_client' => [
101
            'request_middlewares' => [$middleware],
102
        ]]);
103
104
        $this->expectException(InvalidHttpMiddlewareException::class);
105
        $getService->shouldNotBeCalled();
106
        $getConfig->shouldBeCalledOnce();
107
108
        ($this->factory)($this->container->reveal());
109
    }
110
111
    /**
112
     * @param mixed $middleware
113
     * @test
114
     * @dataProvider provideInvalidMiddlewares
115
     */
116
    public function exceptionIsThrownWhenNonCallableServiceMiddlewaresAreProvided($middleware): void
117
    {
118
        $getService = $this->container->get('some_middleware')->willReturn($middleware);
119
        $getConfig = $this->container->get('config')->willReturn(['http_client' => [
120
            'response_middlewares' => ['some_middleware'],
121
        ]]);
122
123
        $this->expectException(InvalidHttpMiddlewareException::class);
124
        $getService->shouldBeCalledOnce();
125
        $getConfig->shouldBeCalledOnce();
126
127
        ($this->factory)($this->container->reveal());
128
    }
129
130
    public function provideInvalidMiddlewares(): iterable
131
    {
132
        yield [1234];
133
        yield [new stdClass()];
134
        yield [[]];
135
        yield [fopen('php://memory', 'rb+')];
136
    }
137
}
138