diff options
Diffstat (limited to 'tests/lib/AppFramework/Http/DispatcherTest.php')
-rw-r--r-- | tests/lib/AppFramework/Http/DispatcherTest.php | 249 |
1 files changed, 162 insertions, 87 deletions
diff --git a/tests/lib/AppFramework/Http/DispatcherTest.php b/tests/lib/AppFramework/Http/DispatcherTest.php index e1d78082a2d..86c78e840e0 100644 --- a/tests/lib/AppFramework/Http/DispatcherTest.php +++ b/tests/lib/AppFramework/Http/DispatcherTest.php @@ -1,28 +1,14 @@ <?php /** - * ownCloud - App Framework - * - * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt <dev@bernhard-posselt.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/>. - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-or-later */ namespace Test\AppFramework\Http; +use OC\AppFramework\DependencyInjection\DIContainer; use OC\AppFramework\Http\Dispatcher; use OC\AppFramework\Http\Request; use OC\AppFramework\Middleware\MiddlewareDispatcher; @@ -31,18 +17,22 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\ParameterOutOfRangeException; use OCP\AppFramework\Http\Response; use OCP\Diagnostics\IEventLogger; use OCP\IConfig; +use OCP\IDBConnection; use OCP\IRequest; +use OCP\IRequestId; +use OCP\Server; use PHPUnit\Framework\MockObject\MockObject; +use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; -use OCP\IRequestId; class TestController extends Controller { /** * @param string $appName - * @param \OCP\IRequest $request + * @param IRequest $request */ public function __construct($appName, $request) { parent::__construct($appName, $request); @@ -51,11 +41,12 @@ class TestController extends Controller { /** * @param int $int * @param bool $bool + * @param double $foo * @param int $test - * @param int $test2 + * @param integer $test2 * @return array */ - public function exec($int, $bool, $test = 4, $test2 = 1) { + public function exec($int, $bool, $foo, $test = 4, $test2 = 1) { $this->registerResponder('text', function ($in) { return new JSONResponse(['text' => $in]); }); @@ -75,6 +66,10 @@ class TestController extends Controller { 'text' => [$int, $bool, $test, $test2] ]); } + + public function test(): Response { + return new DataResponse(); + } } /** @@ -89,22 +84,24 @@ class DispatcherTest extends \Test\TestCase { /** @var Dispatcher */ private $dispatcher; private $controllerMethod; + /** @var Controller|MockObject */ + private $controller; private $response; - /** @var IRequest|MockObject */ + /** @var IRequest|MockObject */ private $request; private $lastModified; private $etag; - /** @var Http|MockObject */ + /** @var Http|MockObject */ private $http; private $reflector; - /** @var IConfig|MockObject */ + /** @var IConfig|MockObject */ private $config; - /** @var LoggerInterface|MockObject */ + /** @var LoggerInterface|MockObject */ private $logger; - /** - * @var IEventLogger|MockObject - */ + /** @var IEventLogger|MockObject */ private $eventLogger; + /** @var ContainerInterface|MockObject */ + private $container; protected function setUp(): void { parent::setUp(); @@ -113,33 +110,18 @@ class DispatcherTest extends \Test\TestCase { $this->config = $this->createMock(IConfig::class); $this->logger = $this->createMock(LoggerInterface::class); $this->eventLogger = $this->createMock(IEventLogger::class); - $app = $this->getMockBuilder( - 'OC\AppFramework\DependencyInjection\DIContainer') - ->disableOriginalConstructor() - ->getMock(); - $request = $this->getMockBuilder( - '\OC\AppFramework\Http\Request') - ->disableOriginalConstructor() - ->getMock(); - $this->http = $this->getMockBuilder( - \OC\AppFramework\Http::class) - ->disableOriginalConstructor() - ->getMock(); - - $this->middlewareDispatcher = $this->getMockBuilder( - '\OC\AppFramework\Middleware\MiddlewareDispatcher') - ->disableOriginalConstructor() - ->getMock(); - $this->controller = $this->getMockBuilder( - '\OCP\AppFramework\Controller') - ->setMethods([$this->controllerMethod]) + $this->container = $this->createMock(ContainerInterface::class); + $app = $this->createMock(DIContainer::class); + $request = $this->createMock(Request::class); + $this->http = $this->createMock(\OC\AppFramework\Http::class); + + $this->middlewareDispatcher = $this->createMock(MiddlewareDispatcher::class); + $this->controller = $this->getMockBuilder(TestController::class) + ->onlyMethods([$this->controllerMethod]) ->setConstructorArgs([$app, $request]) ->getMock(); - $this->request = $this->getMockBuilder( - '\OC\AppFramework\Http\Request') - ->disableOriginalConstructor() - ->getMock(); + $this->request = $this->createMock(Request::class); $this->reflector = new ControllerMethodReflector(); @@ -149,9 +131,10 @@ class DispatcherTest extends \Test\TestCase { $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container, ); $this->response = $this->createMock(Response::class); @@ -174,7 +157,7 @@ class DispatcherTest extends \Test\TestCase { ->method('beforeController') ->with($this->equalTo($this->controller), $this->equalTo($this->controllerMethod)) - ->will($this->throwException($exception)); + ->willThrowException($exception); if ($catchEx) { $this->middlewareDispatcher->expects($this->once()) ->method('afterException') @@ -238,7 +221,7 @@ class DispatcherTest extends \Test\TestCase { } - public function testDispatcherReturnsArrayWith2Entries() { + public function testDispatcherReturnsArrayWith2Entries(): void { $this->setMiddlewareExpectations(''); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -248,7 +231,7 @@ class DispatcherTest extends \Test\TestCase { } - public function testHeadersAndOutputAreReturned() { + public function testHeadersAndOutputAreReturned(): void { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = ['hell' => 'yeah']; @@ -263,7 +246,7 @@ class DispatcherTest extends \Test\TestCase { } - public function testExceptionCallsAfterException() { + public function testExceptionCallsAfterException(): void { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = ['hell' => 'yeah']; @@ -278,7 +261,7 @@ class DispatcherTest extends \Test\TestCase { } - public function testExceptionThrowsIfCanNotBeHandledByAfterException() { + public function testExceptionThrowsIfCanNotBeHandledByAfterException(): void { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = ['hell' => 'yeah']; @@ -294,7 +277,7 @@ class DispatcherTest extends \Test\TestCase { private function dispatcherPassthrough() { $this->middlewareDispatcher->expects($this->once()) - ->method('beforeController'); + ->method('beforeController'); $this->middlewareDispatcher->expects($this->once()) ->method('afterController') ->willReturnCallback(function ($a, $b, $in) { @@ -308,12 +291,13 @@ class DispatcherTest extends \Test\TestCase { } - public function testControllerParametersInjected() { + public function testControllerParametersInjected(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', - 'bool' => 'false' + 'bool' => 'false', + 'double' => 1.2, ], 'method' => 'POST' ], @@ -324,9 +308,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -334,16 +319,17 @@ class DispatcherTest extends \Test\TestCase { $this->dispatcherPassthrough(); $response = $this->dispatcher->dispatch($controller, 'exec'); - $this->assertEquals('[3,true,4,1]', $response[3]); + $this->assertEquals('[3,false,4,1]', $response[3]); } - public function testControllerParametersInjectedDefaultOverwritten() { + public function testControllerParametersInjectedDefaultOverwritten(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', 'bool' => 'false', + 'double' => 1.2, 'test2' => 7 ], 'method' => 'POST', @@ -355,9 +341,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -365,17 +352,18 @@ class DispatcherTest extends \Test\TestCase { $this->dispatcherPassthrough(); $response = $this->dispatcher->dispatch($controller, 'exec'); - $this->assertEquals('[3,true,4,7]', $response[3]); + $this->assertEquals('[3,false,4,7]', $response[3]); } - public function testResponseTransformedByUrlFormat() { + public function testResponseTransformedByUrlFormat(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', - 'bool' => 'false' + 'bool' => 'false', + 'double' => 1.2, ], 'urlParams' => [ 'format' => 'text' @@ -389,9 +377,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -403,12 +392,13 @@ class DispatcherTest extends \Test\TestCase { } - public function testResponseTransformsDataResponse() { + public function testResponseTransformsDataResponse(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', - 'bool' => 'false' + 'bool' => 'false', + 'double' => 1.2, ], 'urlParams' => [ 'format' => 'json' @@ -422,9 +412,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -436,12 +427,13 @@ class DispatcherTest extends \Test\TestCase { } - public function testResponseTransformedByAcceptHeader() { + public function testResponseTransformedByAcceptHeader(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', - 'bool' => 'false' + 'bool' => 'false', + 'double' => 1.2, ], 'server' => [ 'HTTP_ACCEPT' => 'application/text, test', @@ -456,9 +448,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -469,13 +462,49 @@ class DispatcherTest extends \Test\TestCase { $this->assertEquals('{"text":[3,false,4,1]}', $response[3]); } + public function testResponseTransformedBySendingMultipartFormData(): void { + $this->request = new Request( + [ + 'post' => [ + 'int' => '3', + 'bool' => 'false', + 'double' => 1.2, + ], + 'server' => [ + 'HTTP_ACCEPT' => 'application/text, test', + 'HTTP_CONTENT_TYPE' => 'multipart/form-data' + ], + 'method' => 'POST' + ], + $this->createMock(IRequestId::class), + $this->createMock(IConfig::class) + ); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request, + $this->config, + Server::get(IDBConnection::class), + $this->logger, + $this->eventLogger, + $this->container + ); + $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,4,1]}', $response[3]); + } - public function testResponsePrimarilyTransformedByParameterFormat() { + + public function testResponsePrimarilyTransformedByParameterFormat(): void { $this->request = new Request( [ 'post' => [ 'int' => '3', - 'bool' => 'false' + 'bool' => 'false', + 'double' => 1.2, ], 'get' => [ 'format' => 'text' @@ -492,9 +521,10 @@ class DispatcherTest extends \Test\TestCase { $this->http, $this->middlewareDispatcher, $this->reflector, $this->request, $this->config, - \OC::$server->getDatabaseConnection(), + Server::get(IDBConnection::class), $this->logger, - $this->eventLogger + $this->eventLogger, + $this->container ); $controller = new TestController('app', $this->request); @@ -502,6 +532,51 @@ class DispatcherTest extends \Test\TestCase { $this->dispatcherPassthrough(); $response = $this->dispatcher->dispatch($controller, 'exec'); - $this->assertEquals('{"text":[3,true,4,1]}', $response[3]); + $this->assertEquals('{"text":[3,false,4,1]}', $response[3]); + } + + + public static function rangeDataProvider(): array { + return [ + [PHP_INT_MIN, PHP_INT_MAX, 42, false], + [0, 12, -5, true], + [-12, 0, 5, true], + [7, 14, 5, true], + [7, 14, 10, false], + [-14, -7, -10, false], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider('rangeDataProvider')] + public function testEnsureParameterValueSatisfiesRange(int $min, int $max, int $input, bool $throw): void { + $this->reflector = $this->createMock(ControllerMethodReflector::class); + $this->reflector->expects($this->any()) + ->method('getRange') + ->willReturn([ + 'min' => $min, + 'max' => $max, + ]); + + $this->dispatcher = new Dispatcher( + $this->http, + $this->middlewareDispatcher, + $this->reflector, + $this->request, + $this->config, + Server::get(IDBConnection::class), + $this->logger, + $this->eventLogger, + $this->container, + ); + + if ($throw) { + $this->expectException(ParameterOutOfRangeException::class); + } + + $this->invokePrivate($this->dispatcher, 'ensureParameterValueSatisfiesRange', ['myArgument', $input]); + if (!$throw) { + // do not mark this test risky + $this->assertTrue(true); + } } } |