Completed
Push — master ( 6fe931...06ed76 )
by WEBEWEB
04:36
created

CURLGetRequestTest   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 264
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 5
dl 0
loc 264
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A testConstructor() 0 11 1
A testAddHeader() 0 16 2
A testAddQueryData() 0 16 2
B testCall() 0 124 4
A testClearHeaders() 0 10 1
A testClearQueryData() 0 10 1
A testRemoveHeader() 0 13 1
A testRemoveQueryData() 0 13 1
1
<?php
2
3
/**
4
 * This file is part of the curl-library package.
5
 *
6
 * (c) 2017 NdC/WBW
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
namespace WBW\Library\CURL\Tests\Request;
13
14
use Exception;
15
use WBW\Library\Core\Exception\Argument\StringArgumentException;
16
use WBW\Library\Core\Utility\HTTPUtility;
17
use WBW\Library\CURL\Exception\CURLRequestCallException;
18
use WBW\Library\CURL\Request\CURLGetRequest;
19
20
/**
21
 * CURL GET request test.
22
 *
23
 * @author NdC/WBW <https://github.com/webeweb/>
24
 * @package WBW\Library\CURL\Tests\Request
25
 * @final
26
 */
27
final class CURLGetRequestTest extends AbstractCURLRequestTest {
28
29
	/**
30
	 * Tests __construct() method.
31
	 *
32
	 * @return void
33
	 */
34
	public function testConstructor() {
35
36
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
37
38
		$this->assertEquals($this->configuration, $obj->getConfiguration());
39
		$this->assertEquals([], $obj->getHeaders());
40
		$this->assertEquals(CURLGetRequest::METHOD_GET, $obj->getMethod());
41
		$this->assertEquals([], $obj->getPostData());
42
		$this->assertEquals([], $obj->getQueryData());
43
		$this->assertEquals("testCall.php", $obj->getResourcePath());
44
	}
45
46
	/**
47
	 * Tests addHeader() method.
48
	 *
49
	 * @return void
50
	 */
51
	public function testAddHeader() {
52
53
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
54
55
		try {
56
			$obj->addHeader(1, "value");
57
		} catch (Exception $ex) {
58
			$this->assertInstanceOf(StringArgumentException::class, $ex);
59
			$this->assertEquals("The argument \"1\" is not a string", $ex->getMessage());
60
		}
61
62
		$obj->addHeader("name", "value");
63
64
		$res = ["name" => "value"];
65
		$this->assertEquals($res, $obj->getHeaders());
66
	}
67
68
	/**
69
	 * Tests addQueryData() method.
70
	 *
71
	 * @return void
72
	 */
73
	public function testAddQueryData() {
74
75
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
76
77
		try {
78
			$obj->addQueryData(1, "value");
79
		} catch (Exception $ex) {
80
			$this->assertInstanceOf(StringArgumentException::class, $ex);
81
			$this->assertEquals("The argument \"1\" is not a string", $ex->getMessage());
82
		}
83
84
		$obj->addQueryData("name", "value");
85
86
		$res = ["name" => "value"];
87
		$this->assertEquals($res, $obj->getQueryData());
88
	}
89
90
	/**
91
	 * Tests call() method.
92
	 *
93
	 * @return void
94
	 */
95
	public function testCall() {
96
97
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
98
99
		/* === Allow encoding ============================================== */
100
		$obj->getConfiguration()->setAllowEncoding(true);
101
102
		$resAE = $obj->call();
103
104
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resAE->getResponseBody(), true)["method"]);
105
		$this->assertEquals(200, $resAE->getResponseInfo()["http_code"]);
106
107
		$obj->getConfiguration()->setAllowEncoding(false);
108
109
		/* === Connect timeout ============================================= */
110
		$obj->getConfiguration()->setConnectTimeout(30);
111
112
		$resCT = $obj->call();
113
114
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resCT->getResponseBody(), true)["method"]);
115
		$this->assertEquals(200, $resCT->getResponseInfo()["http_code"]);
116
117
		$obj->getConfiguration()->setConnectTimeout(0);
118
119
		/* === Debug ======================================================= */
120
		$obj->getConfiguration()->setDebug(true);
121
122
		$resD = $obj->call();
123
124
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resD->getResponseBody(), true)["method"]);
125
		$this->assertEquals(200, $resD->getResponseInfo()["http_code"]);
126
127
		$obj->getConfiguration()->setDebug(false);
128
129
		/* === Headers ===================================================== */
130
		$obj->addHeader("h", "v");
131
132
		$resH = $obj->call();
133
134
		$this->assertContains("h: v", $resH->getRequestHeader());
135
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resH->getResponseBody(), true)["method"]);
136
		$this->assertEquals(200, $resH->getResponseInfo()["http_code"]);
137
138
		$obj->removeHeader("h");
139
140
		/* === JSON ======================================================== */
141
		$obj->addHeader("Content-Type", "application/json");
142
		$obj->addPostData("name", "value");
143
144
		$resJSON = $obj->call();
145
146
		$this->assertContains("Content-Type: application/json", $resJSON->getRequestHeader());
147
		$this->assertContains('{"name":"value"}', $resJSON->getRequestBody());
