diff --git a/src/Entities/Traits/ClientTrait.php b/src/Entities/Traits/ClientTrait.php
index bf5fb97d..db01649d 100644
--- a/src/Entities/Traits/ClientTrait.php
+++ b/src/Entities/Traits/ClientTrait.php
@@ -12,6 +12,7 @@ trait ClientTrait
      * Get the client's name.
      *
      * @return string
+     * @codeCoverageIgnore
      */
     public function getName()
     {
diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php
index 1f08919c..2e4d8e18 100644
--- a/src/Exception/OAuthServerException.php
+++ b/src/Exception/OAuthServerException.php
@@ -119,6 +119,8 @@ class OAuthServerException extends \Exception
      * @param $hint
      *
      * @return static
+     *
+     * @codeCoverageIgnore
      */
     public static function serverError($hint)
     {
diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php
index 6f3a5611..92cefe44 100644
--- a/src/Grant/AuthCodeGrant.php
+++ b/src/Grant/AuthCodeGrant.php
@@ -234,6 +234,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant
                     ]
                 )
             );
+            $redirectPayload['state'] = $authorizationRequest->getState();
 
             $response = new RedirectResponse();
             $response->setRedirectUri(
diff --git a/src/RequestEvent.php b/src/RequestEvent.php
index d8f7da08..3170beab 100644
--- a/src/RequestEvent.php
+++ b/src/RequestEvent.php
@@ -26,6 +26,7 @@ class RequestEvent extends Event
 
     /**
      * @return ServerRequestInterface
+     * @codeCoverageIgnore
      */
     public function getRequest()
     {
diff --git a/tests/CryptTraitTest.php b/tests/CryptTraitTest.php
index 364d712f..d0ada49e 100644
--- a/tests/CryptTraitTest.php
+++ b/tests/CryptTraitTest.php
@@ -44,4 +44,12 @@ class CryptTraitTest extends \PHPUnit_Framework_TestCase
         $this->cryptStub->setPublicKey(new CryptKey(__DIR__ . '/Stubs/private.key'));
         $this->cryptStub->doDecrypt('');
     }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testNonExistentKey()
+    {
+        new CryptKey('foo/bar');
+    }
 }
diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php
index 1321654d..0c4f6ae7 100644
--- a/tests/Grant/AbstractGrantTest.php
+++ b/tests/Grant/AbstractGrantTest.php
@@ -13,6 +13,7 @@ use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface;
 use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
+use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
 use LeagueTests\Stubs\AccessTokenEntity;
 use LeagueTests\Stubs\AuthCodeEntity;
 use LeagueTests\Stubs\ClientEntity;
@@ -402,4 +403,28 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase
 
         $this->assertTrue(is_string($method->invoke($grantMock)));
     }
+
+    public function testCanRespondToAuthorizationRequest()
+    {
+        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
+        $this->assertFalse($grantMock->canRespondToAuthorizationRequest(new ServerRequest()));
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testValidateAuthorizationRequest()
+    {
+        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
+        $grantMock->validateAuthorizationRequest(new ServerRequest());
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testCompleteAuthorizationRequest()
+    {
+        $grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
+        $grantMock->completeAuthorizationRequest(new AuthorizationRequest());
+    }
 }
diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php
index 4acfba9b..93dfcae6 100644
--- a/tests/Grant/AuthCodeGrantTest.php
+++ b/tests/Grant/AuthCodeGrantTest.php
@@ -24,7 +24,6 @@ use LeagueTests\Stubs\RefreshTokenEntity;
 use LeagueTests\Stubs\ScopeEntity;
 use LeagueTests\Stubs\StubResponseType;
 use LeagueTests\Stubs\UserEntity;
-use Psr\Http\Message\ResponseInterface;
 use Zend\Diactoros\Response;
 use Zend\Diactoros\ServerRequest;
 
diff --git a/tests/Middleware/AuthenticationServerMiddlewareTest.php b/tests/Middleware/AuthenticationServerMiddlewareTest.php
index d5f82594..d9302cae 100644
--- a/tests/Middleware/AuthenticationServerMiddlewareTest.php
+++ b/tests/Middleware/AuthenticationServerMiddlewareTest.php
@@ -2,6 +2,7 @@
 
 namespace LeagueTests\Middleware;
 
+use League\OAuth2\Server\Exception\OAuthServerException;
 use League\OAuth2\Server\Grant\ClientCredentialsGrant;
 use League\OAuth2\Server\Middleware\AuthenticationServerMiddleware;
 use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
@@ -36,7 +37,7 @@ class AuthenticationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
             new StubResponseType()
         );
 
-        $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M'));
+        $server->enableGrantType(new ClientCredentialsGrant());
 
         $_POST['grant_type'] = 'client_credentials';
         $_POST['client_id'] = 'foo';
@@ -89,4 +90,22 @@ class AuthenticationServerMiddlewareTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals(401, $response->getStatusCode());
     }
