HttpClientTest::testOptions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
dl 0
loc 11
c 1
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Elmage\TextNg\Test\Unit;
4
5
use Elmage\TextNg\Enum\Param;
6
use Elmage\TextNg\Authentication\ApiKeyAuthentication;
7
use Elmage\TextNg\Test\TestCase;
8
use Elmage\TextNg\HttpClient;
9
use Elmage\TextNg\Configuration;
10
use GuzzleHttp\Psr7\Response;
11
use GuzzleHttp\RequestOptions;
12
use PHPUnit\Framework\Constraint\Callback;
13
use PHPUnit\Framework\MockObject\MockObject;
14
use GuzzleHttp\ClientInterface;
15
use Psr\Http\Message\RequestInterface;
16
17
class HttpClientTest extends TestCase
18
{
19
    /** @var MockObject|ClientInterface */
20
    private $transport;
21
22
    /** @var HttpClient */
23
    private $client;
24
25
    public static function setUpBeforeClass(): void
26
    {
27
        date_default_timezone_set('Africa/Lagos');
28
    }
29
30
    protected function setUp(): void
31
    {
32
        $this->transport = $this->getMockBuilder(ClientInterface::class)->getMock();
33
34
        $authStub = $this->createStub(ApiKeyAuthentication::class);
35
36
        // Configure the stub.
37
        $authStub->method('getApiKey')
38
            ->will($this->returnValue("TEST_KEY"));
39
40
        $this->client = $this->createHttpClient($authStub);
41
    }
42
43
    protected function tearDown(): void
44
    {
45
        $this->transport = null;
46
        $this->client = null;
47
    }
48
49
    /**
50
     * @dataProvider provideForGetQueryString
51
     */
52
    public function testGetQueryString(string $path, string $expected): void
53
    {
54
        $this->transport->expects($this->once())
55
            ->method('send')
56
            ->with($this->isRequestFor('GET', $expected))
57
            ->will($this->returnValue(new Response()));
58
59
        $this->client->get($path, ['foo' => 'bar']);
60
    }
61
62
    public function provideForGetQueryString(): array
63
    {
64
        return [
65
            ['/', '/?foo=bar&key=TEST_KEY'],
66
            ['/?bar=foo', '/?bar=foo&foo=bar&key=TEST_KEY'],
67
        ];
68
    }
69
70
    /**
71
     * @dataProvider provideForUnsafeMethod
72
     */
73
    public function testUnsafeMethod(string $method): void
74
    {
75
        $this->transport->expects($this->once())
76
            ->method('send')
77
            ->with($this->isRequestFor(strtoupper($method), '/'))
78
            ->will($this->returnValue(new Response()));
79
80
        $this->client->$method('/', ['foo' => 'bar']);
81
    }
82
83
    public function provideForUnsafeMethod(): array
84
    {
85
        return [
86
            ['put'],
87
            ['post'],
88
            ['delete'],
89
        ];
90
    }
91
92
    public function testOptions(): void
93
    {
94
        $this->transport->expects($this->once())
95
            ->method('send')
96
            ->with(
97
                $this->isRequestFor('POST', '/'),
98
                $this->isValidOptionsArray([])
99
            )
100
            ->will($this->returnValue(new Response()));
101
102
        $this->client->post('/', ['foo' => 'bar']);
103
    }
104
105
    /*------------------------------------------------------------------------------
106
    | PRIVATE METHODS
107
    /*------------------------------------------------------------------------------*/
108
109
    private function isRequestFor(string $method, string $path): Callback
110
    {
111
        return $this->callback(
112
            function ($request) use ($method, $path) {
113
                /** @var RequestInterface $request */
114
                $this->assertInstanceOf(RequestInterface::class, $request);
115
                $this->assertEquals($method, $request->getMethod());
116
                $this->assertEquals($path, $request->getRequestTarget());
117
118
                return true;
119
            }
120
        );
121
    }
122
123
    private function isValidOptionsArray(array $headers = [], $form_params = true): Callback
124
    {
125
        return $this->callback(function ($options) use ($headers, $form_params) {
126
            $this->assertArrayHasKey('headers', $options);
127
            $this->assertArrayHasKey('User-Agent', $options['headers']);
128
            $this->assertArrayHasKey('Content-Type', $options['headers']);
129
130
            if ($form_params) {
131
                $this->assertArrayHasKey(RequestOptions::FORM_PARAMS, $options);
132
            }
133
134
            foreach ($headers as $header) {
135
                $this->assertArrayHasKey($header, $options['headers']);
136
            }
137
138
            return true;
139
        });
140
    }
141
142
    private function createHttpClient(ApiKeyAuthentication $auth): HttpClient
143
    {
144
        return new HttpClient(
145
            Configuration::DEFAULT_API_URL,
146
            Configuration::DEFAULT_API_VERSION,
147
            $auth,
148
            "TestSender",
149
            $this->transport
150
        );
151
    }
152
}
153