summaryrefslogtreecommitdiff
path: root/tests/Unit
diff options
context:
space:
mode:
authormsquare <msquare@notrademark.de>2018-09-04 18:24:11 +0200
committermsquare <msquare@notrademark.de>2018-09-04 18:24:11 +0200
commitb320fc779063ee80b8f0ba505cb323287ccccbf5 (patch)
tree1e420597ae72c979361bf29b66ae7e27c73cf431 /tests/Unit
parent9f1ee0c6c6497d43fb275491ec53fda420f64b81 (diff)
parent36dafdb68acbde2fe42ce36ef50f497c8c06411f (diff)
Merge branch 'MyIgel-rebuild-psr7'
Diffstat (limited to 'tests/Unit')
-rw-r--r--tests/Unit/ApplicationTest.php10
-rw-r--r--tests/Unit/Exceptions/HandlerTest.php14
-rw-r--r--tests/Unit/Exceptions/Handlers/WhoopsTest.php8
-rw-r--r--tests/Unit/HelpersTest.php28
-rw-r--r--tests/Unit/Http/MessageTraitRequestTest.php50
-rw-r--r--tests/Unit/Http/MessageTraitResponseTest.php159
-rw-r--r--tests/Unit/Http/Psr7ServiceProviderTest.php56
-rw-r--r--tests/Unit/Http/RequestTest.php283
-rw-r--r--tests/Unit/Http/ResponseServiceProviderTest.php29
-rw-r--r--tests/Unit/Http/ResponseTest.php49
-rw-r--r--tests/Unit/Http/Stub/MessageTraitRequestImplementation.php12
-rw-r--r--tests/Unit/Http/Stub/MessageTraitResponseImplementation.php12
-rw-r--r--tests/Unit/Middleware/DispatcherTest.php230
-rw-r--r--tests/Unit/Middleware/ExceptionHandlerTest.php58
-rw-r--r--tests/Unit/Middleware/LegacyMiddlewareTest.php85
-rw-r--r--tests/Unit/Middleware/NotFoundResponseTest.php39
-rw-r--r--tests/Unit/Middleware/SendResponseHandlerTest.php71
-rw-r--r--tests/Unit/Middleware/Stub/ExceptionMiddlewareHandler.php23
-rw-r--r--tests/Unit/Middleware/Stub/NotARealMiddleware.php8
-rw-r--r--tests/Unit/Middleware/Stub/ReturnResponseMiddleware.php36
-rw-r--r--tests/Unit/Middleware/Stub/ReturnResponseMiddlewareHandler.php30
21 files changed, 1284 insertions, 6 deletions
diff --git a/tests/Unit/ApplicationTest.php b/tests/Unit/ApplicationTest.php
index f58483ea..866eb957 100644
--- a/tests/Unit/ApplicationTest.php
+++ b/tests/Unit/ApplicationTest.php
@@ -9,6 +9,7 @@ use Engelsystem\Container\ServiceProvider;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject;
use Psr\Container\ContainerInterface;
+use Psr\Http\Server\MiddlewareInterface;
use ReflectionClass;
class ApplicationTest extends TestCase
@@ -118,6 +119,7 @@ class ApplicationTest extends TestCase
/**
* @covers \Engelsystem\Application::bootstrap
* @covers \Engelsystem\Application::isBooted
+ * @covers \Engelsystem\Application::getMiddleware
*/
public function testBootstrap()
{
@@ -137,10 +139,11 @@ class ApplicationTest extends TestCase
$config = $this->getMockBuilder(Config::class)
->getMock();
- $config->expects($this->once())
+ $middleware = [MiddlewareInterface::class];
+ $config->expects($this->exactly(2))
->method('get')
- ->with('providers')
- ->willReturn([$serviceProvider]);
+ ->withConsecutive(['providers'], ['middleware'])
+ ->willReturnOnConsecutiveCalls([$serviceProvider], $middleware);
$property = (new ReflectionClass($app))->getProperty('serviceProviders');
$property->setAccessible(true);
@@ -149,6 +152,7 @@ class ApplicationTest extends TestCase
$app->bootstrap($config);
$this->assertTrue($app->isBooted());
+ $this->assertEquals($middleware, $app->getMiddleware());
// Run bootstrap another time to ensure that providers are registered only once
$app->bootstrap($config);
diff --git a/tests/Unit/Exceptions/HandlerTest.php b/tests/Unit/Exceptions/HandlerTest.php
index 5a6ffe16..58d25de3 100644
--- a/tests/Unit/Exceptions/HandlerTest.php
+++ b/tests/Unit/Exceptions/HandlerTest.php
@@ -49,15 +49,19 @@ class HandlerTest extends TestCase
public function testExceptionHandler()
{
$exception = new Exception();
+ $errorMessage = 'Oh noes, an error!';
/** @var HandlerInterface|Mock $handlerMock */
$handlerMock = $this->getMockForAbstractClass(HandlerInterface::class);
- $handlerMock->expects($this->once())
+ $handlerMock->expects($this->atLeastOnce())
->method('report')
->with($exception);
- $handlerMock->expects($this->once())
+ $handlerMock->expects($this->atLeastOnce())
->method('render')
- ->with($this->isInstanceOf(Request::class), $exception);
+ ->with($this->isInstanceOf(Request::class), $exception)
+ ->willReturnCallback(function () use ($errorMessage) {
+ echo $errorMessage;
+ });
/** @var Handler|Mock $handler */
$handler = $this->getMockBuilder(Handler::class)
@@ -68,7 +72,11 @@ class HandlerTest extends TestCase
$handler->setHandler(Handler::ENV_PRODUCTION, $handlerMock);
+ $this->expectOutputString($errorMessage);
$handler->exceptionHandler($exception);
+
+ $return = $handler->exceptionHandler($exception, true);
+ $this->assertEquals($errorMessage, $return);
}
/**
diff --git a/tests/Unit/Exceptions/Handlers/WhoopsTest.php b/tests/Unit/Exceptions/Handlers/WhoopsTest.php
index 261ee83f..4062979b 100644
--- a/tests/Unit/Exceptions/Handlers/WhoopsTest.php
+++ b/tests/Unit/Exceptions/Handlers/WhoopsTest.php
@@ -74,6 +74,14 @@ class WhoopsTest extends TestCase
);
$whoopsRunner
->expects($this->once())
+ ->method('writeToOutput')
+ ->with(false);
+ $whoopsRunner
+ ->expects($this->once())
+ ->method('allowQuit')
+ ->with(false);
+ $whoopsRunner
+ ->expects($this->once())
->method('handleException')
->with($exception);
diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php
index 9514ad8c..cd001df9 100644
--- a/tests/Unit/HelpersTest.php
+++ b/tests/Unit/HelpersTest.php
@@ -6,6 +6,7 @@ use Engelsystem\Application;
use Engelsystem\Config\Config;
use Engelsystem\Container\Container;
use Engelsystem\Http\Request;
+use Engelsystem\Http\Response;
use Engelsystem\Renderer\Renderer;
use Engelsystem\Routing\UrlGeneratorInterface;
use PHPUnit\Framework\TestCase;
@@ -127,6 +128,33 @@ class HelpersTest extends TestCase
}
/**
+ * @covers \response
+ */
+ public function testResponse()
+ {
+ /** @var MockObject|Response $response */
+ $response = $this->getMockBuilder(Response::class)->getMock();
+ $this->getAppMock('psr7.response', $response);
+
+ $response->expects($this->once())
+ ->method('withContent')
+ ->with('Lorem Ipsum?')
+ ->willReturn($response);
+
+ $response->expects($this->once())
+ ->method('withStatus')
+ ->with(501)
+ ->willReturn($response);
+
+ $response->expects($this->exactly(2))
+ ->method('withAddedHeader')
+ ->withConsecutive(['lor', 'em'], ['foo', 'bar'])
+ ->willReturn($response);
+
+ $this->assertEquals($response, response('Lorem Ipsum?', 501, ['lor' => 'em', 'foo' => 'bar',]));
+ }
+
+ /**
* @covers \session
*/
public function testSession()
diff --git a/tests/Unit/Http/MessageTraitRequestTest.php b/tests/Unit/Http/MessageTraitRequestTest.php
new file mode 100644
index 00000000..7430b5d7
--- /dev/null
+++ b/tests/Unit/Http/MessageTraitRequestTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http;
+
+use Engelsystem\Test\Unit\Http\Stub\MessageTraitRequestImplementation;
+use PHPUnit\Framework\TestCase;
+use Zend\Diactoros\Stream;
+
+class MessageTraitRequestTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withProtocolVersion
+ */
+ public function testWithProtocolVersion()
+ {
+ $message = new MessageTraitRequestImplementation();
+ $newMessage = $message->withProtocolVersion('0.1');
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertEquals('0.1', $newMessage->getProtocolVersion());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getHeaders
+ */
+ public function testGetHeaders()
+ {
+ $message = new MessageTraitRequestImplementation();
+ $newMessage = $message->withHeader('lorem', 'ipsum');
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertArraySubset(['lorem' => ['ipsum']], $newMessage->getHeaders());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withBody
+ */
+ public function testWithBody()
+ {
+ /** @var Stream $stream */
+ $stream = new Stream('php://memory', 'wb+');
+ $stream->write('Test content');
+ $stream->rewind();
+
+ $message = new MessageTraitRequestImplementation();
+ $newMessage = $message->withBody($stream);
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertEquals('Test content', $newMessage->getContent());
+ }
+}
diff --git a/tests/Unit/Http/MessageTraitResponseTest.php b/tests/Unit/Http/MessageTraitResponseTest.php
new file mode 100644
index 00000000..f60360a3
--- /dev/null
+++ b/tests/Unit/Http/MessageTraitResponseTest.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http;
+
+use Engelsystem\Test\Unit\Http\Stub\MessageTraitResponseImplementation;
+use PHPUnit\Framework\TestCase;
+use Psr\Http\Message\MessageInterface;
+use Psr\Http\Message\StreamInterface;
+use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
+use Zend\Diactoros\Stream;
+
+class MessageTraitResponseTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Http\MessageTrait
+ */
+ public function testCreate()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $this->assertInstanceOf(MessageInterface::class, $message);
+ $this->assertInstanceOf(SymfonyResponse::class, $message);
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getProtocolVersion
+ * @covers \Engelsystem\Http\MessageTrait::withProtocolVersion
+ */
+ public function testGetProtocolVersion()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withProtocolVersion('0.1');
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertEquals('0.1', $newMessage->getProtocolVersion());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getHeaders
+ */
+ public function testGetHeaders()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withHeader('Foo', 'bar');
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertArraySubset(['Foo' => ['bar']], $newMessage->getHeaders());
+
+ $newMessage = $message->withHeader('lorem', ['ipsum', 'dolor']);
+ $this->assertArraySubset(['lorem' => ['ipsum', 'dolor']], $newMessage->getHeaders());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::hasHeader
+ */
+ public function testHasHeader()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $this->assertFalse($message->hasHeader('test'));
+
+ $newMessage = $message->withHeader('test', '12345');
+ $this->assertTrue($newMessage->hasHeader('Test'));
+ $this->assertTrue($newMessage->hasHeader('test'));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getHeader
+ */
+ public function testGetHeader()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withHeader('foo', 'bar');
+
+ $this->assertEquals(['bar'], $newMessage->getHeader('Foo'));
+ $this->assertEquals([], $newMessage->getHeader('LoremIpsum'));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getHeaderLine
+ */
+ public function testGetHeaderLine()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withHeader('foo', ['bar', 'bla']);
+
+ $this->assertEquals('', $newMessage->getHeaderLine('Lorem-Ipsum'));
+ $this->assertEquals('bar,bla', $newMessage->getHeaderLine('Foo'));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withHeader
+ */
+ public function testWithHeader()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withHeader('foo', 'bar');
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertArraySubset(['foo' => ['bar']], $newMessage->getHeaders());
+
+ $newMessage = $newMessage->withHeader('Foo', ['lorem', 'ipsum']);
+ $this->assertArraySubset(['Foo' => ['lorem', 'ipsum']], $newMessage->getHeaders());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withAddedHeader
+ */
+ public function testWithAddedHeader()
+ {
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withHeader('foo', 'bar');
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertArraySubset(['foo' => ['bar']], $newMessage->getHeaders());
+
+ $newMessage = $newMessage->withAddedHeader('Foo', ['lorem', 'ipsum']);
+ $this->assertArraySubset(['Foo' => ['bar', 'lorem', 'ipsum']], $newMessage->getHeaders());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withoutHeader
+ */
+ public function testWithoutHeader()
+ {
+ $message = (new MessageTraitResponseImplementation())->withHeader('foo', 'bar');
+ $this->assertTrue($message->hasHeader('foo'));
+
+ $newMessage = $message->withoutHeader('Foo');
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertFalse($newMessage->hasHeader('foo'));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::getBody
+ */
+ public function testGetBody()
+ {
+ $message = (new MessageTraitResponseImplementation())->setContent('Foo bar!');
+ $body = $message->getBody();
+
+ $this->assertInstanceOf(StreamInterface::class, $body);
+ $this->assertEquals('Foo bar!', $body->getContents());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\MessageTrait::withBody
+ */
+ public function testWithBody()
+ {
+ /** @var Stream $stream */
+ $stream = new Stream('php://memory', 'wb+');
+ $stream->write('Test content');
+ $stream->rewind();
+
+ $message = new MessageTraitResponseImplementation();
+ $newMessage = $message->withBody($stream);
+
+ $this->assertNotEquals($message, $newMessage);
+ $this->assertEquals('Test content', $newMessage->getContent());
+ }
+}
diff --git a/tests/Unit/Http/Psr7ServiceProviderTest.php b/tests/Unit/Http/Psr7ServiceProviderTest.php
new file mode 100644
index 00000000..e14daf2a
--- /dev/null
+++ b/tests/Unit/Http/Psr7ServiceProviderTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http;
+
+use Engelsystem\Http\Psr7ServiceProvider;
+use Engelsystem\Http\Request;
+use Engelsystem\Http\Response;
+use Engelsystem\Test\Unit\ServiceProviderTest;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface as RequestInterface;
+use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
+
+class Psr7ServiceProviderTest extends ServiceProviderTest
+{
+ /**
+ * @covers \Engelsystem\Http\Psr7ServiceProvider::register()
+ */
+ public function testRegister()
+ {
+ /** @var MockObject|DiactorosFactory $psr7Factory */
+ $psr7Factory = $this->createMock(DiactorosFactory::class);
+ /** @var MockObject|Request $request */
+ $request = $this->createMock(Request::class);
+ /** @var MockObject|Response $response */
+ $response = $this->createMock(Response::class);
+ /** @var MockObject|RequestInterface $psr7request */
+ $psr7request = $this->createMock(Request::class);
+ /** @var MockObject|ResponseInterface $psr7response */
+ $psr7response = $this->createMock(Response::class);
+
+ $app = $this->getApp(['make', 'instance', 'get', 'bind']);
+ $this->setExpects($app, 'make', [DiactorosFactory::class], $psr7Factory);
+
+ $app->expects($this->atLeastOnce())
+ ->method('get')
+ ->withConsecutive(['request'], ['response'])
+ ->willReturnOnConsecutiveCalls($request, $response);
+ $app->expects($this->atLeastOnce())
+ ->method('instance')
+ ->withConsecutive(
+ ['psr7.factory', $psr7Factory],
+ ['psr7.request', $psr7request],
+ ['psr7.response', $psr7response]
+ );
+ $app->expects($this->atLeastOnce())
+ ->method('bind')
+ ->withConsecutive(
+ [RequestInterface::class, 'psr7.request'],
+ [ResponseInterface::class, 'psr7.response']
+ );
+
+ $serviceProvider = new Psr7ServiceProvider($app);
+ $serviceProvider->register();
+ }
+}
diff --git a/tests/Unit/Http/RequestTest.php b/tests/Unit/Http/RequestTest.php
index a68f8b8f..916aac35 100644
--- a/tests/Unit/Http/RequestTest.php
+++ b/tests/Unit/Http/RequestTest.php
@@ -5,10 +5,25 @@ namespace Engelsystem\Test\Unit\Http;
use Engelsystem\Http\Request;
use PHPUnit\Framework\TestCase;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\RequestInterface;
+use Psr\Http\Message\UploadedFileInterface;
+use Psr\Http\Message\UriInterface;
+use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyFile;
+use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
class RequestTest extends TestCase
{
/**
+ * @covers \Engelsystem\Http\Request
+ */
+ public function testCreate()
+ {
+ $response = new Request();
+ $this->assertInstanceOf(SymfonyRequest::class, $response);
+ $this->assertInstanceOf(RequestInterface::class, $response);
+ }
+
+ /**
* @covers \Engelsystem\Http\Request::postData
*/
public function testPostData()
@@ -96,4 +111,272 @@ class RequestTest extends TestCase
$this->assertEquals('http://foo.bar/bla/foo', $request->url());
$this->assertEquals('https://lorem.ipsum/dolor/sit', $request->url());
}
+
+ /**
+ * @covers \Engelsystem\Http\Request::getRequestTarget
+ */
+ public function testGetRequestTarget()
+ {
+ /** @var Request|MockObject $request */
+ $request = $this
+ ->getMockBuilder(Request::class)
+ ->setMethods(['getQueryString', 'path'])
+ ->getMock();
+
+ $request->expects($this->exactly(2))
+ ->method('getQueryString')
+ ->willReturnOnConsecutiveCalls(null, 'foo=bar&lorem=ipsum');
+ $request->expects($this->exactly(2))
+ ->method('path')
+ ->willReturn('foo/bar');
+
+ $this->assertEquals('/foo/bar', $request->getRequestTarget());
+ $this->assertEquals('/foo/bar?foo=bar&lorem=ipsum', $request->getRequestTarget());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withRequestTarget
+ */
+ public function testWithRequestTarget()
+ {
+ $request = new Request();
+ foreach (
+ [
+ '*',
+ '/foo/bar',
+ 'https://lorem.ipsum/test?lor=em'
+ ] as $target
+ ) {
+ $new = $request->withRequestTarget($target);
+ $this->assertNotEquals($request, $new);
+ }
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withMethod
+ */
+ public function testWithMethod()
+ {
+ $request = new Request();
+
+ $new = $request->withMethod('PUT');
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals('PUT', $new->getMethod());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withUri
+ */
+ public function testWithUri()
+ {
+ /** @var UriInterface|MockObject $uri */
+ $uri = $this->getMockForAbstractClass(UriInterface::class);
+
+ $uri->expects($this->atLeastOnce())
+ ->method('__toString')
+ ->willReturn('http://foo.bar/bla?foo=bar');
+
+ $request = Request::create('http://lor.em/');
+
+ $new = $request->withUri($uri);
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals('http://foo.bar/bla?foo=bar', (string)$new->getUri());
+
+ $new = $request->withUri($uri, true);
+ $this->assertEquals('http://lor.em/bla?foo=bar', (string)$new->getUri());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getUri
+ */
+ public function testGetUri()
+ {
+ $request = Request::create('http://lor.em/test?bla=foo');
+
+ $uri = $request->getUri();
+ $this->assertInstanceOf(UriInterface::class, $uri);
+ $this->assertEquals('http://lor.em/test?bla=foo', (string)$uri);
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getServerParams
+ */
+ public function testGetServerParams()
+ {
+ $server = ['foo' => 'bar'];
+ $request = new Request([], [], [], [], [], $server);
+
+ $this->assertEquals($server, $request->getServerParams());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getCookieParams
+ */
+ public function testGetCookieParams()
+ {
+ $cookies = ['session' => 'LoremIpsumDolorSit'];
+ $request = new Request([], [], [], $cookies);
+
+ $this->assertEquals($cookies, $request->getCookieParams());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withCookieParams
+ */
+ public function testWithCookieParams()
+ {
+ $cookies = ['lor' => 'em'];
+ $request = new Request();
+
+ $new = $request->withCookieParams($cookies);
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals($cookies, $new->getCookieParams());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getQueryParams
+ */
+ public function testGetQueryParams()
+ {
+ $params = ['foo' => 'baz'];
+ $request = new Request($params);
+
+ $this->assertEquals($params, $request->getQueryParams());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withQueryParams
+ */
+ public function testWithQueryParams()
+ {
+ $params = ['test' => 'ing'];
+ $request = new Request();
+
+ $new = $request->withQueryParams($params);
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals($params, $new->getQueryParams());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getUploadedFiles
+ */
+ public function testGetUploadedFiles()
+ {
+ $filename = tempnam(sys_get_temp_dir(), 'test');
+ file_put_contents($filename, 'LoremIpsum!');
+ $files = [new SymfonyFile($filename, 'foo.html', 'text/html', 11)];
+ $request = new Request([], [], [], [], $files);
+
+ $uploadedFiles = $request->getUploadedFiles();
+ $this->assertNotEmpty($uploadedFiles);
+
+ /** @var UploadedFileInterface $file */
+ $file = $uploadedFiles[0];
+ $this->assertInstanceOf(UploadedFileInterface::class, $file);
+ $this->assertEquals('foo.html', $file->getClientFilename());
+ $this->assertEquals('text/html', $file->getClientMediaType());
+ $this->assertEquals(11, $file->getSize());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withUploadedFiles
+ */
+ public function testWithUploadedFiles()
+ {
+ $filename = tempnam(sys_get_temp_dir(), 'test');
+ file_put_contents($filename, 'LoremIpsum!');
+ $file = new \Zend\Diactoros\UploadedFile($filename, 11, UPLOAD_ERR_OK, 'test.txt', 'text/plain');
+
+ $request = new Request();
+ $new = $request->withUploadedFiles([$file]);
+ $uploadedFiles = $new->getUploadedFiles();
+ $this->assertNotEquals($request, $new);
+ $this->assertNotEmpty($uploadedFiles);
+
+ /** @var UploadedFileInterface $file */
+ $file = $uploadedFiles[0];
+ $this->assertEquals('test.txt', $file->getClientFilename());
+ $this->assertEquals('text/plain', $file->getClientMediaType());
+ $this->assertEquals(11, $file->getSize());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getParsedBody
+ */
+ public function testGetParsedBody()
+ {
+ $body = ['foo' => 'lorem'];
+ $request = new Request();
+ $request->request->add($body);
+
+ $this->assertEquals($body, $request->getParsedBody());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withParsedBody
+ */
+ public function testWithParsedBody()
+ {
+ $data = ['test' => 'er'];
+ $request = new Request();
+
+ $new = $request->withParsedBody($data);
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals($data, $new->getParsedBody());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getAttributes
+ */
+ public function testGetAttributes()
+ {
+ $attributes = ['foo' => 'lorem', 'ipsum' => 'dolor'];
+ $request = new Request([], [], $attributes);
+
+ $this->assertEquals($attributes, $request->getAttributes());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::getAttribute
+ */
+ public function testGetAttribute()
+ {
+ $attributes = ['foo' => 'lorem', 'ipsum' => 'dolor'];
+ $request = new Request([], [], $attributes);
+
+ $this->assertEquals($attributes['ipsum'], $request->getAttribute('ipsum'));
+ $this->assertEquals(null, $request->getAttribute('dolor'));
+ $this->assertEquals(1234, $request->getAttribute('test', 1234));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withAttribute
+ */
+ public function testWithAttribute()
+ {
+ $request = new Request();
+
+ $new = $request->withAttribute('lorem', 'ipsum');
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals('ipsum', $new->getAttribute('lorem'));
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Request::withoutAttribute
+ */
+ public function testWithoutAttribute()
+ {
+ $attributes = ['foo' => 'lorem', 'ipsum' => 'dolor'];
+ $request = new Request([], [], $attributes);
+
+ $new = $request->withoutAttribute('ipsum');
+
+ $this->assertNotEquals($request, $new);
+ $this->assertEquals(['foo' => 'lorem'], $new->getAttributes());
+ }
}
diff --git a/tests/Unit/Http/ResponseServiceProviderTest.php b/tests/Unit/Http/ResponseServiceProviderTest.php
new file mode 100644
index 00000000..52e95714
--- /dev/null
+++ b/tests/Unit/Http/ResponseServiceProviderTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http;
+
+use Engelsystem\Http\Response;
+use Engelsystem\Http\ResponseServiceProvider;
+use Engelsystem\Test\Unit\ServiceProviderTest;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+class ResponseServiceProviderTest extends ServiceProviderTest
+{
+ /**
+ * @covers \Engelsystem\Http\ResponseServiceProvider::register()
+ */
+ public function testRegister()
+ {
+ /** @var MockObject|Response $response */
+ $response = $this->getMockBuilder(Response::class)
+ ->getMock();
+
+ $app = $this->getApp();
+
+ $this->setExpects($app, 'make', [Response::class], $response);
+ $this->setExpects($app, 'instance', ['response', $response]);
+
+ $serviceProvider = new ResponseServiceProvider($app);
+ $serviceProvider->register();
+ }
+}
diff --git a/tests/Unit/Http/ResponseTest.php b/tests/Unit/Http/ResponseTest.php
new file mode 100644
index 00000000..f6c24767
--- /dev/null
+++ b/tests/Unit/Http/ResponseTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http;
+
+use Engelsystem\Http\Response;
+use PHPUnit\Framework\TestCase;
+use Psr\Http\Message\ResponseInterface;
+use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
+
+class ResponseTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Http\Response
+ */
+ public function testCreate()
+ {
+ $response = new Response();
+ $this->assertInstanceOf(SymfonyResponse::class, $response);
+ $this->assertInstanceOf(ResponseInterface::class, $response);
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Response::withStatus
+ * @covers \Engelsystem\Http\Response::getReasonPhrase
+ */
+ public function testWithStatus()
+ {
+ $response = new Response();
+ $newResponse = $response->withStatus(503);
+ $this->assertNotEquals($response, $newResponse);
+ $this->assertNotEquals('', $newResponse->getReasonPhrase());
+ $this->assertEquals(503, $newResponse->getStatusCode());
+
+ $newResponse = $response->withStatus(503, 'Foo');
+ $this->assertEquals('Foo', $newResponse->getReasonPhrase());
+ }
+
+ /**
+ * @covers \Engelsystem\Http\Response::withContent
+ */
+ public function testWithContent()
+ {
+ $response = new Response();
+ $newResponse = $response->withContent('Lorem Ipsum?');
+
+ $this->assertNotEquals($response, $newResponse);
+ $this->assertEquals('Lorem Ipsum?', $newResponse->getContent());
+ }
+}
diff --git a/tests/Unit/Http/Stub/MessageTraitRequestImplementation.php b/tests/Unit/Http/Stub/MessageTraitRequestImplementation.php
new file mode 100644
index 00000000..04d08913
--- /dev/null
+++ b/tests/Unit/Http/Stub/MessageTraitRequestImplementation.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http\Stub;
+
+use Engelsystem\Http\MessageTrait;
+use Psr\Http\Message\MessageInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+class MessageTraitRequestImplementation extends Request implements MessageInterface
+{
+ use MessageTrait;
+}
diff --git a/tests/Unit/Http/Stub/MessageTraitResponseImplementation.php b/tests/Unit/Http/Stub/MessageTraitResponseImplementation.php
new file mode 100644
index 00000000..2ec4b943
--- /dev/null
+++ b/tests/Unit/Http/Stub/MessageTraitResponseImplementation.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Http\Stub;
+
+use Engelsystem\Http\MessageTrait;
+use Psr\Http\Message\MessageInterface;
+use Symfony\Component\HttpFoundation\Response;
+
+class MessageTraitResponseImplementation extends Response implements MessageInterface
+{
+ use MessageTrait;
+}
diff --git a/tests/Unit/Middleware/DispatcherTest.php b/tests/Unit/Middleware/DispatcherTest.php
new file mode 100644
index 00000000..c01c5029
--- /dev/null
+++ b/tests/Unit/Middleware/DispatcherTest.php
@@ -0,0 +1,230 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Application;
+use Engelsystem\Middleware\Dispatcher;
+use Engelsystem\Test\Unit\Middleware\Stub\NotARealMiddleware;
+use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddleware;
+use InvalidArgumentException;
+use LogicException;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use ReflectionClass as Reflection;
+
+class DispatcherTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::__construct
+ */
+ public function testInit()
+ {
+ /** @var Application|MockObject $container */
+ $container = $this->createMock(Application::class);
+
+ $dispatcher = new Dispatcher([], $container);
+ $this->assertInstanceOf(MiddlewareInterface::class, $dispatcher);
+ $this->assertInstanceOf(RequestHandlerInterface::class, $dispatcher);
+
+ $reflection = new Reflection(get_class($dispatcher));
+ $property = $reflection->getProperty('container');
+ $property->setAccessible(true);
+ $this->assertEquals($container, $property->getValue($dispatcher));
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::process
+ */
+ public function testProcess()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->createMock(ResponseInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->createMock(RequestHandlerInterface::class);
+
+ /** @var Dispatcher|MockObject $dispatcher */
+ $dispatcher = $this->getMockBuilder(Dispatcher::class)
+ ->setMethods(['handle'])
+ ->getMock();
+
+ $dispatcher->expects($this->once())
+ ->method('handle')
+ ->willReturn($response);
+
+ $return = $dispatcher->process($request, $handler);
+ $this->assertEquals($response, $return);
+
+ $reflection = new Reflection(get_class($dispatcher));
+ $property = $reflection->getProperty('next');
+ $property->setAccessible(true);
+
+ $this->assertEquals($handler, $property->getValue($dispatcher));
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::handle
+ */
+ public function testHandle()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->createMock(ResponseInterface::class);
+ /** @var MiddlewareInterface|MockObject $middleware */
+ $middleware = $this->createMock(MiddlewareInterface::class);
+
+ $dispatcher = new Dispatcher([$middleware]);
+ $middleware->expects($this->once())
+ ->method('process')
+ ->with($request, $dispatcher)
+ ->willReturn($response);
+
+ $return = $dispatcher->handle($request);
+ $this->assertEquals($response, $return);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::handle
+ */
+ public function testHandleNext()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->createMock(ResponseInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->createMock(RequestHandlerInterface::class);
+
+ $dispatcher = new Dispatcher();
+ $handler->expects($this->once())
+ ->method('handle')
+ ->with($request)
+ ->willReturn($response);
+
+ $reflection = new Reflection(get_class($dispatcher));
+ $property = $reflection->getProperty('next');
+ $property->setAccessible(true);
+ $property->setValue($dispatcher, $handler);
+
+ $return = $dispatcher->handle($request);
+ $this->assertEquals($response, $return);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::handle
+ */
+ public function testHandleNoMiddleware()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+
+ $this->expectException(LogicException::class);
+
+ $dispatcher = new Dispatcher();
+ $dispatcher->handle($request);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::handle
+ */
+ public function testHandleNoRealMiddleware()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+
+ $this->expectException(InvalidArgumentException::class);
+
+ $dispatcher = new Dispatcher([new NotARealMiddleware()]);
+ $dispatcher->handle($request);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::handle
+ */
+ public function testHandleCallResolve()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->createMock(ResponseInterface::class);
+ /** @var MiddlewareInterface|MockObject $middleware */
+ $middleware = $this->createMock(MiddlewareInterface::class);
+
+ /** @var Dispatcher|MockObject $dispatcher */
+ $dispatcher = $this->getMockBuilder(Dispatcher::class)
+ ->setConstructorArgs([[MiddlewareInterface::class]])
+ ->setMethods(['resolveMiddleware'])
+ ->getMock();
+
+ $dispatcher->expects($this->once())
+ ->method('resolveMiddleware')
+ ->with(MiddlewareInterface::class)
+ ->willReturn($middleware);
+
+ $middleware->expects($this->once())
+ ->method('process')
+ ->with($request, $dispatcher)
+ ->willReturn($response);
+
+ $return = $dispatcher->handle($request);
+ $this->assertEquals($response, $return);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::resolveMiddleware
+ * @covers \Engelsystem\Middleware\Dispatcher::setContainer
+ */
+ public function testResolveMiddleware()
+ {
+ /** @var Application|MockObject $container */
+ $container = $this->createMock(Application::class);
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->createMock(ResponseInterface::class);
+
+ $returnResponseMiddleware = new ReturnResponseMiddleware($response);
+
+ $container->expects($this->exactly(2))
+ ->method('has')
+ ->withConsecutive([ReturnResponseMiddleware::class], ['middleware'])
+ ->willReturnOnConsecutiveCalls(false, true);
+
+ $container->expects($this->once())
+ ->method('make')
+ ->with(ReturnResponseMiddleware::class)
+ ->willReturn($returnResponseMiddleware);
+
+ $container->expects($this->once())
+ ->method('get')
+ ->with('middleware')
+ ->willReturn($returnResponseMiddleware);
+
+ $dispatcher = new Dispatcher([ReturnResponseMiddleware::class]);
+ $dispatcher->setContainer($container);
+ $dispatcher->handle($request);
+
+ $dispatcher = new Dispatcher(['middleware'], $container);
+ $dispatcher->handle($request);
+ }
+
+ /**
+ * @covers \Engelsystem\Middleware\Dispatcher::resolveMiddleware
+ */
+ public function testResolveMiddlewareNoContainer()
+ {
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->createMock(ServerRequestInterface::class);
+
+ $this->expectException(InvalidArgumentException::class);
+
+ $dispatcher = new Dispatcher([ReturnResponseMiddleware::class]);
+ $dispatcher->handle($request);
+ }
+}
diff --git a/tests/Unit/Middleware/ExceptionHandlerTest.php b/tests/Unit/Middleware/ExceptionHandlerTest.php
new file mode 100644
index 00000000..6d2a20e6
--- /dev/null
+++ b/tests/Unit/Middleware/ExceptionHandlerTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Application;
+use Engelsystem\Exceptions\Handler;
+use Engelsystem\Http\Response;
+use Engelsystem\Middleware\ExceptionHandler;
+use Engelsystem\Test\Unit\Middleware\Stub\ExceptionMiddlewareHandler;
+use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddlewareHandler;
+use Illuminate\Contracts\Container\Container as ContainerInterface;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+
+class ExceptionHandlerTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\ExceptionHandler::__construct
+ * @covers \Engelsystem\Middleware\ExceptionHandler::process
+ */
+ public function testRegister()
+ {
+ /** @var MockObject|ContainerInterface $container */
+ $container = $this->getMockForAbstractClass(ContainerInterface::class);
+ /** @var MockObject|ServerRequestInterface $request */
+ $request = $this->getMockBuilder(ServerRequestInterface::class)->getMock();
+ /** @var MockObject|ResponseInterface $response */
+ $response = $this->getMockBuilder(Response::class)->getMock();
+ /** @var MockObject|Handler $errorHandler */
+ $errorHandler = $this->getMockBuilder(Handler::class)->getMock();
+ $returnResponseHandler = new ReturnResponseMiddlewareHandler($response);
+ $throwExceptionHandler = new ExceptionMiddlewareHandler();
+
+ Application::setInstance($container);
+
+ $container->expects($this->exactly(2))
+ ->method('get')
+ ->withConsecutive(['error.handler'], ['psr7.response'])
+ ->willReturnOnConsecutiveCalls($errorHandler, $response);
+
+ $response->expects($this->once())
+ ->method('withContent')
+ ->willReturn($response);
+ $response->expects($this->once())
+ ->method('withStatus')
+ ->with(500)
+ ->willReturn($response);
+
+ $handler = new ExceptionHandler($container);
+ $return = $handler->process($request, $returnResponseHandler);
+ $this->assertEquals($response, $return);
+
+ $return = $handler->process($request, $throwExceptionHandler);
+ $this->assertEquals($response, $return);
+ }
+}
diff --git a/tests/Unit/Middleware/LegacyMiddlewareTest.php b/tests/Unit/Middleware/LegacyMiddlewareTest.php
new file mode 100644
index 00000000..34e60b60
--- /dev/null
+++ b/tests/Unit/Middleware/LegacyMiddlewareTest.php
@@ -0,0 +1,85 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Http\Request;
+use Engelsystem\Middleware\LegacyMiddleware;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Container\ContainerInterface;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpFoundation\ParameterBag;
+
+class LegacyMiddlewareTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\LegacyMiddleware::__construct
+ * @covers \Engelsystem\Middleware\LegacyMiddleware::process
+ */
+ public function testRegister()
+ {
+ /** @var ContainerInterface|MockObject $container */
+ $container = $this->getMockForAbstractClass(ContainerInterface::class);
+ /** @var LegacyMiddleware|MockObject $middleware */
+ $middleware = $this->getMockBuilder(LegacyMiddleware::class)
+ ->setConstructorArgs([$container])
+ ->setMethods(['loadPage', 'renderPage'])
+ ->getMock();
+ /** @var Request|MockObject $defaultRequest */
+ $defaultRequest = $this->createMock(Request::class);
+ /** @var ParameterBag|MockObject $parameters */
+ $parameters = $this->createMock(ParameterBag::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->getMockForAbstractClass(ResponseInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->getMockForAbstractClass(ServerRequestInterface::class);
+
+ $middleware->expects($this->exactly(2))
+ ->method('loadPage')
+ ->withConsecutive(['user_worklog'], ['login'])
+ ->willReturnOnConsecutiveCalls(
+ ['title', 'content'],
+ ['title2', 'content2']
+ );
+
+ $middleware->expects($this->exactly(2))
+ ->method('renderPage')
+ ->withConsecutive(
+ ['user_worklog', 'title', 'content'],
+ ['login', 'title2', 'content2']
+ )
+ ->willReturn($response);
+
+ $container->expects($this->atLeastOnce())
+ ->method('get')
+ ->with('request')
+ ->willReturn($defaultRequest);
+
+ $defaultRequest->query = $parameters;
+ $defaultRequest->expects($this->once())
+ ->method('path')
+ ->willReturn('user-worklog');
+
+ $parameters->expects($this->exactly(3))
+ ->method('get')
+ ->with('p')
+ ->willReturnOnConsecutiveCalls(
+ null,
+ 'foo',
+ '/'
+ );
+
+ $handler->expects($this->once())
+ ->method('handle')
+ ->with($request)
+ ->willReturn($response);
+
+ $middleware->process($request, $handler);
+ $middleware->process($request, $handler);
+ $middleware->process($request, $handler);
+ }
+}
diff --git a/tests/Unit/Middleware/NotFoundResponseTest.php b/tests/Unit/Middleware/NotFoundResponseTest.php
new file mode 100644
index 00000000..9279e81d
--- /dev/null
+++ b/tests/Unit/Middleware/NotFoundResponseTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Middleware\NotFoundResponse;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class NotFoundResponseTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\NotFoundResponse::process
+ */
+ public function testRegister()
+ {
+ /** @var NotFoundResponse|MockObject $middleware */
+ $middleware = $this->getMockBuilder(NotFoundResponse::class)
+ ->setMethods(['renderPage'])
+ ->getMock();
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->getMockForAbstractClass(ResponseInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->getMockForAbstractClass(ServerRequestInterface::class);
+
+ $middleware->expects($this->once())
+ ->method('renderPage')
+ ->willReturn($response);
+
+ $handler->expects($this->never())
+ ->method('handle');
+
+ $middleware->process($request, $handler);
+ }
+}
diff --git a/tests/Unit/Middleware/SendResponseHandlerTest.php b/tests/Unit/Middleware/SendResponseHandlerTest.php
new file mode 100644
index 00000000..7431299e
--- /dev/null
+++ b/tests/Unit/Middleware/SendResponseHandlerTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware;
+
+use Engelsystem\Middleware\SendResponseHandler;
+use PHPUnit\Framework\TestCase;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class SendResponseHandlerTest extends TestCase
+{
+ /**
+ * @covers \Engelsystem\Middleware\SendResponseHandler::process
+ */
+ public function testRegister()
+ {
+ /** @var SendResponseHandler|MockObject $middleware */
+ $middleware = $this->getMockBuilder(SendResponseHandler::class)
+ ->setMethods(['headersSent', 'sendHeader'])
+ ->getMock();
+ /** @var ServerRequestInterface|MockObject $request */
+ $request = $this->getMockForAbstractClass(ServerRequestInterface::class);
+ /** @var ResponseInterface|MockObject $response */
+ $response = $this->getMockForAbstractClass(ResponseInterface::class);
+ /** @var RequestHandlerInterface|MockObject $handler */
+ $handler = $this->getMockForAbstractClass(RequestHandlerInterface::class);
+
+ $middleware->expects($this->atLeastOnce())
+ ->method('headersSent')
+ ->willReturnOnConsecutiveCalls(true, false);
+
+ $middleware->expects($this->exactly(4))
+ ->method('sendHeader')
+ ->withConsecutive(
+ ['HTTP/0.7 505 Something went wrong!', true, 505],
+ ['Foo: bar', false],
+ ['lorem: ipsum', false],
+ ['lorem: dolor', false]
+ );
+
+ $handler->expects($this->exactly(2))
+ ->method('handle')
+ ->with($request)
+ ->willReturn($response);
+
+ $response->expects($this->exactly(2))
+ ->method('getBody')
+ ->willReturn('Lorem Ipsum!');
+
+ $response->expects($this->atLeastOnce())
+ ->method('getProtocolVersion')
+ ->willReturn('0.7');
+
+ $response->expects($this->atLeastOnce())
+ ->method('getStatusCode')
+ ->willReturn(505);
+
+ $response->expects($this->once())
+ ->method('getReasonPhrase')
+ ->willReturn('Something went wrong!');
+ $response->expects($this->once())
+ ->method('getHeaders')
+ ->willReturn(['Foo' => ['bar'], 'lorem' => ['ipsum', 'dolor']]);
+
+ $this->expectOutputString('Lorem Ipsum!Lorem Ipsum!');
+ $middleware->process($request, $handler);
+ $middleware->process($request, $handler);
+ }
+}
diff --git a/tests/Unit/Middleware/Stub/ExceptionMiddlewareHandler.php b/tests/Unit/Middleware/Stub/ExceptionMiddlewareHandler.php
new file mode 100644
index 00000000..5e374bea
--- /dev/null
+++ b/tests/Unit/Middleware/Stub/ExceptionMiddlewareHandler.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware\Stub;
+
+use Exception;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class ExceptionMiddlewareHandler implements RequestHandlerInterface
+{
+ /**
+ * Throws an exception
+ *
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
+ * @throws Exception
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ throw new Exception('Boooom!');
+ }
+}
diff --git a/tests/Unit/Middleware/Stub/NotARealMiddleware.php b/tests/Unit/Middleware/Stub/NotARealMiddleware.php
new file mode 100644
index 00000000..017389da
--- /dev/null
+++ b/tests/Unit/Middleware/Stub/NotARealMiddleware.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware\Stub;
+
+class NotARealMiddleware
+{
+ // I'm not a middleware!
+}
diff --git a/tests/Unit/Middleware/Stub/ReturnResponseMiddleware.php b/tests/Unit/Middleware/Stub/ReturnResponseMiddleware.php
new file mode 100644
index 00000000..7c241353
--- /dev/null
+++ b/tests/Unit/Middleware/Stub/ReturnResponseMiddleware.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware\Stub;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class ReturnResponseMiddleware implements MiddlewareInterface
+{
+ /** @var ResponseInterface */
+ protected $response;
+
+ public function __construct(ResponseInterface $response)
+ {
+ $this->response = $response;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * response creation to a handler.
+ *
+ * Could be used to group middleware
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(
+ ServerRequestInterface $request,
+ RequestHandlerInterface $handler
+ ): ResponseInterface {
+ return $this->response;
+ }
+}
diff --git a/tests/Unit/Middleware/Stub/ReturnResponseMiddlewareHandler.php b/tests/Unit/Middleware/Stub/ReturnResponseMiddlewareHandler.php
new file mode 100644
index 00000000..323e07b4
--- /dev/null
+++ b/tests/Unit/Middleware/Stub/ReturnResponseMiddlewareHandler.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Engelsystem\Test\Unit\Middleware\Stub;
+
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class ReturnResponseMiddlewareHandler implements RequestHandlerInterface
+{
+ /** @var ResponseInterface */
+ protected $response;
+
+ public function __construct(ResponseInterface $response)
+ {
+ $this->response = $response;
+ }
+
+ /**
+ * Returns a given response
+ *
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
+ * @throws \Exception
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ return $this->response;
+ }
+}