Skip to content

Commit 5ae0b19

Browse files
author
Alexander Obuhovich
committed
Add tests for client classes
1 parent 9be9b50 commit 5ae0b19

File tree

10 files changed

+519
-41
lines changed

10 files changed

+519
-41
lines changed

.travis.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,18 @@ php:
1717
install:
1818
- composer install --prefer-dist
1919

20+
before_script:
21+
- echo "always_populate_raw_post_data = -1" >> /home/travis/.phpenv/versions/5.6.5/etc/php.ini
22+
- ~/.phpenv/versions/5.6/bin/php --ini
23+
- ~/.phpenv/versions/5.6/bin/php -S localhost:8000 -t $(pwd) > /dev/null 2> /tmp/webserver_output.txt &
24+
- export REPO_URL=http://localhost:8000/
25+
- curl -I http://localhost:8000/tests/debug_response.php/http_code/201/response_mode/empty/? || true
26+
- curl -I http://localhost:8000/tests/debug_response.php/http_code/201/response_mode/empty/ || true
27+
- curl -I http://localhost:8000/tests/debug_response.php/http_code/201/ || true
28+
- curl -I http://localhost:8000/tests/debug_response.php/ || true
29+
2030
script:
2131
- ./vendor/bin/phpunit
32+
33+
after_failure:
34+
- cat /tmp/webserver_output.txt

CONTRIBUTING.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ JIRA REST API Client is an open source, community-driven project. If you'd like
1515
7. Create Pull Request.
1616

