Working on tests for the Resource class.

Got a bunch more validation rules to port over.
This commit is contained in:
Josh Sherman 2014-09-28 09:47:54 -04:00
parent 3b8eddc7b5
commit 6c173cdc89
4 changed files with 188 additions and 171 deletions

View file

@ -87,13 +87,11 @@ class Resource extends Object
try try
{ {
// Determines if we need to serve over HTTP or HTTPS // Determines if we need to serve over HTTP or HTTPS
if ($this->https === true if (($this->https === true
|| (isset($this->https[$method]) && $this->https[$method])) || (isset($this->https[$method]) && $this->https[$method]))
&& (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == false))
{ {
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] == false) throw new \Exception('HTTPS is required.', 400);
{
throw new \Exception('SSL is required.', 400);
}
} }
// Check auth if flag is explicitly true or is true for the method // Check auth if flag is explicitly true or is true for the method
@ -201,37 +199,35 @@ class Resource extends Object
{ {
$rule = explode(':', $rule); $rule = explode(':', $rule);
switch (strtolower($rule[0])) switch ($rule[0])
{ {
// {{{ Checks using filter_var() // {{{ Checks using filter_var()
case 'filter': case 'filter':
if (count($rule) < 2) if (!isset($rule[1]))
{ {
throw new \Exception('Invalid validation rule, expected: "validate:boolean|email|float|int|ip|url".'); $rule[1] = false;
} }
else
switch ($rule[1])
{ {
switch (strtolower($rule[1])) case 'boolean':
{ case 'email':
case 'boolean': case 'float':
case 'email': case 'int':
case 'float': case 'ip':
case 'int': case 'url':
case 'ip': $filter = constant('FILTER_VALIDATE_' . strtoupper($rule[1]));
case 'url': break;
$filter = constant('FILTER_VALIDATE_' . strtoupper($rule[1]));
break;
default: default:
throw new \Exception('Invalid filter, expecting boolean, email, float, int, ip or url.'); throw new \Exception('Invalid filter, expecting boolean, email, float, int, ip or url.');
break; break;
} }
if (!filter_var($value, $filter)) if (!filter_var($value, $filter))
{ {
$this->errors[$variable][] = $message; $this->errors[$variable][] = $message;
}
} }
break; break;
@ -374,7 +370,16 @@ class Resource extends Object
} }
catch (\Exception $e) catch (\Exception $e)
{ {
throw $e; $code = $e->getCode();
// Anything below 200 is probably a PHP error
if ($code < 200)
{
$code = 500;
}
$this->status = $code;
$this->message = $e->getMessage();
} }
} }

View file

