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;
/** @var int HTTP status code */
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)
{
$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()
{
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()
{
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()
{
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()
{
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()
{
return sprintf(
'%s/%s %s %s',
strtoupper($this->protocol),
$this->protocolVersion,
$this->statusCode,
$this->reasonPhrase
);
return $this->protocol . " " . $this->statusCode . " " . $this->reasonPhrase;
}
/**
@ -140,7 +150,7 @@ class Response extends Message implements ResponseInterface
*/
public function setStatusCode($statusCode, $reasonPhrase = null)
{
$this->statusCode = (int)$statusCode;
$this->statusCode = (int) $statusCode;
if (is_null($reasonPhrase)) {
@ -179,7 +189,7 @@ class Response extends Message implements ResponseInterface
$text = 'Moved Permanently';
break;
case 302:
$text = 'Moved Temporarily';
$text = 'Found';
break;
case 303:
$text = 'See Other';
@ -215,7 +225,7 @@ class Response extends Message implements ResponseInterface
$text = 'Proxy Authentication Required';
break;
case 408:
$text = 'Request Time-out';
$text = 'Request Timeout';
break;
case 409:
$text = 'Conflict';
@ -233,7 +243,7 @@ class Response extends Message implements ResponseInterface
$text = 'Request Entity Too Large';
break;
case 414:
$text = 'Request-URI Too Large';
$text = 'Request-URI Too Long';
break;
case 415:
$text = 'Unsupported Media Type';
@ -251,10 +261,10 @@ class Response extends Message implements ResponseInterface
$text = 'Service Unavailable';
break;
case 504:
$text = 'Gateway Time-out';
$text = 'Gateway Timeout';
break;
case 505:
$text = 'HTTP Version not supported';
$text = 'HTTP Version Not Supported';
break;
default:
$text = 'Nonstandard';
@ -306,14 +316,12 @@ class Response extends Message implements ResponseInterface
private function outputBodyFile()
{
$handle = fopen($this->getBodyFilePath(), 'rb');
if ($handle === false) {
return;
}
while (!feof($handle)) {
$buffer = fread($handle, self::CHUNK_SIZE);
print $buffer;
ob_flush();
flush();
if ($handle !== false) {
while (!feof($handle)) {
$buffer = fread($handle, self::CHUNK_SIZE);
print $buffer;
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
* @expectedException \UnexpectedValueException
@ -516,9 +535,9 @@ class RequestBuilderTest extends \PHPUnit_Framework_TestCase
{
return [
["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);
}
}