Fix documentation and add tests for Response

This commit is contained in:
PJ Dietz 2014-07-13 23:56:19 -04:00
parent 581c3d1351
commit 794d0901b9
3 changed files with 253 additions and 37 deletions

View File

@ -33,6 +33,8 @@ class Response extends Message implements ResponseInterface
private $reasonPhrase; private $reasonPhrase;
/** @var int HTTP status code */ /** @var int HTTP status code */
private $statusCode; private $statusCode;
/** @var string HTTP protocol and version*/
private $protocol = "HTTP/1.1";
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@ -79,56 +81,64 @@ class Response extends Message implements ResponseInterface
} }
} }
/** @param string $bodyFilePath Path to a file to read and output as the body */ /**
* Provide the path to a file to output as the response body.
*
* @param string $bodyFilePath Filepath
*/
public function setBodyFilePath($bodyFilePath) public function setBodyFilePath($bodyFilePath)
{ {
$this->bodyFilePath = $bodyFilePath; $this->bodyFilePath = $bodyFilePath;
} }
/** @return string Path to a file to read and output as the body */ /**
* Return the path to the file to output as the response body.
*
* @return string Filepath
*/
public function getBodyFilePath() public function getBodyFilePath()
{ {
return $this->bodyFilePath; return $this->bodyFilePath;
} }
/** @return string Portion of the status line explaining the status. */ /**
* Return the portion of the status line explaining the status.
*
* @return string
*/
public function getReasonPhrase() public function getReasonPhrase()
{ {
return $this->reasonPhrase; return $this->reasonPhrase;
} }
/** /**
* Assign an explaination for the status code. Not normally needed. * Return true for status codes in the 1xx-3xx range.
* *
* @param string $statusCodeMessage * @return bool
*/ */
public function setReasonPhrase($statusCodeMessage)
{
$this->reasonPhrase = $statusCodeMessage;
}
/** @return bool True if the status code is in the 2xx range. */
public function getSuccess() public function getSuccess()
{ {
return $this->statusCode >= 200 && $this->statusCode < 300; return $this->statusCode < 400;
} }
/** @return int */ /**
* Return the HTTP status code for the response.
*
* @return int
*/
public function getStatusCode() public function getStatusCode()
{ {
return $this->statusCode; return $this->statusCode;
} }
/** @return string HTTP status line, e.g. HTTP/1.1 200 OK. */ /**
* Return the HTTP status line, e.g. HTTP/1.1 200 OK.
*
* @return string
*/
public function getStatusLine() public function getStatusLine()
{ {
return sprintf( return $this->protocol . " " . $this->statusCode . " " . $this->reasonPhrase;
'%s/%s %s %s',
strtoupper($this->protocol),
$this->protocolVersion,
$this->statusCode,
$this->reasonPhrase
);
} }
/** /**
@ -140,7 +150,7 @@ class Response extends Message implements ResponseInterface
*/ */
public function setStatusCode($statusCode, $reasonPhrase = null) public function setStatusCode($statusCode, $reasonPhrase = null)
{ {
$this->statusCode = (int)$statusCode; $this->statusCode = (int) $statusCode;
if (is_null($reasonPhrase)) { if (is_null($reasonPhrase)) {
@ -179,7 +189,7 @@ class Response extends Message implements ResponseInterface
$text = 'Moved Permanently'; $text = 'Moved Permanently';
break; break;
case 302: case 302:
$text = 'Moved Temporarily'; $text = 'Found';
break; break;
case 303: case 303:
$text = 'See Other'; $text = 'See Other';
@ -215,7 +225,7 @@ class Response extends Message implements ResponseInterface
$text = 'Proxy Authentication Required'; $text = 'Proxy Authentication Required';
break; break;
case 408: case 408:
$text = 'Request Time-out'; $text = 'Request Timeout';
break; break;
case 409: case 409:
$text = 'Conflict'; $text = 'Conflict';
@ -233,7 +243,7 @@ class Response extends Message implements ResponseInterface
$text = 'Request Entity Too Large'; $text = 'Request Entity Too Large';
break; break;
case 414: case 414:
$text = 'Request-URI Too Large'; $text = 'Request-URI Too Long';
break; break;
case 415: case 415:
$text = 'Unsupported Media Type'; $text = 'Unsupported Media Type';
@ -251,10 +261,10 @@ class Response extends Message implements ResponseInterface
$text = 'Service Unavailable'; $text = 'Service Unavailable';
break; break;
case 504: case 504:
$text = 'Gateway Time-out'; $text = 'Gateway Timeout';
break; break;
case 505: case 505:
$text = 'HTTP Version not supported'; $text = 'HTTP Version Not Supported';
break; break;
default: default:
$text = 'Nonstandard'; $text = 'Nonstandard';
@ -306,14 +316,12 @@ class Response extends Message implements ResponseInterface
private function outputBodyFile() private function outputBodyFile()
{ {
$handle = fopen($this->getBodyFilePath(), 'rb'); $handle = fopen($this->getBodyFilePath(), 'rb');
if ($handle === false) { if ($handle !== false) {
return; while (!feof($handle)) {
} $buffer = fread($handle, self::CHUNK_SIZE);
while (!feof($handle)) { print $buffer;
$buffer = fread($handle, self::CHUNK_SIZE); flush();
print $buffer; }
ob_flush();
flush();
} }
} }
} }

View File

@ -240,6 +240,25 @@ class RequestBuilderTest extends \PHPUnit_Framework_TestCase
); );
} }
/**
* @dataProvider defaultPortProvider
*/
public function testDefaultPort($scheme, $port)
{
$rqst = new Request("http://localhost:9999");
$rqst->setScheme($scheme);
$rqst->setPort();
$this->assertEquals($port, $rqst->getPort());
}
public function defaultPortProvider()
{
return [
["http", 80],
["https", 443]
];
}
/** /**
* @dataProvider invalidSchemeProvider * @dataProvider invalidSchemeProvider
* @expectedException \UnexpectedValueException * @expectedException \UnexpectedValueException
@ -516,9 +535,9 @@ class RequestBuilderTest extends \PHPUnit_Framework_TestCase
{ {
return [ return [
["http://localhost:9991", [ ["http://localhost:9991", [
CURLOPT_FAILONERROR, true CURLOPT_FAILONERROR, true,
CURLOPT_TIMEOUT_MS, 10
]], ]],
]; ];
} }
} }

189
test/ResponseTest.php Normal file
View File

@ -0,0 +1,189 @@
<?php
use pjdietz\WellRESTed\Request;
use pjdietz\WellRESTed\Response;
use pjdietz\WellRESTed\Test;
class ResponseBuilderTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
ob_start();
}
public function tearDown()
{
ob_clean();
ob_end_clean();
}
public function testConstructor()
{
$resp = new Response(200, "This is the body", array("Content-type" => "text/plain"));
}
/**
* @dataProvider statusCodeProvider
*/
public function testStatusLine($statusCode, $reasonPhrase, $statusLine)
{
$resp = new Response();
$resp->setStatusCode($statusCode, $reasonPhrase);
$this->assertEquals($statusLine, $resp->getStatusLine());
}
/**
* @dataProvider statusCodeProvider
*/
public function testReasonPhrase($statusCode, $reasonPhrase, $statusLine)
{
$resp = new Response();
$resp->setStatusCode($statusCode, $reasonPhrase);
$this->assertEquals(substr($statusLine, 13), $resp->getReasonPhrase());
}
/**
* @dataProvider statusCodeProvider
*/
public function testSuccess($statusCode, $reasonPhrase, $statusLine)
{
$resp = new Response();
$resp->setStatusCode($statusCode, $reasonPhrase);
if ($statusCode < 400) {
$this->assertTrue($resp->getSuccess());
} else {
$this->assertFalse($resp->getSuccess());
}
}
public function statusCodeProvider()
{
return [
[100, null, "HTTP/1.1 100 Continue"],
[101, null, "HTTP/1.1 101 Switching Protocols"],
[200, null, "HTTP/1.1 200 OK"],
[201, null, "HTTP/1.1 201 Created"],
[202, null, "HTTP/1.1 202 Accepted"],
[203, null, "HTTP/1.1 203 Non-Authoritative Information"],
[204, null, "HTTP/1.1 204 No Content"],
[205, null, "HTTP/1.1 205 Reset Content"],
[206, null, "HTTP/1.1 206 Partial Content"],
[300, null, "HTTP/1.1 300 Multiple Choices"],
[301, null, "HTTP/1.1 301 Moved Permanently"],
[302, null, "HTTP/1.1 302 Found"],
[303, null, "HTTP/1.1 303 See Other"],
[304, null, "HTTP/1.1 304 Not Modified"],
[305, null, "HTTP/1.1 305 Use Proxy"],
[400, null, "HTTP/1.1 400 Bad Request"],
[401, null, "HTTP/1.1 401 Unauthorized"],
[402, null, "HTTP/1.1 402 Payment Required"],
[403, null, "HTTP/1.1 403 Forbidden"],
[404, null, "HTTP/1.1 404 Not Found"],
[405, null, "HTTP/1.1 405 Method Not Allowed"],
[406, null, "HTTP/1.1 406 Not Acceptable"],
[407, null, "HTTP/1.1 407 Proxy Authentication Required"],
[408, null, "HTTP/1.1 408 Request Timeout"],
[409, null, "HTTP/1.1 409 Conflict"],
[410, null, "HTTP/1.1 410 Gone"],
[411, null, "HTTP/1.1 411 Length Required"],
[412, null, "HTTP/1.1 412 Precondition Failed"],
[413, null, "HTTP/1.1 413 Request Entity Too Large"],
[414, null, "HTTP/1.1 414 Request-URI Too Long"],
[415, null, "HTTP/1.1 415 Unsupported Media Type"],
[500, null, "HTTP/1.1 500 Internal Server Error"],
[501, null, "HTTP/1.1 501 Not Implemented"],
[502, null, "HTTP/1.1 502 Bad Gateway"],
[503, null, "HTTP/1.1 503 Service Unavailable"],
[504, null, "HTTP/1.1 504 Gateway Timeout"],
[505, null, "HTTP/1.1 505 HTTP Version Not Supported"],
[598, null, "HTTP/1.1 598 Nonstandard"],
[599, "Smelly", "HTTP/1.1 599 Smelly"]
];
}
/**
* @dataProvider invalidReasonPhraseProvider
* @expectedException \InvalidArgumentException
*/
public function testInvalidReasonPhrase($statusCode, $reasonPhrase)
{
$resp = new Response();
$resp->setStatusCode($statusCode, $reasonPhrase);
}
public function invalidReasonPhraseProvider()
{
return [
[599, false],
["100", true],
["*", []]
];
}
public function testBodyFile()
{
$path = tempnam(sys_get_temp_dir(), "TST");
$resp = new Response();
$resp->setBodyFilePath($path);
$this->assertEquals($path, $resp->getBodyFilePath());
unlink($path);
}
public function testRespondBodyFile()
{
$path = tempnam(sys_get_temp_dir(), "TST");
$body = "This is the body";
$f = fopen($path, "w");
fwrite($f, $body);
fclose($f);
$resp = new Response();
$resp->setStatusCode(200);
$resp->setBodyFilePath($path);
ob_start();
ob_clean();
@$resp->respond();
$captured = ob_get_contents();
ob_end_clean();
unlink($path);
$this->assertEquals($captured, $body);
}
public function testMissingRespondBodyFile()
{
$path = tempnam(sys_get_temp_dir(), "TST");
$resp = new Response();
$resp->setStatusCode(200);
$resp->setBodyFilePath($path);
unlink($path);
ob_start();
ob_clean();
@$resp->respond();
$captured = ob_get_contents();
ob_end_clean();
$this->assertEquals("", $captured);
}
public function testRespondBody()
{
$body = "This is the body";
$resp = new Response(200, $body, array("Content-type" => "text/plain"));
ob_start();
@$resp->respond();
$captured = ob_get_contents();
ob_end_clean();
$this->assertEquals($body, $captured);
}
}