@ -1,69 +1,138 @@
<?php <?php
$_POST['field2'] = 'short'; namespace Resources\v1
$_GET['field2'] = 'short';
$_REQUEST['field2'] = 'short';
class MockParentResource extends Pickles\Resource
{ {
public $validate = [ class resource extends \Pickles\Resource
'field1',
'field2' => [
'length:<:10' => 'Too short',
'length:>:50' => 'Too long',
],
];
}
class MockChildResource extends MockParentResource
{
public $method = ['POST', 'GET'];
}
class ResourceTest extends PHPUnit_Framework_TestCase
{
public function testAutoRun()
{ {
$this->assertInstanceOf('Pickles\\Resource', new Pickles\Resource(true)); public $https = [
} 'POST' => true,
];
public function testAutoRunParentError() public $auth = [
{ 'DELETE' => true,
$this->expectOutputString(''); ];
$model = new MockChildResource(true);
}
public function testSetGetReturn() public $filter = [
{ 'GET' => [
$module = new Pickles\Resource(); 'foo' => 'trim',
$module->foo = 'bar'; 'bar' => 'password_hash',
$this->assertEquals('bar', $module->foo); ],
} ];
public function testGetMissing() public $validate = [
{ 'GET' => [
$module = new Pickles\Resource(); 'missing',
$this->assertFalse($module->missing); 'isBoolean' => ['filter:boolean' => 'Error'],
} 'isNotBoolean' => ['filter:boolean' => 'Error'],
'isEmail' => ['filter:email' => 'Error'],
'isNotEmail' => ['filter:email' => 'Error'],
'isFloat' => ['filter:float' => 'Error'],
'isNotFloat' => ['filter:float' => 'Error'],
'isInt' => ['filter:int' => 'Error'],
'isNotInt' => ['filter:int' => 'Error'],
'isIP' => ['filter:ip' => 'Error'],
'isNotIP' => ['filter:ip' => 'Error'],
'isURL' => ['filter:url' => 'Error'],
'isNotURL' => ['filter:url' => 'Error'],
'invalidRule' => ['filter' => 'Error'],
],
];
public function testValidateGet() public function GET()
{ {
$module = new MockParentResource(); return ['foo' => 'bar'];
$module->method = 'GET'; }
$this->assertEquals(['The field1 field is required.', 'Too long'], $module->__validate()); }
} }
public function testValidatePost() namespace
{ {
$module = new MockParentResource(); class ResourceTest extends PHPUnit_Framework_TestCase
$this->assertEquals(['The field1 field is required.', 'Too long'], $module->__validate()); {
} public function testFilterAndValidate()
{
public function testValidateRequest() $response = json_encode([
{ 'meta' => [
$module = new MockParentResource(); 'status' => 500,
$module->method = null; 'message' => 'Invalid filter, expecting boolean, email, float, int, ip or url.',
$this->assertEquals(['The field1 field is required.', 'Too long'], $module->__validate()); 'errors' => [
'missing' => ['The missing parameter is required.'],
'isNotBoolean' => ['Error'],
'isNotEmail' => ['Error'],
'isNotFloat' => ['Error'],
'isNotInt' => ['Error'],
'isNotIP' => ['Error'],
'isNotURL' => ['Error'],
],
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'GET';
$_REQUEST['request'] = 'v1/resource/1';
$_GET = [
'foo' => ' bar ',
'bar' => 'unencrypted',
'isBoolean' => true,
'isNotBoolean' => 'invalid',
'isEmail' => 'foo@bar.com',
'isNotEmail' => 'nope',
'isFloat' => 1.234567890,
'isNotFloat' => 'five',
'isInt' => 22381,
'isNotInt' => 'pretzel',
'isIP' => '127.0.0.1',
'isNotIP' => 'home',
'isURL' => 'http://joshtronic.com',
'isNotURL' => 'doubleUdoubleUdoubleUdot',
'invalidRule' => 'invalid',
];
new Pickles\Router();
$this->assertEquals('bar', $_GET['foo']);
$this->assertFalse('unencrypted' == $_GET['bar']);
}
public function testHTTPS()
{
$response = json_encode([
'meta' => [
'status' => 400,
'message' => 'HTTPS is required.',
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'POST';
$_REQUEST['request'] = 'v1/resource/1';
new Pickles\Router();
}
public function testAuthMisconfigured()
{
$response = json_encode([
'meta' => [
'status' => 401,
'message' => 'Authentication is not configured properly.',
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'DELETE';
$_REQUEST['request'] = 'v1/resource/1';
new Pickles\Router();
}
public function testValidation()
{
}
} }
} }

View file

@ -2,7 +2,7 @@
namespace Resources\v1 namespace Resources\v1
{ {
class resource extends \Pickles\Resource class router extends \Pickles\Resource
{ {
} }
@ -14,7 +14,14 @@ namespace
{ {
public function testServerError() public function testServerError()
{ {
$this->expectOutputRegex('/{"status":500,"message":"Undefined index: request"}/'); $response = json_encode([
'meta' => [
'status' => 500,
'message' => 'Undefined index: request',
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_METHOD'] = 'GET';
@ -23,22 +30,36 @@ namespace
public function testNotFound() public function testNotFound()
{ {
$this->expectOutputRegex('/{"status":404,"message":"Not Found."}/'); $response = json_encode([
'meta' => [
'status' => 404,
'message' => 'Not Found.',
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_METHOD'] = 'GET';
$_REQUEST['request'] = 'v1/test'; $_REQUEST['request'] = 'v1/doesnotexist';
new Pickles\Router(); new Pickles\Router();
} }
// We're just testing that the class can be loaded, not that it will // We're just testing that the class can be loaded, not that it will
// work. That logic is off in ResourceTest // work. That logic is off in ResourceTest
public function testFound() public function testFoundWithUID()
{ {
$this->expectOutputRegex('/{"status":405,"message":"Method not allowed."}/'); $response = json_encode([
'meta' => [
'status' => 405,
'message' => 'Method not allowed.',
],
]);
$this->expectOutputString($response);
$_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['REQUEST_METHOD'] = 'GET';
$_REQUEST['request'] = 'v1/resource/1'; $_REQUEST['request'] = 'v1/router/1';
new Pickles\Router(); new Pickles\Router();
} }

View file

@ -2,84 +2,6 @@
// class ValidateTest extends PHPUnit_Framework_TestCase // class ValidateTest extends PHPUnit_Framework_TestCase
// { // {
// public function testFilterBoolean()
// {
// $this->assertTrue(Validate::isValid(true, ['filter:boolean' => 'error']));
// }
//
// public function testFilterBooleanError()
// {
// $this->assertEquals(['error'], Validate::isValid(false, ['filter:boolean' => 'error']));
// }
//
// public function testFilterEmail()
// {
// $this->assertTrue(Validate::isValid('foo@bar.com', ['filter:email' => 'error']));
// }
//
// public function testFilterEmailError()
// {
// $this->assertEquals(['error'], Validate::isValid('invalid', ['filter:email' => 'error']));
// }
//
// public function testFilterFloat()
// {
// $this->assertTrue(Validate::isValid(2.231981, ['filter:float' => 'error']));
// }
//
// public function testFilterFloatError()
// {
// $this->assertEquals(['error'], Validate::isValid('invalid', ['filter:float' => 'error']));
// }
//
// public function testFilterInt()
// {
// $this->assertTrue(Validate::isValid(2231981, ['filter:int' => 'error']));
// }
//
// public function testFilterIntError()
// {
// $this->assertEquals(['error'], Validate::isValid('invalid', ['filter:int' => 'error']));
// }
//
// public function testFilterIP()
// {
// $this->assertTrue(Validate::isValid('2.23.19.81', ['filter:ip' => 'error']));
// }
//
// public function testFilterIPError()
// {
// $this->assertEquals(['error'], Validate::isValid('invalid', ['filter:ip' => 'error']));
// }
//
// public function testFilterURL()
// {
// $this->assertTrue(Validate::isValid('http://foo.com/bar?stuff', ['filter:url' => 'error']));
// }
//
// public function testFilterURLError()
// {
// $this->assertEquals(['error'], Validate::isValid('invalid', ['filter:url' => 'error']));
// }
//
// /**
// * @expectedException Exception
// * @expectedExceptionMessage Invalid validation rule, expected: "validate:boolean|email|float|int|ip|url".
// */
// public function testFilterVarInvalidRule()
// {
// Validate::isValid('value', ['filter' => 'foo']);
// }
//
// /**
// * @expectedException Exception
// * @expectedExceptionMessage Invalid filter, expecting boolean, email, float, int, ip or url.
// */
// public function testFilterVarInvalidFilter()
// {
// Validate::isValid('value', ['filter:foo' => 'bar']);
// }
//
// public function testLengthLessThan() // public function testLengthLessThan()
// { // {
// $this->assertTrue(Validate::isValid('value', ['length:<:10' => 'error'])); // $this->assertTrue(Validate::isValid('value', ['length:<:10' => 'error']));