[Pkg-owncloud-commits] [owncloud] 42/172: implement most of the basic stuff that was suggested in #8290
David Prévot
taffit at moszumanska.debian.org
Sun May 18 20:09:38 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository owncloud.
commit 80648da43197c91ed52f36cee8bc818038b88eb6
Author: Bernhard Posselt <dev at bernhard-posselt.com>
Date: Tue May 6 16:29:19 2014 +0200
implement most of the basic stuff that was suggested in #8290
---
.../dependencyinjection/dicontainer.php | 16 +-
lib/private/appframework/http/dispatcher.php | 88 ++++++++++-
.../middleware/security/securitymiddleware.php | 16 +-
...ionreader.php => controllermethodreflector.php} | 46 +++++-
lib/public/appframework/controller.php | 65 ++++++++
.../appframework/http/iresponseserializer.php | 36 +----
lib/public/appframework/http/templateresponse.php | 10 +-
.../lib/appframework/controller/ControllerTest.php | 55 ++++++-
tests/lib/appframework/http/DispatcherTest.php | 164 +++++++++++++++++++--
.../lib/appframework/http/TemplateResponseTest.php | 46 ++----
.../middleware/security/SecurityMiddlewareTest.php | 33 +++--
.../utility/ControllerMethodReflectorTest.php | 115 +++++++++++++++
12 files changed, 585 insertions(+), 105 deletions(-)
diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php
index becd755..c6139df 100644
--- a/lib/private/appframework/dependencyinjection/dicontainer.php
+++ b/lib/private/appframework/dependencyinjection/dicontainer.php
@@ -33,6 +33,7 @@ use OC\AppFramework\Middleware\Security\SecurityMiddleware;
use OC\AppFramework\Middleware\Security\CORSMiddleware;
use OC\AppFramework\Utility\SimpleContainer;
use OC\AppFramework\Utility\TimeFactory;
+use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\IApi;
use OCP\AppFramework\IAppContainer;
use OCP\AppFramework\Middleware;
@@ -81,7 +82,11 @@ class DIContainer extends SimpleContainer implements IAppContainer{
});
$this['Dispatcher'] = $this->share(function($c) {
- return new Dispatcher($c['Protocol'], $c['MiddlewareDispatcher']);
+ return new Dispatcher(
+ $c['Protocol'],
+ $c['MiddlewareDispatcher'],
+ $c['ControllerMethodReflector']
+ );
});
@@ -90,7 +95,11 @@ class DIContainer extends SimpleContainer implements IAppContainer{
*/
$app = $this;
$this['SecurityMiddleware'] = $this->share(function($c) use ($app){
- return new SecurityMiddleware($app, $c['Request']);
+ return new SecurityMiddleware(
+ $app,
+ $c['Request'],
+ $c['ControllerMethodReflector']
+ );
});
$this['CORSMiddleware'] = $this->share(function($c) {
@@ -118,6 +127,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{
return new TimeFactory();
});
+ $this['ControllerMethodReflector'] = $this->share(function($c) {
+ return new ControllerMethodReflector();
+ });
}
diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php
index a2afb53..532e495 100644
--- a/lib/private/appframework/http/dispatcher.php
+++ b/lib/private/appframework/http/dispatcher.php
@@ -26,7 +26,11 @@ namespace OC\AppFramework\Http;
use \OC\AppFramework\Middleware\MiddlewareDispatcher;
use \OC\AppFramework\Http;
+use \OC\AppFramework\Utility\ControllerMethodReflector;
+
use OCP\AppFramework\Controller;
+use OCP\AppFramework\Http\Response;
+use OCP\IRequest;
/**
@@ -36,17 +40,25 @@ class Dispatcher {
private $middlewareDispatcher;
private $protocol;
-
+ private $reflector;
+ private $request;
/**
* @param Http $protocol the http protocol with contains all status headers
* @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which
* runs the middleware
+ * @param ControllerMethodReflector the reflector that is used to inject
+ * the arguments for the controller
+ * @param IRequest $request the incoming request
*/
public function __construct(Http $protocol,
- MiddlewareDispatcher $middlewareDispatcher) {
+ MiddlewareDispatcher $middlewareDispatcher,
+ ControllerMethodReflector $reflector,
+ IRequest $request) {
$this->protocol = $protocol;
$this->middlewareDispatcher = $middlewareDispatcher;
+ $this->reflector = $reflector;
+ $this->request = $request;
}
@@ -63,10 +75,13 @@ class Dispatcher {
$out = array(null, array(), null);
try {
+ // prefill reflector with everything thats needed for the
+ // middlewares
+ $this->reflector->reflect($controller, $methodName);
$this->middlewareDispatcher->beforeController($controller,
$methodName);
- $response = $controller->$methodName();
+ $response = $this->executeController($controller, $methodName);
// if an exception appears, the middleware checks if it can handle the
// exception and creates a response. If no response is created, it is
@@ -98,4 +113,71 @@ class Dispatcher {
}
+ /**
+ * Uses the reflected parameters, types and request parameters to execute
+ * the controller
+ * @return Response
+ */
+ private function executeController($controller, $methodName) {
+ $arguments = array();
+
+ // valid types that will be casted
+ $types = array('int', 'integer', 'bool', 'boolean', 'float');
+
+ foreach($this->reflector->getParameters() as $param) {
+
+ // try to get the parameter from the request object and cast
+ // it to the type annotated in the @param annotation
+ $value = $this->request->getParam($param);
+ $type = $this->reflector->getType($param);
+
+ // if this is submitted using GET or a POST form, 'false' should be
+ // converted to false
+ if(($type === 'bool' || $type === 'boolean') &&
+ $value === 'false' &&
+ (
+ $this->request->method === 'GET' ||
+ (
+ $this->request->method === 'POST' &&
+ strpos($this->request->getHeader('Content-Type'),
+ 'application/x-www-form-urlencoded') !== false
+ )
+ )
+ ) {
+ $value = false;
+
+ } elseif(in_array($type, $types)) {
+ settype($value, $type);
+ }
+
+ $arguments[] = $value;
+ }
+
+ $response = call_user_func_array(array($controller, $methodName), $arguments);
+
+ // format response if not of type response
+ if(!($response instanceof Response)) {
+
+ // get format from the url format or request format parameter
+ $format = $this->request->getParam('format');
+
+ // if none is given try the first Accept header
+ if($format === null) {
+ $header = $this->request->getHeader('Accept');
+ $formats = explode(',', $header);
+
+ if($header !== null && count($formats) > 0) {
+ $accept = strtolower(trim($formats[0]));
+ $format = str_replace('application/', '', $accept);
+ } else {
+ $format = 'json';
+ }
+ }
+
+ $response = $controller->formatResponse($response, $format);
+ }
+
+ return $response;
+ }
+
}
diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php
index 0f160d2..b4ace5d 100644
--- a/lib/private/appframework/middleware/security/securitymiddleware.php
+++ b/lib/private/appframework/middleware/security/securitymiddleware.php
@@ -25,7 +25,7 @@
namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Http;
-use OC\AppFramework\Utility\MethodAnnotationReader;
+use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Middleware;
use OCP\AppFramework\Http\Response;
@@ -55,10 +55,13 @@ class SecurityMiddleware extends Middleware {
/**
* @param IAppContainer $app
* @param IRequest $request
+ * @param ControllerMethodReflector $reflector
*/
- public function __construct(IAppContainer $app, IRequest $request){
+ public function __construct(IAppContainer $app, IRequest $request,
+ ControllerMethodReflector $reflector){
$this->app = $app;
$this->request = $request;
+ $this->reflector = $reflector;
}
@@ -72,28 +75,25 @@ class SecurityMiddleware extends Middleware {
*/
public function beforeController($controller, $methodName){
- // get annotations from comments
- $annotationReader = new MethodAnnotationReader($controller, $methodName);
-
// this will set the current navigation entry of the app, use this only
// for normal HTML requests and not for AJAX requests
$this->app->getServer()->getNavigationManager()->setActiveEntry($this->app->getAppName());
// security checks
- $isPublicPage = $annotationReader->hasAnnotation('PublicPage');
+ $isPublicPage = $this->reflector->hasAnnotation('PublicPage');
if(!$isPublicPage) {
if(!$this->app->isLoggedIn()) {
throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED);
}
- if(!$annotationReader->hasAnnotation('NoAdminRequired')) {
+ if(!$this->reflector->hasAnnotation('NoAdminRequired')) {
if(!$this->app->isAdminUser()) {
throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN);
}
}
}
- if(!$annotationReader->hasAnnotation('NoCSRFRequired')) {
+ if(!$this->reflector->hasAnnotation('NoCSRFRequired')) {
if(!$this->request->passesCSRFCheck()) {
throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED);
}
diff --git a/lib/private/appframework/utility/methodannotationreader.php b/lib/private/appframework/utility/controllermethodreflector.php
similarity index 59%
rename from lib/private/appframework/utility/methodannotationreader.php
rename to lib/private/appframework/utility/controllermethodreflector.php
index 42060a0..d6209ca 100644
--- a/lib/private/appframework/utility/methodannotationreader.php
+++ b/lib/private/appframework/utility/controllermethodreflector.php
@@ -28,23 +28,59 @@ namespace OC\AppFramework\Utility;
/**
* Reads and parses annotations from doc comments
*/
-class MethodAnnotationReader {
+class ControllerMethodReflector {
private $annotations;
+ private $types;
+ private $parameters;
+
+ public function __construct() {
+ $this->types = array();
+ $this->parameters = array();
+ $this->annotations = array();
+ }
+
/**
* @param object $object an object or classname
- * @param string $method the method which we want to inspect for annotations
+ * @param string $method the method which we want to inspect
*/
- public function __construct($object, $method){
- $this->annotations = array();
-
+ public function reflect($object, $method){
$reflection = new \ReflectionMethod($object, $method);
$docs = $reflection->getDocComment();
// extract everything prefixed by @ and first letter uppercase
preg_match_all('/@([A-Z]\w+)/', $docs, $matches);
$this->annotations = $matches[1];
+
+ // extract type parameter information
+ preg_match_all('/@param (?<type>\w+) \$(?<var>\w+)/', $docs, $matches);
+ $this->types = array_combine($matches['var'], $matches['type']);
+
+ // get method parameters
+ foreach ($reflection->getParameters() as $param) {
+ $this->parameters[] = $param->name;
+ }
+ }
+
+
+ /**
+ * Inspects the PHPDoc parameters for types
+ * @param strint $parameter the parameter whose type comments should be
+ * parsed
+ * @return string type in the type parameters (@param int $something) would
+ * return int
+ */
+ public function getType($parameter) {
+ return $this->types[$parameter];
+ }
+
+
+ /**
+ * @return array the arguments of the method
+ */
+ public function getParameters() {
+ return $this->parameters;
}
diff --git a/lib/public/appframework/controller.php b/lib/public/appframework/controller.php
index f42eba1..f28a1d8 100644
--- a/lib/public/appframework/controller.php
+++ b/lib/public/appframework/controller.php
@@ -28,6 +28,8 @@
namespace OCP\AppFramework;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\IResponseSerializer;
use OCP\IRequest;
@@ -48,6 +50,8 @@ abstract class Controller {
*/
protected $request;
+ private $serializer;
+ private $formatters;
/**
* constructor of the controller
@@ -66,11 +70,66 @@ abstract class Controller {
IRequest $request){
$this->appName = $appName;
$this->request = $request;
+
+ // default formatters
+ $this->formatters = array(
+ 'json' => function ($response) {
+ return new JSONResponse($response);
+ }
+ );
+ }
+
+
+ /**
+ * Registers a serializer that is executed before a formatter is being
+ * called, useful for turning any data into PHP arrays that can be used
+ * by a JSONResponse for instance
+ * @param IResponseSerializer $serializer
+ */
+ protected function registerSerializer(IResponseSerializer $serializer) {
+ $this->serializer = $serializer;
+ }
+
+
+ /**
+ * Registers a formatter for a type
+ * @param string $format
+ * @param \Closure $closure
+ */
+ protected function registerFormatter($format, \Closure $formatter) {
+ $this->formatters[$format] = $formatter;
+ }
+
+
+ /**
+ * Serializes and formats a response
+ * @param mixed response the value that was returned from a controller and
+ * is not a Response instance
+ * @param string $format the format for which a formatter has been registered
+ * @throws \DomainException if format does not match a registered formatter
+ * @return Response
+ */
+ public function formatResponse($response, $format='json') {
+ if(array_key_exists($format, $this->formatters)) {
+
+ if ($this->serializer) {
+ $response = $this->serializer->serialize($response);
+ }
+
+ $formatter = $this->formatters[$format];
+
+ return $formatter($response);
+
+ } else {
+ throw new \DomainException('No formatter registered for format ' .
+ $format . '!');
+ }
}
/**
* Lets you access post and get parameters by the index
+ * @deprecated write your parameters as method arguments instead
* @param string $key the key which you want to access in the URL Parameter
* placeholder, $_POST or $_GET array.
* The priority how they're returned is the following:
@@ -88,6 +147,7 @@ abstract class Controller {
/**
* Returns all params that were received, be it from the request
* (as GET or POST) or throuh the URL by the route
+ * @deprecated use $this->request instead
* @return array the array with all parameters
*/
public function getParams() {
@@ -97,6 +157,7 @@ abstract class Controller {
/**
* Returns the method of the request
+ * @deprecated use $this->request instead
* @return string the method of the request (POST, GET, etc)
*/
public function method() {
@@ -106,6 +167,7 @@ abstract class Controller {
/**
* Shortcut for accessing an uploaded file through the $_FILES array
+ * @deprecated use $this->request instead
* @param string $key the key that will be taken from the $_FILES array
* @return array the file in the $_FILES element
*/
@@ -116,6 +178,7 @@ abstract class Controller {
/**
* Shortcut for getting env variables
+ * @deprecated use $this->request instead
* @param string $key the key that will be taken from the $_ENV array
* @return array the value in the $_ENV element
*/
@@ -126,6 +189,7 @@ abstract class Controller {
/**
* Shortcut for getting cookie variables
+ * @deprecated use $this->request instead
* @param string $key the key that will be taken from the $_COOKIE array
* @return array the value in the $_COOKIE element
*/
@@ -136,6 +200,7 @@ abstract class Controller {
/**
* Shortcut for rendering a template
+ * @deprecated return a template response instead
* @param string $templateName the name of the template
* @param array $params the template parameters in key => value structure
* @param string $renderAs user renders a full page, blank only your template
diff --git a/tests/lib/appframework/utility/MethodAnnotationReaderTest.php b/lib/public/appframework/http/iresponseserializer.php
similarity index 52%
rename from tests/lib/appframework/utility/MethodAnnotationReaderTest.php
rename to lib/public/appframework/http/iresponseserializer.php
index c68812a..8ffdd45 100644
--- a/tests/lib/appframework/utility/MethodAnnotationReaderTest.php
+++ b/lib/public/appframework/http/iresponseserializer.php
@@ -1,5 +1,4 @@
<?php
-
/**
* ownCloud - App Framework
*
@@ -21,35 +20,8 @@
*
*/
+namespace OCP\AppFramework\Http;
-namespace OC\AppFramework\Utility;
-
-
-class MethodAnnotationReaderTest extends \PHPUnit_Framework_TestCase {
-
-
- /**
- * @Annotation
- */
- public function testReadAnnotation(){
- $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest',
- 'testReadAnnotation');
-
- $this->assertTrue($reader->hasAnnotation('Annotation'));
- }
-
-
- /**
- * @Annotation
- * @param test
- */
- public function testReadAnnotationNoLowercase(){
- $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest',
- 'testReadAnnotationNoLowercase');
-
- $this->assertTrue($reader->hasAnnotation('Annotation'));
- $this->assertFalse($reader->hasAnnotation('param'));
- }
-
-
-}
+interface IResponseSerializer {
+ function serialize($response);
+}
\ No newline at end of file
diff --git a/lib/public/appframework/http/templateresponse.php b/lib/public/appframework/http/templateresponse.php
index f5baf78..52355f9 100644
--- a/lib/public/appframework/http/templateresponse.php
+++ b/lib/public/appframework/http/templateresponse.php
@@ -61,12 +61,16 @@ class TemplateResponse extends Response {
* constructor of TemplateResponse
* @param string $appName the name of the app to load the template from
* @param string $templateName the name of the template
+ * @param array $params an array of parameters which should be passed to the
+ * template
+ * @param string $renderAs how the page should be rendered, defaults to user
*/
- public function __construct($appName, $templateName) {
+ public function __construct($appName, $templateName, array $params=array(),
+ $renderAs='user') {
$this->templateName = $templateName;
$this->appName = $appName;
- $this->params = array();
- $this->renderAs = 'user';
+ $this->params = $params;
+ $this->renderAs = $renderAs;
}
diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php
index b6c8312..4785c68 100644
--- a/tests/lib/appframework/controller/ControllerTest.php
+++ b/tests/lib/appframework/controller/ControllerTest.php
@@ -26,9 +26,31 @@ namespace OCP\AppFramework;
use OC\AppFramework\Http\Request;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\IResponseSerializer;
-class ChildController extends Controller {};
+class ToUpperCaseSerializer implements IResponseSerializer {
+ public function serialize($response) {
+ return array(strtoupper($response));
+ }
+}
+
+class ChildController extends Controller {
+ public function custom($in) {
+ $this->registerFormatter('json', function ($response) {
+ return new JSONResponse(array(strlen($response)));
+ });
+
+ return $in;
+ }
+
+ public function serializer($in) {
+ $this->registerSerializer(new ToUpperCaseSerializer());
+
+ return $in;
+ }
+};
class ControllerTest extends \PHPUnit_Framework_TestCase {
@@ -129,4 +151,35 @@ class ControllerTest extends \PHPUnit_Framework_TestCase {
}
+ /**
+ * @expectedException \DomainException
+ */
+ public function testFormatResonseInvalidFormat() {
+ $this->controller->formatResponse(null, 'test');
+ }
+
+
+ public function testFormat() {
+ $response = $this->controller->formatResponse(array('hi'), 'json');
+
+ $this->assertEquals(array('hi'), $response->getData());
+ }
+
+
+ public function testCustomFormatter() {
+ $response = $this->controller->custom('hi');
+ $response = $this->controller->formatResponse($response, 'json');
+
+ $this->assertEquals(array(2), $response->getData());
+ }
+
+
+ public function testCustomSerializer() {
+ $response = $this->controller->serializer('hi');
+ $response = $this->controller->formatResponse($response, 'json');
+
+ $this->assertEquals(array('HI'), $response->getData());
+ }
+
+
}
diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php
index 9841dca..ba1e989 100644
--- a/tests/lib/appframework/http/DispatcherTest.php
+++ b/tests/lib/appframework/http/DispatcherTest.php
@@ -25,8 +25,28 @@
namespace OC\AppFramework\Http;
use OC\AppFramework\Middleware\MiddlewareDispatcher;
+use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\Http;
-//require_once(__DIR__ . "/../classloader.php");
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Controller;
+
+
+class TestController extends Controller {
+ public function __construct($appName, $request) {
+ parent::__construct($appName, $request);
+ }
+
+ /**
+ * @param int $int
+ * @param bool $bool
+ */
+ public function exec($int, $bool) {
+ $this->registerFormatter('text', function($in) {
+ return new JSONResponse(array('text' => $in));
+ });
+ return array($int, $bool);
+ }
+}
class DispatcherTest extends \PHPUnit_Framework_TestCase {
@@ -39,6 +59,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
private $lastModified;
private $etag;
private $http;
+ private $reflector;
protected function setUp() {
$this->controllerMethod = 'test';
@@ -64,8 +85,17 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
'\OCP\AppFramework\Controller',
array($this->controllerMethod), array($app, $request));
+ $this->request = $this->getMockBuilder(
+ '\OC\AppFramework\Http\Request')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->reflector = new ControllerMethodReflector();
+
$this->dispatcher = new Dispatcher(
- $this->http, $this->middlewareDispatcher);
+ $this->http, $this->middlewareDispatcher, $this->reflector,
+ $this->request
+ );
$this->response = $this->getMockBuilder(
'\OCP\AppFramework\Http\Response')
@@ -81,7 +111,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
* @param string $out
* @param string $httpHeaders
*/
- private function setMiddlewareExpections($out=null,
+ private function setMiddlewareExpectations($out=null,
$httpHeaders=null, $responseHeaders=array(),
$ex=false, $catchEx=true) {
@@ -159,14 +189,12 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
->with($this->equalTo($this->controller),
$this->equalTo($this->controllerMethod),
$this->equalTo($out))
- ->will($this->returnValue($out));
-
-
+ ->will($this->returnValue($out));
}
public function testDispatcherReturnsArrayWith2Entries() {
- $this->setMiddlewareExpections();
+ $this->setMiddlewareExpectations();
$response = $this->dispatcher->dispatch($this->controller,
$this->controllerMethod);
@@ -180,7 +208,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
$out = 'yo';
$httpHeaders = 'Http';
$responseHeaders = array('hell' => 'yeah');
- $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders);
+ $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders);
$response = $this->dispatcher->dispatch($this->controller,
$this->controllerMethod);
@@ -195,7 +223,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
$out = 'yo';
$httpHeaders = 'Http';
$responseHeaders = array('hell' => 'yeah');
- $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true);
+ $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true);
$response = $this->dispatcher->dispatch($this->controller,
$this->controllerMethod);
@@ -210,7 +238,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
$out = 'yo';
$httpHeaders = 'Http';
$responseHeaders = array('hell' => 'yeah');
- $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true, false);
+ $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true, false);
$this->setExpectedException('\Exception');
$response = $this->dispatcher->dispatch($this->controller,
@@ -218,4 +246,120 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase {
}
+
+ private function dispatcherPassthrough() {
+ $this->middlewareDispatcher->expects($this->once())
+ ->method('beforeController');
+ $this->middlewareDispatcher->expects($this->once())
+ ->method('afterController')
+ ->will($this->returnCallback(function($a, $b, $in) {
+ return $in;
+ }));
+ $this->middlewareDispatcher->expects($this->once())
+ ->method('beforeOutput')
+ ->will($this->returnCallback(function($a, $b, $in) {
+ return $in;
+ }));
+ }
+
+ public function testControllerParametersInjected() {
+ $this->request = new Request(array(
+ 'post' => array(
+ 'int' => '3',
+ 'bool' => 'false'
+ ),
+ 'method' => 'POST'
+ ));
+ $this->dispatcher = new Dispatcher(
+ $this->http, $this->middlewareDispatcher, $this->reflector,
+ $this->request
+ );
+ $controller = new TestController('app', $this->request);
+
+ // reflector is supposed to be called once
+ $this->dispatcherPassthrough();
+ $response = $this->dispatcher->dispatch($controller, 'exec');
+
+ $this->assertEquals('[3,true]', $response[2]);
+ }
+
+
+ public function testResponseTransformedByUrlFormat() {
+ $this->request = new Request(array(
+ 'post' => array(
+ 'int' => '3',
+ 'bool' => 'false'
+ ),
+ 'urlParams' => array(
+ 'format' => 'text'
+ ),
+ 'method' => 'GET'
+ ));
+ $this->dispatcher = new Dispatcher(
+ $this->http, $this->middlewareDispatcher, $this->reflector,
+ $this->request
+ );
+ $controller = new TestController('app', $this->request);
+
+ // reflector is supposed to be called once
+ $this->dispatcherPassthrough();
+ $response = $this->dispatcher->dispatch($controller, 'exec');
+
+ $this->assertEquals('{"text":[3,false]}', $response[2]);
+ }
+
+
+ public function testResponseTransformedByAcceptHeader() {
+ $this->request = new Request(array(
+ 'post' => array(
+ 'int' => '3',
+ 'bool' => 'false'
+ ),
+ 'server' => array(
+ 'HTTP_ACCEPT' => 'application/text, test',
+ 'HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded'
+ ),
+ 'method' => 'POST'
+ ));
+ $this->dispatcher = new Dispatcher(
+ $this->http, $this->middlewareDispatcher, $this->reflector,
+ $this->request
+ );
+ $controller = new TestController('app', $this->request);
+
+ // reflector is supposed to be called once
+ $this->dispatcherPassthrough();
+ $response = $this->dispatcher->dispatch($controller, 'exec');
+
+ $this->assertEquals('{"text":[3,false]}', $response[2]);
+ }
+
+
+ public function testResponsePrimarilyTransformedByParameterFormat() {
+ $this->request = new Request(array(
+ 'post' => array(
+ 'int' => '3',
+ 'bool' => 'false'
+ ),
+ 'get' => array(
+ 'format' => 'text'
+ ),
+ 'server' => array(
+ 'HTTP_ACCEPT' => 'application/json, test'
+ ),
+ 'method' => 'POST'
+ ));
+ $this->dispatcher = new Dispatcher(
+ $this->http, $this->middlewareDispatcher, $this->reflector,
+ $this->request
+ );
+ $controller = new TestController('app', $this->request);
+
+ // reflector is supposed to be called once
+ $this->dispatcherPassthrough();
+ $response = $this->dispatcher->dispatch($controller, 'exec');
+
+ $this->assertEquals('{"text":[3,true]}', $response[2]);
+ }
+
}
diff --git a/tests/lib/appframework/http/TemplateResponseTest.php b/tests/lib/appframework/http/TemplateResponseTest.php
index 0b158ed..29ce8cf 100644
--- a/tests/lib/appframework/http/TemplateResponseTest.php
+++ b/tests/lib/appframework/http/TemplateResponseTest.php
@@ -51,6 +51,22 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase {
}
+ public function testSetParamsConstructor(){
+ $params = array('hi' => 'yo');
+ $this->tpl = new TemplateResponse($this->api, 'home', $params);
+
+ $this->assertEquals(array('hi' => 'yo'), $this->tpl->getParams());
+ }
+
+
+ public function testSetRenderAsConstructor(){
+ $renderAs = 'myrender';
+ $this->tpl = new TemplateResponse($this->api, 'home', array(), $renderAs);
+
+ $this->assertEquals($renderAs, $this->tpl->getRenderAs());
+ }
+
+
public function testSetParams(){
$params = array('hi' => 'yo');
$this->tpl->setParams($params);
@@ -63,36 +79,6 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase {
$this->assertEquals('home', $this->tpl->getTemplateName());
}
-
-// public function testRender(){
-// $ocTpl = $this->getMock('Template', array('fetchPage'));
-// $ocTpl->expects($this->once())
-// ->method('fetchPage');
-//
-// $tpl = new TemplateResponse('core', 'error');
-//
-// $tpl->render();
-// }
-//
-//
-// public function testRenderAssignsParams(){
-// $params = array('john' => 'doe');
-//
-// $tpl = new TemplateResponse('app', 'home');
-// $tpl->setParams($params);
-//
-// $tpl->render();
-// }
-//
-//
-// public function testRenderDifferentApp(){
-//
-// $tpl = new TemplateResponse('app', 'home', 'app2');
-//
-// $tpl->render();
-// }
-
-
public function testGetRenderAs(){
$render = 'myrender';
$this->tpl->renderAs($render);
diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
index 19e8a68..e91aaca 100644
--- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
+++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php
@@ -26,6 +26,7 @@ namespace OC\AppFramework\Middleware\Security;
use OC\AppFramework\Http;
use OC\AppFramework\Http\Request;
+use OC\AppFramework\Utility\ControllerMethodReflector;
use OCP\AppFramework\Http\RedirectResponse;
use OCP\AppFramework\Http\JSONResponse;
@@ -37,14 +38,16 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
private $secException;
private $secAjaxException;
private $request;
+ private $reader;
public function setUp() {
$api = $this->getMock('OC\AppFramework\DependencyInjection\DIContainer', array(), array('test'));
$this->controller = $this->getMock('OCP\AppFramework\Controller',
array(), array($api, new Request()));
+ $this->reader = new ControllerMethodReflector();
$this->request = new Request();
- $this->middleware = new SecurityMiddleware($api, $this->request);
+ $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader);
$this->secException = new SecurityException('hey', false);
$this->secAjaxException = new SecurityException('hey', true);
}
@@ -68,7 +71,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
$api->expects($this->any())->method('getServer')
->will($this->returnValue($serverMock));
- $sec = new SecurityMiddleware($api, $this->request);
+ $sec = new SecurityMiddleware($api, $this->request, $this->reader);
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method);
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method);
}
@@ -99,11 +103,12 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->will($this->returnValue(true));
}
- $sec = new SecurityMiddleware($api, $this->request);
+ $sec = new SecurityMiddleware($api, $this->request, $this->reader);
try {
- $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest',
- $method);
+ $controller = '\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest';
+ $this->reader->reflect($controller, $method);
+ $sec->beforeController($controller, $method);
} catch (SecurityException $ex){
$this->assertEquals($status, $ex->getCode());
}
@@ -184,7 +189,9 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->method('isLoggedIn')
->will($this->returnValue(true));
- $sec = new SecurityMiddleware($api, $this->request);
+ $sec = new SecurityMiddleware($api, $this->request, $this->reader);
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest',
+ 'testNoChecks');
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest',
'testNoChecks');
}
@@ -207,7 +214,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->will($this->returnValue(true));
}
- $sec = new SecurityMiddleware($api, $this->request);
+ $sec = new SecurityMiddleware($api, $this->request, $this->reader);
if($shouldFail){
$this->setExpectedException('\OC\AppFramework\Middleware\Security\SecurityException');
@@ -215,6 +222,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
$this->setExpectedException(null);
}
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method);
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method);
}
@@ -230,7 +238,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->method('passesCSRFCheck')
->will($this->returnValue(false));
- $sec = new SecurityMiddleware($api, $request);
+ $sec = new SecurityMiddleware($api, $request, $this->reader);
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck');
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck');
}
@@ -246,7 +255,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->method('passesCSRFCheck')
->will($this->returnValue(false));
- $sec = new SecurityMiddleware($api, $request);
+ $sec = new SecurityMiddleware($api, $request, $this->reader);
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck');
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck');
}
@@ -261,7 +271,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
->method('passesCSRFCheck')
->will($this->returnValue(true));
- $sec = new SecurityMiddleware($api, $request);
+ $sec = new SecurityMiddleware($api, $request, $this->reader);
+ $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck');
$sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck');
}
@@ -318,7 +329,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase {
$this->request = new Request(
array('server' => array('HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')));
- $this->middleware = new SecurityMiddleware($api, $this->request);
+ $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader);
$response = $this->middleware->afterException($this->controller, 'test',
$this->secException);
diff --git a/tests/lib/appframework/utility/ControllerMethodReflectorTest.php b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php
new file mode 100644
index 0000000..2a7c003
--- /dev/null
+++ b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * ownCloud - App Framework
+ *
+ * @author Bernhard Posselt
+ * @copyright 2012 Bernhard Posselt nukeawhale at gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+namespace OC\AppFramework\Utility;
+
+
+class ControllerMethodReflectorTest extends \PHPUnit_Framework_TestCase {
+
+
+ /**
+ * @Annotation
+ */
+ public function testReadAnnotation(){
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'testReadAnnotation'
+ );
+
+ $this->assertTrue($reader->hasAnnotation('Annotation'));
+ }
+
+
+ /**
+ * @Annotation
+ * @param test
+ */
+ public function testReadAnnotationNoLowercase(){
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'testReadAnnotationNoLowercase'
+ );
+
+ $this->assertTrue($reader->hasAnnotation('Annotation'));
+ $this->assertFalse($reader->hasAnnotation('param'));
+ }
+
+
+ /**
+ * @Annotation
+ * @param int $test
+ */
+ public function testReadTypeIntAnnotations(){
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'testReadTypeIntAnnotations'
+ );
+
+ $this->assertEquals('int', $reader->getType('test'));
+ }
+
+
+ /**
+ * @Annotation
+ * @param double $test
+ */
+ public function testReadTypeDoubleAnnotations(){
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'testReadTypeDoubleAnnotations'
+ );
+
+ $this->assertEquals('double', $reader->getType('test'));
+ }
+
+
+ public function arguments($arg, $arg2) {}
+ public function testReflectParameters() {
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'arguments'
+ );
+
+ $this->assertEquals(array('arg', 'arg2'), $reader->getParameters());
+ }
+
+
+ public function arguments2($arg) {}
+ public function testReflectParameters2() {
+ $reader = new ControllerMethodReflector();
+ $reader->reflect(
+ '\OC\AppFramework\Utility\ControllerMethodReflectorTest',
+ 'arguments2'
+ );
+
+ $this->assertEquals(array('arg',), $reader->getParameters());
+ }
+
+
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git
More information about the Pkg-owncloud-commits
mailing list