+
+    public function testOAuthErrorResponseRedirectUri()
+    {
+        $exception = OAuthServerException::invalidScope('test', 'http://foo/bar');
+        $response = $exception->generateHttpResponse(new Response());
+
+        $this->assertEquals(302, $response->getStatusCode());
+        $this->assertEquals('http://foo/bar?error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $response->getHeader('location')[0]);
+    }
+
+    public function testOAuthErrorResponseRedirectUriFragment()
+    {
+        $exception = OAuthServerException::invalidScope('test', 'http://foo/bar');
+        $response = $exception->generateHttpResponse(new Response(), true);
+
+        $this->assertEquals(302, $response->getStatusCode());
+        $this->assertEquals('http://foo/bar#error=invalid_scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope', $response->getHeader('location')[0]);
+    }
 }
diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php
index 5656d3d1..a71dc5ab 100644
--- a/tests/Middleware/ResourceServerMiddlewareTest.php
+++ b/tests/Middleware/ResourceServerMiddlewareTest.php
@@ -57,6 +57,47 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(200, $response->getStatusCode());
     }
 
+    public function testValidResponseExpiredToken()
+    {
+        $clientRepository = $this->getMock(ClientRepositoryInterface::class);
+
+        $server = new Server(
+            $clientRepository,
+            $this->getMock(AccessTokenRepositoryInterface::class),
+            $this->getMock(ScopeRepositoryInterface::class),
+            'file://' . __DIR__ . '/../Stubs/private.key',
+            'file://' . __DIR__ . '/../Stubs/public.key',
+            new StubResponseType()
+        );
+
+        $client = new ClientEntity();
+        $client->setIdentifier('clientName');
+
+        $accessToken = new AccessTokenEntity();
+        $accessToken->setIdentifier('test');
+        $accessToken->setUserIdentifier(123);
+        $accessToken->setExpiryDateTime((new \DateTime())->sub(new \DateInterval('PT1H')));
+        $accessToken->setClient($client);
+
+        $token = $accessToken->convertToJWT(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key'));
+
+        $request = new ServerRequest();
+        $request = $request->withHeader('authorization', sprintf('Bearer %s', $token));
+
+        $middleware = new ResourceServerMiddleware($server);
+        $response = $middleware->__invoke(
+            $request,
+            new Response(),
+            function () {
+                $this->assertEquals('test', func_get_args()[0]->getAttribute('oauth_access_token_id'));
+
+                return func_get_args()[1];
+            }
+        );
+
+        $this->assertEquals(401, $response->getStatusCode());
+    }
+
     public function testErrorResponse()
     {
         $clientRepository = $this->getMock(ClientRepositoryInterface::class);
diff --git a/tests/ServerTest.php b/tests/ServerTest.php
index 82d07059..2505d5e4 100644
--- a/tests/ServerTest.php
+++ b/tests/ServerTest.php
@@ -2,6 +2,7 @@
 
 namespace LeagueTests;
 
+use League\OAuth2\Server\CryptKey;
 use League\OAuth2\Server\Exception\OAuthServerException;
 use League\OAuth2\Server\Grant\AuthCodeGrant;
 use League\OAuth2\Server\Grant\ClientCredentialsGrant;
@@ -11,6 +12,7 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface;
 use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
 use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
 use League\OAuth2\Server\Repositories\UserRepositoryInterface;
+use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
 use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
 use League\OAuth2\Server\Server;
 use LeagueTests\Stubs\AccessTokenEntity;
@@ -20,6 +22,7 @@ use LeagueTests\Stubs\StubResponseType;
 use LeagueTests\Stubs\UserEntity;
 use Psr\Http\Message\ResponseInterface;
 use Zend\Diactoros\Response;
+use Zend\Diactoros\ServerRequest;
 use Zend\Diactoros\ServerRequestFactory;
 
 class ServerTest extends \PHPUnit_Framework_TestCase
@@ -74,57 +77,6 @@ class ServerTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(200, $response->getStatusCode());
     }
 
-    public function testRespondToRequestPsrResponse()
-    {
-        $client = new ClientEntity();
-        $client->setIdentifier('foo');
-        $client->setIdentifier('http://bar.com');
-
-        $clientRepository = $this->getMock(ClientRepositoryInterface::class);
-        $clientRepository->method('getClientEntity')->willReturn($client);
-
-        $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock();
-        $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0);
-
-        $server = new Server(
-            $clientRepository,
-            $this->getMock(AccessTokenRepositoryInterface::class),
-            $scopeRepositoryMock,
-            'file://' . __DIR__ . '/Stubs/private.key',
-            'file://' . __DIR__ . '/Stubs/public.key',
-            new StubResponseType()
-        );
-
-        $userRepository = $this->getMock(UserRepositoryInterface::class);
-        $userRepository->method('getUserEntityByUserCredentials')->willReturn(new UserEntity());
-
-        $authCodeRepoMock = $this->getMock(AuthCodeRepositoryInterface::class);
-        $authCodeRepoMock->expects($this->once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
-
-        $server->enableGrantType(
-            new AuthCodeGrant(
-                $authCodeRepoMock,
-                $this->getMock(RefreshTokenRepositoryInterface::class),
-                $userRepository,
-                new \DateInterval('PT1H')
-            ),
-            new \DateInterval('PT1M')
-        );
-
-        $_SERVER['HTTP_HOST'] = 'http://auth.com';
-        $_SERVER['REQUEST_URI'] = '/auth';
-        $_GET['response_type'] = 'code';
-        $_GET['client_id'] = $client->getIdentifier();
-        $_GET['redirect_uri'] = $client->getRedirectUri();
-        $_POST['action'] = 'approve';
-        $_POST['username'] = 'user';
-        $_POST['password'] = 'pass';
-        $response = $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response);
-        $this->assertTrue($response instanceof ResponseInterface);
-        $this->assertEquals(302, $response->getStatusCode());
-        $this->assertTrue(strstr($response->getHeaderLine('location'), 'code=') !== false);
-    }
-
     public function testGetResponseType()
     {
         $clientRepository = $this->getMock(ClientRepositoryInterface::class);
@@ -144,7 +96,7 @@ class ServerTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($method->invoke($server) instanceof BearerTokenResponse);
     }
 
