Passed
Pull Request — master (#306)
by Tobias
02:05
created

BrowserTest   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 154
rs 10
c 0
b 0
f 0
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A testLastMessages() 0 13 1
C testSubmitForm() 0 45 7
A testBasicMethods() 0 13 1
A setUp() 0 5 1
B submitFormProvider() 0 37 1
A provideMethods() 0 9 1
A testGetClient() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Buzz\Test\Unit;
6
7
use Buzz\Browser;
8
use Buzz\Client\Curl;
9
use Nyholm\Psr7\Request;
10
use Nyholm\Psr7\Response;
11
use PHPUnit\Framework\TestCase;
12
use Psr\Http\Message\ResponseInterface;
13
14
class BrowserTest extends TestCase
15
{
16
    /** @var Curl */
17
    private $client;
18
19
    /** @var Browser */
20
    private $browser;
21
22
    protected function setUp()
23
    {
24
        $this->client = $this->getMockBuilder('Buzz\Client\Curl')->getMock();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getMockBuilder('B...lient\Curl')->getMock() of type PHPUnit\Framework\MockObject\MockObject is incompatible with the declared type Buzz\Client\Curl of property $client.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
25
26
        $this->browser = new Browser($this->client);
27
    }
28
29
    /**
30
     * @dataProvider provideMethods
31
     */
32
    public function testBasicMethods($method, $content)
33
    {
34
        $response = new Response(200, [], 'foobar');
35
        $headers = ['X-Foo' => 'bar'];
36
37
        $this->client->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Buzz\Client\Curl. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
        $this->client->/** @scrutinizer ignore-call */ 
38
                       expects($this->once())

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
38
            ->method('sendRequest')
39
            ->will($this->returnValue($response));
40
41
        $actual = $this->browser->$method('http://google.com/', $headers, $content);
42
43
        $this->assertInstanceOf(ResponseInterface::class, $actual);
44
        $this->assertEquals($response->getBody()->__toString(), $actual->getBody()->__toString());
45
    }
46
47
    public function provideMethods()
48
    {
49
        return [
50
            ['get',    ''],
51
            ['head',   ''],
52
            ['post',   'content'],
53
            ['put',    'content'],
54
            ['patch',    'content'],
55
            ['delete', 'content'],
56
        ];
57
    }
58
59
    public function testLastMessages()
60
    {
61
        $request = new Request('GET', 'http://www.google.se');
62
        $response = new Response(200, [], 'foobar');
63
64
        $this->client->expects($this->once())
65
            ->method('sendRequest')
66
            ->will($this->returnValue($response));
67
68
        $this->browser->sendRequest($request);
69
70
        $this->assertSame($request, $this->browser->getLastRequest());
71
        $this->assertSame($response, $this->browser->getLastResponse());
72
    }
73
74
    public function testGetClient()
75
    {
76
        $client = new Curl();
77
        $browser = new Browser($client);
78
        $this->assertSame($client, $browser->getClient());
79
    }
80
81
    /**
82
     * @dataProvider submitFormProvider
83
     */
84
    public function testSubmitForm(array $fields, array $headers, array $requestHeaders, string $requestBody)
85
    {
86
        $request = new Request('GET', '/');
87
        $response = new Response(201);
88
        $headerValidator = function (array $input) use ($requestHeaders) {
89
            foreach ($requestHeaders as $name => $value) {
90
                if (!isset($input[$name])) {
91
                    return false;
92
                }
93
94
                if ('regex' === substr($value, 0, 5)) {
95
                    if (!preg_match(substr($value, 5), $input[$name])) {
96
                        return false;
97
                    }
98
                } elseif ($value !== $input[$name]) {
99
                    return false;
100
                }
101
            }
102
103
            return true;
104
        };
105
        $bodyValidator = function ($input) use ($requestBody) {
106
            if ('regex' !== substr($requestBody, 0, 5)) {
107
                return $input === $requestBody;
108
            }
109
            $regex = substr($requestBody, 5);
110
            $regex = str_replace("\n", "\r\n", $regex);
111
112
            return preg_match($regex, $input);
113
        };
114
115
        $browser = $this->getMockBuilder(Browser::class)
116
            ->setMethods(['sendRequest', 'createRequest'])
117
            ->disableOriginalConstructor()
118
            ->getMock();
119
        $browser->expects($this->once())->method('createRequest')
120
            ->with('POST', '/', $this->callback($headerValidator), $this->callback($bodyValidator))
0 ignored issues
show
Bug introduced by
'POST' of type string is incompatible with the type array expected by parameter $arguments of PHPUnit\Framework\MockOb...nvocationMocker::with(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
            ->with(/** @scrutinizer ignore-type */ 'POST', '/', $this->callback($headerValidator), $this->callback($bodyValidator))
Loading history...
Bug introduced by
$this->callback($headerValidator) of type PHPUnit\Framework\Constraint\Callback is incompatible with the type array expected by parameter $arguments of PHPUnit\Framework\MockOb...nvocationMocker::with(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
            ->with('POST', '/', /** @scrutinizer ignore-type */ $this->callback($headerValidator), $this->callback($bodyValidator))
Loading history...
121
            ->willReturn($request);
122
        $browser->expects($this->once())->method('sendRequest')
123
            ->willReturn($response);
124
125
        /** @var Browser $browser */
126
        $result = $browser->submitForm('/', $fields, 'POST', $headers);
127
128
        $this->assertEquals($response->getStatusCode(), $result->getStatusCode());
129
    }
130
131
    public function submitFormProvider()
132
    {
133
        yield [
134
            ['user[name]' => 'Kris Wallsmith', 'user[email]' => '[email protected]'],
135
            ['foo' => 'bar'],
136
            ['foo' => 'bar', 'Content-Type' => 'application/x-www-form-urlencoded'],
137
            'user%5Bname%5D=Kris+Wallsmith&user%5Bemail%5D=foo%40bar.com',
138
        ];
139
        yield [
140
            ['email' => '[email protected]', 'image' => ['path' => dirname(__DIR__).'/Resources/pixel.gif']],
141
            [],
142
            ['Content-Type' => 'regex|^multipart/form-data; boundary=".+"$|'],
143
            'regex|--[0-9a-f\.]+
144
Content-Disposition: form-data; name="image"
145
Content-Length: 43
146
147
GIF[^;]+;
148
--[0-9a-f\.]+
149
Content-Disposition: form-data; name="email"
150
Content-Length: 11
151
152
[email protected]
153
--[0-9a-f\.]+--
154
|', ];
155
        yield [
156
            ['email' => '[email protected]', 'image' => [
157
                'path' => dirname(__DIR__).'/Resources/pixel.gif',
158
                'contentType' => 'image/gif',
159
                'filename' => 'my-pixel.gif',
160
            ], 'other-image' => [
161
                'path' => dirname(__DIR__).'/Resources/pixel.gif',
162
                'contentType' => 'image/gif',
163
                'filename' => 'other-pixel.gif',
164
            ]],
165
            [],
166
            ['Content-Type' => 'regex|^multipart/form-data; boundary=".+"$|'],
167
            'regex|--[0-9a-f\.]+
168
Content-Disposition: form-data; name="image"; filename="my-pixel.gif"
169
Content-Length: 43
170
Content-Type: image/gif
171
172
GIF[^;]+;
173
--[0-9a-f\.]+
174
Content-Disposition: form-data; name="other-image"; filename="other-pixel.gif"
175
Content-Length: 43
176
Content-Type: image/gif
177
178
GIF[^;]+;
179
--[0-9a-f\.]+
180
Content-Disposition: form-data; name="email"
181
Content-Length: 11
182
183
[email protected]
184
--[0-9a-f\.]+--
185
|', ];
186
    }
187
}
188