148
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resH->getResponseBody(), true)["method"]);
149
		$this->assertEquals(200, $resH->getResponseInfo()["http_code"]);
150
151
		$obj->removeHeader("Content-Type");
152
		$obj->removePostData("name");
153
154
		/* === Request timeout ============================================= */
155
		$obj->getConfiguration()->setRequestTimeout(30);
156
157
		$resRT = $obj->call();
158
159
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resRT->getResponseBody(), true)["method"]);
160
		$this->assertEquals(200, $resRT->getResponseInfo()["http_code"]);
161
162
		$obj->getConfiguration()->setRequestTimeout(0);
163
164
		/* === SSL verification ============================================ */
165
		$obj->getConfiguration()->setSslVerification(false);
166
167
		$resSSL = $obj->call();
168
169
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resSSL->getResponseBody(), true)["method"]);
170
		$this->assertEquals(200, $resSSL->getResponseInfo()["http_code"]);
171
172
		$obj->getConfiguration()->setSslVerification(true);
173
174
		/* === Verbose ===================================================== */
175
		$obj->getConfiguration()->setVerbose(true);
176
177
		$resV = $obj->call();
178
179
		$this->assertEquals(CURLGetRequest::METHOD_GET, json_decode($resV->getResponseBody(), true)["method"]);
180
		$this->assertEquals(200, $resV->getResponseInfo()["http_code"]);
181
182
		$obj->getConfiguration()->setVerbose(false);
183
		/* === HTTP code 0 ================================================= */
184
		$obj->getConfiguration()->setRequestTimeout(10);
185
		$obj->addQueryData("sleep", 60);
186
187
		try {
188
			$obj->call();
189
		} catch (Exception $ex) {
190
191
			$this->assertInstanceOf(CURLRequestCallException::class, $ex);
192
			$this->assertContains("Call to ", $ex->getMessage());
193
			$this->assertEquals(0, $ex->getResponse()->getResponseInfo()["http_code"]);
1 ignored issue
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Exception as the method getResponse() does only exist in the following sub-classes of Exception: WBW\Library\CURL\Excepti...URLRequestCallException. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
194
		}
195
196
		$obj->getConfiguration()->setRequestTimeout(0);
197
		$obj->removeQueryData("sleep");
198
199
		/* === HTTP codes ================================================== */
200
		foreach (HTTPUtility::getCodes() as $code) {
201
			try {
202
203
				$obj->addQueryData("code", $code);
204
205
				$rslt = $obj->call();
206
207
				$this->assertEquals($code, $rslt->getResponseInfo()["http_code"], "The method getResponseInfo() does not return the expected value with code " . $code);
208
				$this->assertGreaterThanOrEqual(200, $rslt->getResponseInfo()["http_code"]);
209
				$this->assertLessThanOrEqual(299, $rslt->getResponseInfo()["http_code"]);
210
			} catch (Exception $ex) {
211
212
				$this->assertInstanceOf(CURLRequestCallException::class, $ex);
213
				$this->assertEquals($code, $ex->getResponse()->getResponseInfo()["http_code"], "The method getResponseInfo() does not return the expected value with code " . $code);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Exception as the method getResponse() does only exist in the following sub-classes of Exception: WBW\Library\CURL\Excepti...URLRequestCallException. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
214
			}
215
		}
216
217
		/* ================================================================= */
218
	}
219
220
	/**
221
	 * Tests the clearHeader() method.
222
	 *
223
	 * @return void
224
	 */
225
	public function testClearHeaders() {
226
227
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
228
229
		$obj->addHeader("name", "value");
230
		$this->assertCount(1, $obj->getHeaders());
231
232
		$obj->clearHeaders();
233
		$this->assertCount(0, $obj->getHeaders());
234
	}
235
236
	/**
237
	 * Tests the clearQueryData() method.
238
	 *
239
	 * @return void
240
	 */
241
	public function testClearQueryData() {
242
243
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
244
245
		$obj->addQueryData("name", "value");
246
		$this->assertCount(1, $obj->getQueryData());
247
248
		$obj->clearQueryData();
249
		$this->assertCount(0, $obj->getQueryData());
250
	}
251
252
	/**
253
	 * Tests removeHeader() method.
254
	 *
255
	 * @return void
256
	 */
257
	public function testRemoveHeader() {
258
259
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
260
261
		$obj->addHeader("name", "value");
262
		$this->assertCount(1, $obj->getHeaders());
263
264
		$obj->removeHeader("Name");
265
		$this->assertCount(1, $obj->getHeaders());
266
267
		$obj->removeHeader("name");
268
		$this->assertCount(0, $obj->getHeaders());
269
	}
270
271
	/**
272
	 * Tests removeQueryData() method.
273
	 *
274
	 * @return void
275
	 */
276
	public function testRemoveQueryData() {
277
278
		$obj = new CURLGetRequest($this->configuration, self::RESOURCE_PATH);
279
280
		$obj->addQueryData("name", "value");
281
		$this->assertCount(1, $obj->getQueryData());
282
283
		$obj->removeQueryData("Name");
284
		$this->assertCount(1, $obj->getQueryData());
285
286
		$obj->removeQueryData("name");
287
		$this->assertCount(0, $obj->getQueryData());
288
	}
289
290
}
291