-    public function testValidateRequest()
+    public function testValidateAuthenticatedRequest()
     {
         $clientRepository = $this->getMock(ClientRepositoryInterface::class);
 
@@ -162,4 +114,113 @@ class ServerTest extends \PHPUnit_Framework_TestCase
             $this->assertEquals('Missing "Authorization" header', $e->getHint());
         }
     }
+
+    public function testCompleteAuthorizationRequest()
+    {
+        $clientRepository = $this->getMock(ClientRepositoryInterface::class);
+
+        $server = new Server(
+            $clientRepository,
+            $this->getMock(AccessTokenRepositoryInterface::class),
+            $this->getMock(ScopeRepositoryInterface::class),
+            'file://' . __DIR__ . '/Stubs/private.key',
+            'file://' . __DIR__ . '/Stubs/public.key'
+        );
+
+        $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock();
+        $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity());
+
+        $grant = new AuthCodeGrant(
+            $authCodeRepository,
+            $this->getMock(RefreshTokenRepositoryInterface::class),
+            $this->getMock(UserRepositoryInterface::class),
+            new \DateInterval('PT10M')
+        );
+
+        $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/Stubs/private.key'));
+        $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/Stubs/public.key'));
+
+        $server->enableGrantType($grant);
+
+        $authRequest = new AuthorizationRequest();
+        $authRequest->setAuthorizationApproved(true);
+        $authRequest->setClient(new ClientEntity());
+        $authRequest->setGrantTypeId('authorization_code');
+        $authRequest->setUser(new UserEntity());
+
+        $this->assertTrue(
+            $server->completeAuthorizationRequest($authRequest, new Response) instanceof ResponseInterface
+        );
+    }
+
+    public function testValidateAuthorizationRequest()
+    {
+        $client = new ClientEntity();
+        $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
+        $clientRepositoryMock->method('getClientEntity')->willReturn($client);
+
+        $grant = new AuthCodeGrant(
+            $this->getMock(AuthCodeRepositoryInterface::class),
+            $this->getMock(RefreshTokenRepositoryInterface::class),
+            $this->getMock(UserRepositoryInterface::class),
+            new \DateInterval('PT10M')
+        );
+        $grant->setClientRepository($clientRepositoryMock);
+
+        $server = new Server(
+            $clientRepositoryMock,
+            $this->getMock(AccessTokenRepositoryInterface::class),
+            $this->getMock(ScopeRepositoryInterface::class),
+            'file://' . __DIR__ . '/Stubs/private.key',
+            'file://' . __DIR__ . '/Stubs/public.key'
+        );
+        $server->enableGrantType($grant);
+
+        $request = new ServerRequest(
+            [],
+            [],
+            null,
+            null,
+            'php://input',
+            $headers = [],
+            $cookies = [],
+            $queryParams = [
+                'response_type' => 'code',
+                'client_id'     => 'foo',
+            ]
+        );
+
+        $this->assertTrue($server->validateAuthorizationRequest($request) instanceof AuthorizationRequest);
+    }
+
+    /**
+     * @expectedException  \League\OAuth2\Server\Exception\OAuthServerException
+     * @expectedExceptionCode 2
+     */
+    public function testValidateAuthorizationRequestUnregistered()
+    {
+        $server = new Server(
+            $this->getMock(ClientRepositoryInterface::class),
+            $this->getMock(AccessTokenRepositoryInterface::class),
+            $this->getMock(ScopeRepositoryInterface::class),
+            'file://' . __DIR__ . '/Stubs/private.key',
+            'file://' . __DIR__ . '/Stubs/public.key'
+        );
+
+        $request = new ServerRequest(
+            [],
+            [],
+            null,
+            null,
+            'php://input',
+            $headers = [],
+            $cookies = [],
+            $queryParams = [
+                'response_type' => 'code',
+                'client_id'     => 'foo',
+            ]
+        );
+
+        $server->validateAuthorizationRequest($request);
+    }
 }