1717
## Running the Tests
18-
Make sure that you don't break anything with your changes by running:
18+
19+
1. make sure repository is located in web server document root (or it's sub-folder)
20+
2. copy `phpunit.xml.dist` file into `phpunit.xml` file
21+
3. in the `phpunit.xml` file:
22+
* uncomment part, where `REPO_URL` environment variable is defined
23+
* set `REPO_URL` environment variable value to URL, from where repository can be accessed (e.g. `http://localhost/path/to/repository/`)
24+
4. run following command to make sure that you don't break anything with your changes:
1925

2026
```bash
2127
$> phpunit

phpunit.xml.dist

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
2-
<phpunit backupGlobals="true"
2+
<phpunit bootstrap="vendor/autoload.php"
3+
backupGlobals="true"
34
backupStaticAttributes="false"
45
colors="true"
56
convertErrorsToExceptions="true"
@@ -13,13 +14,17 @@
1314
syntaxCheck="true"
1415
strict="true"
1516
verbose="true">
16-
<php>
17-
<ini name="date.timezone" value="Asia/Tokyo" />
18-
</php>
17+
1918
<testsuites>
2019
<testsuite name="Jira_Api Test Suite">
2120
<directory>tests</directory>
2221
</testsuite>
2322
</testsuites>
2423

25-
</phpunit>
24+
<!--
25+
<php>
26+
<server name="REPO_URL" value="http://localhost/"/>
27+
</php>
28+
-->
29+
30+
</phpunit>

src/Jira/Api/Client/ClientInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727

2828
use chobie\Jira\Api\Authentication\AuthenticationInterface;
29+
use chobie\Jira\Api\Exception;
30+
use chobie\Jira\Api\UnauthorizedException;
2931

3032
interface ClientInterface
3133
{
@@ -42,6 +44,11 @@ interface ClientInterface
4244
* @param boolean $debug Debug this request.
4345
*
4446
* @return array|string
47+
* @throws \InvalidArgumentException When non-supported implementation of AuthenticationInterface is given.
48+
* @throws \InvalidArgumentException When data is not an array and http method is GET.
49+
* @throws Exception When request failed due communication error.
50+
* @throws UnauthorizedException When request failed, because user can't be authorized properly.
51+
* @throws Exception When there was empty response instead of needed data.
4552
*/
4653
public function sendRequest(
4754
$method,

src/Jira/Api/Client/CurlClient.php

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ public function __construct()
5353
* @param boolean $debug Debug this request.
5454
*
5555
* @return array|string
56-
* @throws \Exception When non-supported implementation of AuthenticationInterface is given.
57-
* @throws Exception When request failed due CURL error.
56+
* @throws \InvalidArgumentException When non-supported implementation of AuthenticationInterface is given.
57+
* @throws \InvalidArgumentException When data is not an array and http method is GET.
58+
* @throws Exception When request failed due communication error.
5859
* @throws UnauthorizedException When request failed, because user can't be authorized properly.
5960
* @throws Exception When there was empty response instead of needed data.
60-
* @throws \InvalidArgumentException When data is not an array and http method is GET.
6161
*/
6262
public function sendRequest(
6363
$method,
@@ -69,17 +69,20 @@ public function sendRequest(
6969
$debug = false
7070
) {
7171
if ( !($credential instanceof Basic) && !($credential instanceof Anonymous) ) {
72-
throw new \Exception(sprintf('CurlClient does not support %s authentication.', get_class($credential)));
72+
throw new \InvalidArgumentException(sprintf(
73+
'CurlClient does not support %s authentication.',
74+
get_class($credential)
75+
));
7376
}
7477

7578
$curl = curl_init();
7679

7780
if ( $method == 'GET' ) {
78-
$url .= '?' . http_build_query($data);
79-
8081
if ( !is_array($data) ) {
8182
throw new \InvalidArgumentException('Data must be an array.');
8283
}
84+
85+
$url .= '?' . http_build_query($data);
8386
}
8487

8588
curl_setopt($curl, CURLOPT_URL, $endpoint . $url);
@@ -96,7 +99,7 @@ public function sendRequest(
9699
curl_setopt($curl, CURLOPT_VERBOSE, $debug);
97100

98101
if ( $is_file ) {
99-
if ( defined('CURLOPT_SAFE_UPLOAD') ) {
102+
if ( defined('CURLOPT_SAFE_UPLOAD') && PHP_VERSION_ID < 70000 ) {
100103
curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
101104
}
102105

@@ -117,12 +120,12 @@ public function sendRequest(
117120
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
118121
}
119122
}
120-
elseif ( $method == 'PUT' ) {
121-
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
123+
elseif ( $method == 'PUT' || $method == 'DELETE' ) {
124+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
122125
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
123126
}
124127

125-
$data = curl_exec($curl);
128+
$response = curl_exec($curl);
126129

127130
$error_number = curl_errno($curl);
128131

@@ -139,15 +142,17 @@ public function sendRequest(
139142
throw new UnauthorizedException('Unauthorized');
140143
}
141144

142-
if ( $data === '' && !in_array($http_code, array(201, 204)) ) {
145+
if ( $response === '' && !in_array($http_code, array(201, 204)) ) {
143146
throw new Exception('JIRA Rest server returns unexpected result.');
144147
}
145148

146-
if ( is_null($data) ) {
149+
// @codeCoverageIgnoreStart
150+
if ( is_null($response) ) {
147151
throw new Exception('JIRA Rest server returns unexpected result.');
148152
}
153+
// @codeCoverageIgnoreEnd
149154

150-
return $data;
155+
return $response;
151156
}
152157

153158
/**
@@ -160,10 +165,10 @@ public function sendRequest(
160165
protected function getCurlValue($file_string)
161166
{
162167
if ( !function_exists('curl_file_create') ) {
163-
return $file_string . '; filename=' . basename($file_string);
168+
return $file_string . ';filename=' . basename($file_string);
164169
}
165170

166-
return curl_file_create(substr($file_string, 1), null, basename($file_string));
171+
return curl_file_create(substr($file_string, 1), '', basename($file_string));
167172
}
168173

169174
}

src/Jira/Api/Client/PHPClient.php

Lines changed: 81 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use chobie\Jira\Api\Authentication\AuthenticationInterface;
3030
use chobie\Jira\Api\Authentication\Basic;
3131
use chobie\Jira\Api\Exception;
32+
use chobie\Jira\Api\UnauthorizedException;
3233

3334
class PHPClient implements ClientInterface
3435
{
@@ -40,6 +41,13 @@ class PHPClient implements ClientInterface
4041
*/
4142
protected $httpsSupport = false;
4243

44+
/**
45+
* Last error message.
46+
*
47+
* @var string
48+
*/
49+
private $_lastErrorMessage = '';
50+
4351
/**
4452
* Create a traditional php client.
4553
*/
@@ -57,6 +65,8 @@ public function __construct()
5765
* Returns status of HTTP support.
5866
*
5967
* @return boolean
68+
*
69+
* @codeCoverageIgnore
6070
*/
6171
protected function isHttpsSupported()
6272
{
@@ -75,7 +85,12 @@ protected function isHttpsSupported()
7585
* @param boolean $debug Debug this request.
7686
*
7787
* @return array|string
78-
* @throws \Exception When non-supported implementation of AuthenticationInterface is given.
88+
* @throws \InvalidArgumentException When non-supported implementation of AuthenticationInterface is given.
89+
* @throws \InvalidArgumentException When data is not an array and http method is GET.
90+
* @throws Exception When request failed due communication error.
91+
* @throws UnauthorizedException When request failed, because user can't be authorized properly.
92+
* @throws Exception When there was empty response instead of needed data.
93+
* @throws \InvalidArgumentException When "https" wrapper is not available, but http:// is requested.
7994
*/
8095
public function sendRequest(
8196
$method,
@@ -87,7 +102,10 @@ public function sendRequest(
87102
$debug = false
88103
) {
89104
if ( !($credential instanceof Basic) && !($credential instanceof Anonymous) ) {
90-
throw new \Exception(sprintf('PHPClient does not support %s authentication.', get_class($credential)));
105+
throw new \InvalidArgumentException(sprintf(
106+
'PHPClient does not support %s authentication.',
107+
get_class($credential)
108+
));
91109
}
92110

93111
$header = array();
@@ -96,18 +114,18 @@ public function sendRequest(
96114
$header[] = 'Authorization: Basic ' . $credential->getCredential();
97115
}
98116

117+
if ( !$is_file ) {
118+
$header[] = 'Content-Type: application/json;charset=UTF-8';
119+
}
120+
99121
$context = array(
100122
'http' => array(
101123
'method' => $method,
102124
'header' => implode("\r\n", $header),
103125
),
104126
);
105127

106-
if ( !$is_file ) {
107-
$header[] = 'Content-Type: application/json;charset=UTF-8';
108-
}
109-
110-
if ( $method == 'POST' || $method == 'PUT' ) {
128+
if ( $method == 'POST' || $method == 'PUT' || $method == 'DELETE' ) {
111129
if ( $is_file ) {
112130
$filename = preg_replace('/^@/', '', $data['file']);
113131
$boundary = '--------------------------' . microtime(true);
@@ -129,41 +147,84 @@ public function sendRequest(
129147
$context['http']['header'] = implode("\r\n", $header);
130148
$context['http']['content'] = $__data;
131149
}
132-
else {
150+
elseif ( $method == 'GET' ) {
151+
if ( !is_array($data) ) {
152+
throw new \InvalidArgumentException('Data must be an array.');
153+
}
154+
133155
$url .= '?' . http_build_query($data);
134156
}
135157

158+
// @codeCoverageIgnoreStart
136159
if ( strpos($endpoint, 'https://') === 0 && !$this->isHttpsSupported() ) {
137-
throw new \Exception('does not support https wrapper. please enable openssl extension');
160+
throw new \InvalidArgumentException('does not support https wrapper. please enable openssl extension');
161+
}
162+
// @codeCoverageIgnoreEnd
163+
164+
list ($http_code, $response, $error_message) = $this->doSendRequest($endpoint . $url, $context);
165+
166+
// Check for 401 code before "$error_message" checking, because it's considered as an error.
167+
if ( $http_code == 401 ) {
168+
throw new UnauthorizedException('Unauthorized');
169+
}
170+
171+
if ( !empty($error_message) ) {
172+
throw new Exception(
173+
sprintf('Jira request failed: "%s"', $error_message)
174+
);
175+
}
176+
177+
if ( $response === '' && !in_array($http_code, array(201, 204)) ) {
178+
throw new Exception('JIRA Rest server returns unexpected result.');
138179
}
139180

181+
// @codeCoverageIgnoreStart
182+
if ( is_null($response) ) {
183+
throw new Exception('JIRA Rest server returns unexpected result.');
184+
}
185+
// @codeCoverageIgnoreEnd
186+
187+
return $response;
188+
}
189+
190+
/**
191+
* Sends the request.
192+
*
193+
* @param string $url URL.
194+
* @param array $context Context.
195+
*
196+
* @return array
197+
*/
198+
protected function doSendRequest($url, array $context)
199+
{
200+
$this->_lastErrorMessage = '';
201+
140202
set_error_handler(array($this, 'errorHandler'));
141-
$data = file_get_contents(
142-
$endpoint . $url,
143-
false,
144-
stream_context_create($context)
145-
);
203+
$response = file_get_contents($url, false, stream_context_create($context));
146204
restore_error_handler();
147205

148-
if ( is_null($data) ) {
149-
throw new \Exception('JIRA Rest server returns unexpected result.');
206+
if ( isset($http_response_header) ) {
207+
preg_match('#HTTP/\d+\.\d+ (\d+)#', $http_response_header[0], $matches);
208+
$http_code = $matches[1];
209+
}
210+
else {
211+
$http_code = 0;
150212
}
151213

152-
return $data;
214+
return array($http_code, $response, $this->_lastErrorMessage);
153215
}
154216

155217
/**
156-
* Throws exception on error.
218+
* Remembers last error.
157219
*
158220
* @param integer $errno Error number.
159221
* @param string $errstr Error message.
160222
*
161223
* @return void
162-
* @throws \Exception Always.
163224
*/
164225
public function errorHandler($errno, $errstr)
165226
{
166-
throw new \Exception($errstr);
227+
$this->_lastErrorMessage = $errstr;
167228
}
168229

169230
}

0 commit comments

Comments
 (0)