diff --git a/library/Barberry/Application.php b/library/Barberry/Application.php index 59c6faa..54e8ecf 100644 --- a/library/Barberry/Application.php +++ b/library/Barberry/Application.php @@ -9,9 +9,19 @@ class Application */ private $resources; - public function __construct(Config $config, Filter\FilterInterface $filter = null) + /** + * @var RequestSource + */ + private $requestSource; + + public function __construct(Config $config, Filter\FilterInterface $filter = null, RequestSource $requestSource = null) { - $this->resources = new Resources($config, $filter); + if (is_null($requestSource)) { + $requestSource = new RequestSource(); + } + $this->requestSource = $requestSource; + + $this->resources = new Resources($config, $requestSource, $filter); } /** @@ -22,7 +32,7 @@ public function run() $controller = new Controller($this->resources->request(), $this->resources->storage(), new Direction\Factory()); try { - $response = $controller->{$_SERVER['REQUEST_METHOD']}(); + $response = $controller->{$this->requestSource->_SERVER['REQUEST_METHOD']}(); $this->invokeCache($response); return $response; @@ -41,9 +51,9 @@ public function run() private function invokeCache(Response $response) { - if('GET' == strtoupper($_SERVER['REQUEST_METHOD'])) { + if('GET' == strtoupper($this->requestSource->_SERVER['REQUEST_METHOD'])) { $this->resources->cache()->save($response->body, $this->resources->request()); - } elseif('DELETE' == strtoupper($_SERVER['REQUEST_METHOD'])) { + } elseif('DELETE' == strtoupper($this->requestSource->_SERVER['REQUEST_METHOD'])) { $this->resources->cache()->invalidate($this->resources->request()); } } diff --git a/library/Barberry/PostedFile/Collection.php b/library/Barberry/PostedFile/Collection.php index 9d479a0..5a465ef 100644 --- a/library/Barberry/PostedFile/Collection.php +++ b/library/Barberry/PostedFile/Collection.php @@ -133,8 +133,8 @@ public function unshift($offset, \Barberry\PostedFile $value) { } } - protected function readTempFile($filepath) { - if (is_uploaded_file($filepath)) { + protected function readTempFile($filepath, $trusted) { + if (is_uploaded_file($filepath) || $trusted === true) { return file_get_contents($filepath); } return null; @@ -147,8 +147,9 @@ private function getPostedFile($key) { $spec = $this->specsIterator[$key]; if (is_array($spec)) { + $trusted = (array_key_exists('trusted', $spec) && $spec['trusted'] === true)?:false; $this->specsIterator[$key] = new \Barberry\PostedFile( - $this->readTempFile($spec['tmp_name']), + $this->readTempFile($spec['tmp_name'], $trusted), $spec['name'] ); } diff --git a/library/Barberry/RequestSource.php b/library/Barberry/RequestSource.php new file mode 100644 index 0000000..3fa6560 --- /dev/null +++ b/library/Barberry/RequestSource.php @@ -0,0 +1,55 @@ +setDefaultValues(); + + foreach ($propertiesToOverride as $key => $value) { + if (property_exists($this, $key) && (gettype($value) === gettype($this->$key))) { + $this->$key = $value; + } + } + + } + + public function __get($property) { + if (property_exists($this, $property)) { + return $this->{$property}; + } + trigger_error('Undefined property via __get(): ' . $property, E_USER_NOTICE); + return null; + } + + private function setDefaultValues() + { + $this->_SERVER = array_merge( + array( + 'REQUEST_METHOD' => 'GET', + 'REQUEST_URI' => '/', + ), + $_SERVER + ); + $this->_FILES = $_FILES; + $this->_POST = $_POST; + } + +} diff --git a/library/Barberry/Resources.php b/library/Barberry/Resources.php index 0b3b5b6..52b5919 100644 --- a/library/Barberry/Resources.php +++ b/library/Barberry/Resources.php @@ -19,14 +19,21 @@ class Resources */ private $filter; + /** + * @var RequestSource + */ + private $requestSource; + + /** * @param Config $config * @param Filter\FilterInterface $filter */ - public function __construct(Config $config, Filter\FilterInterface $filter = null) + public function __construct(Config $config, RequestSource $requestSource, Filter\FilterInterface $filter = null) { $this->config = $config; $this->filter = $filter; + $this->requestSource = $requestSource; } /** @@ -68,8 +75,10 @@ public function request() function () use ($filter) { $dp = new PostedDataProcessor($filter); return new Request( - array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : '/', - $dp->process($_FILES, $_POST) + array_key_exists('REQUEST_URI', $this->requestSource->_SERVER) + ? $this->requestSource->_SERVER['REQUEST_URI'] + : '/', + $dp->process($this->requestSource->_FILES, $this->requestSource->_POST) ); } ); diff --git a/library/Barberry/Test/Data.php b/library/Barberry/Test/Data.php index 752ca26..cd4f778 100644 --- a/library/Barberry/Test/Data.php +++ b/library/Barberry/Test/Data.php @@ -34,4 +34,12 @@ public static function odsSpreadsheet() { public static function pdfDocument() { return file_get_contents(__DIR__ . '/data/sample.pdf'); } + + public static function gif1x1Path() { + return __DIR__ . '/data/1x1.gif'; + } + + public static function pdfDocumentPath() { + return __DIR__ . '/data/sample.pdf'; + } } diff --git a/test/integration/ApplicationTest.php b/test/integration/ApplicationTest.php index 715dcac..81102c1 100644 --- a/test/integration/ApplicationTest.php +++ b/test/integration/ApplicationTest.php @@ -6,8 +6,6 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase public function testCanRun() { - $_SERVER['REQUEST_METHOD'] = 'GET'; - $a = new Application(new Config(__DIR__)); $this->assertInstanceOf('Barberry\\Response', $a->run()); } diff --git a/test/phpunit.xml b/test/phpunit.xml index ae202d5..7edd892 100644 --- a/test/phpunit.xml +++ b/test/phpunit.xml @@ -8,7 +8,6 @@ convertWarningsToExceptions="true" forceCoversAnnotation="false" mapTestClassNameToCoveredClassName="false" - printerClass="PHPUnit_TextUI_ResultPrinter" processIsolation="false" stopOnError="true" stopOnFailure="true" diff --git a/test/unit/ConfigTest.php b/test/unit/ConfigTest.php index 72aaef1..63102aa 100644 --- a/test/unit/ConfigTest.php +++ b/test/unit/ConfigTest.php @@ -3,7 +3,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase { - public function testOptionsCanBeOverriden() { + public function testOptionsCanBeOverridden() { $config = new Config(__DIR__, '/test_config.php'); $this->assertEquals('/usr/another/storage', $config->directoryStorage); } diff --git a/test/unit/PostedFile/CollectionTest.php b/test/unit/PostedFile/CollectionTest.php index f2690a6..6b819b0 100644 --- a/test/unit/PostedFile/CollectionTest.php +++ b/test/unit/PostedFile/CollectionTest.php @@ -107,6 +107,11 @@ public function testCanBeCreatedWithPostedFilesInConstructor() { $this->assertEquals(Test\Data::gif1x1(), $collection['file']->bin); } + public function testCanReadTrustedTempFile() { + $collection = new Collection(array('file' => $this->goodTrustedFileInPhpFilesArray())); + $this->assertEquals(Test\Data::gif1x1(), $collection['file']->bin); + } + //-------------------------------------------------------------------------------------------------- private static function goodFileInPhpFilesArray() { @@ -134,6 +139,16 @@ private static function badFileInPhpFilesArray() { ); } + private static function goodTrustedFileInPhpFilesArray() { + return array( + 'size' => 43, + 'tmp_name' => Test\Data::gif1x1Path(), + 'error' => UPLOAD_ERR_OK, + 'name' => 'Name of a file.txt', + 'trusted' => true, + ); + } + private function partiallyMockedEmptyCollection(array $specs = null) { if ($specs === null) { $specs = array('file' => self::goodFileInPhpFilesArray()); diff --git a/test/unit/RequestSourceTest.php b/test/unit/RequestSourceTest.php new file mode 100644 index 0000000..e0566eb --- /dev/null +++ b/test/unit/RequestSourceTest.php @@ -0,0 +1,73 @@ +assertEquals(true, property_exists($requestSource, '_SERVER')); + } + + public function testServerPropertyHasArrayType() { + $requestSource = new RequestSource(); + $this->assertInternalType('array', $requestSource->_SERVER); + } + + public function testHavePostProperty() { + $requestSource = new RequestSource(); + $this->assertEquals(true, property_exists($requestSource, '_POST')); + } + + public function testPostPropertyHasArrayType() { + $requestSource = new RequestSource(); + $this->assertInternalType('array', $requestSource->_POST); + } + + public function testHaveFilesProperty() { + $requestSource = new RequestSource(); + $this->assertEquals(true, property_exists($requestSource, '_FILES')); + } + + public function testFilesPropertyHasArrayType() { + $requestSource = new RequestSource(); + $this->assertInternalType('array', $requestSource->_FILES); + } + + public function testPropertiesOverriddenOnlyIfHaveSameAsDefaultType() { + $requestSource = new RequestSource(array( + '_SERVER' => null, + )); + $this->assertInternalType(gettype($_SERVER), $requestSource->_SERVER); + } + + public function testHaveProperServerKeys() { + $requestSource = new RequestSource(); + $haveAllKeys = array_reduce( + $this->serverKeys(), + function($result, $propertyKey) use ($requestSource) { + $result = $result && array_key_exists($propertyKey, $requestSource->_SERVER); + return $result; + }, + true + ); + + $this->assertEquals(true, $haveAllKeys); + } + + public function testPropertiesCanBeOverridden() { + $requestSource = new RequestSource(array( + '_SERVER' => array( + 'REQUEST_URI' => '/some/url' + ), + )); + $this->assertEquals('/some/url', $requestSource->_SERVER['REQUEST_URI']); + } + + protected function serverKeys() { + return array( + 'REQUEST_METHOD', + 'REQUEST_URI', + ); + } + +} diff --git a/test/unit/ResourceTest.php b/test/unit/ResourceTest.php index 89d47ac..30bcb0f 100644 --- a/test/unit/ResourceTest.php +++ b/test/unit/ResourceTest.php @@ -31,6 +31,6 @@ public function testPassesDataFilterToPostedDataProcessor() { //-------------------------------------------------------------------------------------------------- private static function r(Filter\FilterInterface $filter = null) { - return new Resources(new Config(__DIR__), $filter); + return new Resources(new Config(__DIR__), new RequestSource(), $filter); } }