<?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());
        });
    }
    
}