Improved response middleware, added tests
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							@@ -24,7 +24,7 @@ phpstan: ## Run static analysis
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.PHONY: phpunit
 | 
					.PHONY: phpunit
 | 
				
			||||||
phpunit: ## Run unit tests
 | 
					phpunit: ## Run unit tests
 | 
				
			||||||
	@phpunit --testdox --no-progress
 | 
						@phpunit --testdox --no-progress --display-warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: coverage
 | 
					.PHONY: coverage
 | 
				
			||||||
coverage: ## Code coverage
 | 
					coverage: ## Code coverage
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,14 @@ class ResponseMiddleware
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $promise = new Promise(
 | 
					        $promise = new Promise(
 | 
				
			||||||
            function (callable $resolve) use ($request, $next) {
 | 
					            function (callable $resolve) use ($request, $next) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
                    $resolve($next($request));
 | 
					                    $resolve($next($request));
 | 
				
			||||||
 | 
					                } catch (SecurityException $t) {
 | 
				
			||||||
 | 
					                    $resolve(Response::plaintext("Access Denied")->withStatus(Response::STATUS_UNAUTHORIZED));
 | 
				
			||||||
 | 
					                } catch (\Throwable $t) {
 | 
				
			||||||
 | 
					                    $this->logger->warning(get_class($t).": ".$t->getMessage(), [ 'file'=>$t->getFile(), 'line'=>$t->getLine() ]);
 | 
				
			||||||
 | 
					                    $resolve(Response::plaintext("500: Internal Server Error (".$t->getMessage().")\n")->withStatus(500));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return $promise->then(
 | 
					        return $promise->then(
 | 
				
			||||||
@@ -50,19 +57,10 @@ class ResponseMiddleware
 | 
				
			|||||||
                    return Response::plaintext($response);
 | 
					                    return Response::plaintext($response);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return Response::plaintext((string)$response);
 | 
					                return Response::plaintext((string)$response);
 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            function (Throwable $t) {
 | 
					 | 
				
			||||||
                if ($t instanceof SecurityException) {
 | 
					 | 
				
			||||||
                    return Response::plaintext("Access Denied")->withStatus(Response::STATUS_UNAUTHORIZED);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                $this->logger->warning(get_class($t).": ".$t->getMessage(), [ 'file'=>$t->getFile(), 'line'=>$t->getLine() ]);
 | 
					 | 
				
			||||||
                return Response::plaintext("500: Internal Server Error (".$t->getMessage().")\n")->withStatus(500);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        )->then(
 | 
					        )->then(
 | 
				
			||||||
            function ($response) use ($request) {
 | 
					            function ($response) use ($request) {
 | 
				
			||||||
                assert("\$response instanceof ResponseInterface");
 | 
					                assert("\$response instanceof ResponseInterface");
 | 
				
			||||||
                $host = ($request->getServerParams()['SERVER_ADDR']??"");
 | 
					 | 
				
			||||||
                        //. ":" . ($request->getServerParams()['SERVER_PORT']??"80");
 | 
					 | 
				
			||||||
                $this->logger->debug(sprintf("%s %s %s → %3d (%d)", 
 | 
					                $this->logger->debug(sprintf("%s %s %s → %3d (%d)", 
 | 
				
			||||||
                    $request->getServerParams()['REMOTE_ADDR'], 
 | 
					                    $request->getServerParams()['REMOTE_ADDR'], 
 | 
				
			||||||
                    $request->getMethod(), 
 | 
					                    $request->getMethod(), 
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										62
									
								
								tests/Http/Middleware/ResponseMiddlewareTest.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								tests/Http/Middleware/ResponseMiddlewareTest.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace NoccyLabs\Mercureact\Http\Middleware;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use NoccyLabs\Mercureact\Configuration;
 | 
				
			||||||
 | 
					use NoccyLabs\Mercureact\Exception\SecurityException;
 | 
				
			||||||
 | 
					use PHPUnit\Framework\Attributes\CoversClass;
 | 
				
			||||||
 | 
					use Psr\Http\Message\ServerRequestInterface;
 | 
				
			||||||
 | 
					use Psr\Log\NullLogger;
 | 
				
			||||||
 | 
					use React\Http\Message\Response;
 | 
				
			||||||
 | 
					use React\Http\Message\ServerRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[CoversClass(ResponseMiddleware::class)]
 | 
				
			||||||
 | 
					#[CoversClass(Configuration::class)]
 | 
				
			||||||
 | 
					class ResponseMiddlewareTest extends \PHPUnit\Framework\TestCase
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testResponseIsValid()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $logger = new NullLogger();
 | 
				
			||||||
 | 
					        $config = Configuration::createDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $request = new ServerRequest("GET", "/", serverParams:['REMOTE_ADDR'=>'127.0.0.1']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $return = null; // chained response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $next = function ($chainedRequest) use ($request, &$return) {
 | 
				
			||||||
 | 
					            $this->assertInstanceOf(ServerRequestInterface::class, $chainedRequest);
 | 
				
			||||||
 | 
					            $return = $chainedRequest;
 | 
				
			||||||
 | 
					            return "response";
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $middleware = new ResponseMiddleware($config, $logger);
 | 
				
			||||||
 | 
					        $middleware->__invoke($request, $next)->then(function ($result) {
 | 
				
			||||||
 | 
					            $this->assertInstanceOf(Response::class, $result);
 | 
				
			||||||
 | 
					            $this->assertEquals("response", $result->getBody());
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testSecurityExceptionsAreHandled()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $logger = new NullLogger();
 | 
				
			||||||
 | 
					        $config = Configuration::createDefault();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $request = new ServerRequest("GET", "/", serverParams:['REMOTE_ADDR'=>'127.0.0.1']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $return = null; // chained response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $next = function ($chainedRequest) use ($request, &$return) {
 | 
				
			||||||
 | 
					            $this->assertInstanceOf(ServerRequestInterface::class, $chainedRequest);
 | 
				
			||||||
 | 
					            $return = $chainedRequest;
 | 
				
			||||||
 | 
					            throw new SecurityException();
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $middleware = new ResponseMiddleware($config, $logger);
 | 
				
			||||||
 | 
					        $middleware->__invoke($request, $next)->then(function ($result) {
 | 
				
			||||||
 | 
					            $this->assertInstanceOf(Response::class, $result);
 | 
				
			||||||
 | 
					            $this->assertEquals("Access Denied", (string)$result->getBody());
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user