Completed
Push — master ( 99d70a...9f3aab )
by Cees-Jan
28s queued 12s
created

IssueClientTest::testExecute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 43
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 1
eloc 31
c 3
b 0
f 0
nc 1
nop 0
dl 0
loc 43
rs 9.424
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ChangelogGenerator\Tests;
6
7
use ChangelogGenerator\GitHubUsernamePassword;
8
use ChangelogGenerator\IssueClient;
9
use PHPUnit\Framework\MockObject\MockObject;
10
use PHPUnit\Framework\TestCase;
11
use Psr\Http\Client\ClientInterface;
12
use Psr\Http\Message\RequestFactoryInterface;
13
use Psr\Http\Message\RequestInterface;
14
use Psr\Http\Message\ResponseInterface;
15
use Psr\Http\Message\StreamInterface;
16
use RuntimeException;
17
18
final class IssueClientTest extends TestCase
19
{
20
    private RequestFactoryInterface&MockObject $messageFactory;
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected '&', expecting T_VARIABLE on line 20 at column 35
Loading history...
21
22
    private ClientInterface&MockObject $client;
23
24
    private IssueClient $issueClient;
25
26
    public function testExecute(): void
27
    {
28
        $request  = $this->createMock(RequestInterface::class);
29
        $response = $this->createMock(ResponseInterface::class);
30
31
        $this->messageFactory->expects(self::once())
32
            ->method('createRequest')
33
            ->with('GET', 'https://www.google.com')
34
            ->willReturn($request);
35
36
        $request->expects(self::once())
37
            ->method('withAddedHeader')
38
            ->with('User-Agent', 'jwage/changelog-generator')
39
            ->willReturn($request);
40
41
        $this->client->expects(self::once())
42
            ->method('sendRequest')
43
            ->with($request)
44
            ->willReturn($response);
45
46
        $stream = $this->createMock(StreamInterface::class);
47
48
        $response->expects(self::once())
49
            ->method('getBody')
50
            ->willReturn($stream);
51
52
        $stream->expects(self::once())
53
            ->method('__toString')
54
            ->willReturn('{"test": true}');
55
56
        $response->expects(self::once())
57
            ->method('getStatusCode')
58
            ->willReturn(200);
59
60
        $response->expects(self::once())
61
            ->method('getHeader')
62
            ->with('Link')
63
            ->willReturn(['<https://www.google.com?next>; rel="next", <https://www.google.com?last>; rel="last"']);
64
65
        $response = $this->issueClient->execute('https://www.google.com');
66
67
        self::assertSame(['test' => true], $response->getBody());
68
        self::assertSame('https://www.google.com?next', $response->getNextUrl());
69
    }
70
71
    public function testExecuteNullNextUrl(): void
72
    {
73
        $request  = $this->createMock(RequestInterface::class);
74
        $response = $this->createMock(ResponseInterface::class);
75
76
        $this->messageFactory->expects(self::once())
77
            ->method('createRequest')
78
            ->with('GET', 'https://www.google.com')
79
            ->willReturn($request);
80
81
        $request->expects(self::once())
82
            ->method('withAddedHeader')
83
            ->with('User-Agent', 'jwage/changelog-generator')
84
            ->willReturn($request);
85
86
        $this->client->expects(self::once())
87
            ->method('sendRequest')
88
            ->with($request)
89
            ->willReturn($response);
90
91
        $stream = $this->createMock(StreamInterface::class);
92
93
        $response->expects(self::once())
94
            ->method('getBody')
95
            ->willReturn($stream);
96
97
        $stream->expects(self::once())
98
            ->method('__toString')
99
            ->willReturn('{"test": true}');
100
101
        $response->expects(self::once())
102
            ->method('getStatusCode')
103
            ->willReturn(200);
104
105
        $response->expects(self::once())
106
            ->method('getHeader')
107
            ->with('Link')
108
            ->willReturn([]);
109
110
        $response = $this->issueClient->execute('https://www.google.com');
111
112
        self::assertSame(['test' => true], $response->getBody());
113
        self::assertNull($response->getNextUrl());
114
    }
115
116
    public function testExecuteThrowsRuntimeExceptionOnNon200(): void
117
    {
118
        $request  = $this->createMock(RequestInterface::class);
119
        $response = $this->createMock(ResponseInterface::class);
120
121
        $this->messageFactory->expects(self::once())
122
            ->method('createRequest')
123
            ->with('GET', 'https://www.google.com')
124
            ->willReturn($request);
125
126
        $request->expects(self::once())
127
            ->method('withAddedHeader')
128
            ->with('User-Agent', 'jwage/changelog-generator')
129
            ->willReturn($request);
130
131
        $this->client->expects(self::once())
132
            ->method('sendRequest')
133
            ->with($request)
134
            ->willReturn($response);
135
136
        $stream = $this->createMock(StreamInterface::class);
137
138
        $response->expects(self::once())
139
            ->method('getBody')
140
            ->willReturn($stream);
141
142
        $stream->expects(self::once())
143
            ->method('__toString')
144
            ->willReturn('{"message": "It failed yo!"}');
145
146
        $response->expects(self::once())
147
            ->method('getStatusCode')
148
            ->willReturn(400);
149
150
        self::expectException(RuntimeException::class);
151
        self::expectExceptionMessage('API call to GitHub failed with status code 400 and message "It failed yo!"');
152
153
        $this->issueClient->execute('https://www.google.com');
154
    }
155
156
    public function testExecuteWithGitHubCredentials(): void
157
    {
158
        $request  = $this->createMock(RequestInterface::class);
159
        $response = $this->createMock(ResponseInterface::class);
160
161
        $this->messageFactory->expects(self::once())
162
            ->method('createRequest')
163
            ->with('GET', 'https://www.google.com')
164
            ->willReturn($request);
165
166
        $request->method('withAddedHeader')
167
            ->with(
168
                self::logicalOr('User-Agent', 'Authorization'),
169
                self::logicalOr('jwage/changelog-generator', 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=')
170
            )
171
            ->willReturnSelf();
172
173
        $this->client->expects(self::once())
174
            ->method('sendRequest')
175
            ->with($request)
176
            ->willReturn($response);
177
178
        $stream = $this->createMock(StreamInterface::class);
179
180
        $response->expects(self::once())
181
            ->method('getBody')
182
            ->willReturn($stream);
183
184
        $stream->expects(self::once())
185
            ->method('__toString')
186
            ->willReturn('{"test": true}');
187
188
        $response->expects(self::once())
189
            ->method('getStatusCode')
190
            ->willReturn(200);
191
192
        $response->expects(self::once())
193
            ->method('getHeader')
194
            ->with('Link')
195
            ->willReturn([]);
196
197
        $response = $this->issueClient->execute(
198
            'https://www.google.com',
199
            new GitHubUsernamePassword('username', 'password')
200
        );
201
202
        self::assertSame(['test' => true], $response->getBody());
203
    }
204
205
    protected function setUp(): void
206
    {
207
        $this->messageFactory = $this->createMock(RequestFactoryInterface::class);
208
        $this->client         = $this->createMock(ClientInterface::class);
209
210
        $this->issueClient = new IssueClient($this->messageFactory, $this->client);
211
    }
212
}
213