diff --git a/php-packages/testing/tests/integration/TestCase.php b/php-packages/testing/tests/integration/TestCase.php index 2d295d11d..9fa641df0 100644 --- a/php-packages/testing/tests/integration/TestCase.php +++ b/php-packages/testing/tests/integration/TestCase.php @@ -11,8 +11,13 @@ namespace Flarum\Tests\integration; +use Dflydev\FigCookies\SetCookie; use Flarum\Foundation\InstalledSite; use Illuminate\Database\ConnectionInterface; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Zend\Diactoros\CallbackStream; +use Zend\Diactoros\ServerRequest; abstract class TestCase extends \PHPUnit\Framework\TestCase { @@ -88,4 +93,69 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase // And finally, turn on foreign key checks again. $this->database()->getSchemaBuilder()->enableForeignKeyConstraints(); } + + /** + * Send a full HTTP request through Flarum's middleware stack. + */ + protected function send(ServerRequestInterface $request): ResponseInterface + { + return $this->server->handle($request); + } + + /** + * Build a HTTP request that can be passed through middleware. + * + * This method simplifies building HTTP request for use in our HTTP-level + * integration tests. It provides options for all features repeatedly being + * used in those tests. + * + * @param string $method + * @param string $path + * @param array $options + * An array of optional request properties. + * Currently supported: + * - "json" should point to a JSON-serializable object that will be + * serialized and used as request body. The corresponding Content-Type + * header will be set automatically. + * - "cookiesFrom" should hold a response object from a previous HTTP + * interaction. All cookies returned from the server in that response + * (via the "Set-Cookie" header) will be copied to the cookie params of + * the new request. + * @return ServerRequestInterface + */ + protected function request(string $method, string $path, array $options = []): ServerRequestInterface + { + $request = new ServerRequest([], [], $path, $method); + + // Do we want a JSON request body? + if (isset($options['json'])) { + $request = $request + ->withHeader('Content-Type', 'application/json') + ->withBody( + new CallbackStream(function () use ($options) { + return json_encode($options['json']); + }) + ); + } + + // Let's copy the cookies from a previous response + if (isset($options['cookiesFrom'])) { + /** @var ResponseInterface $previousResponse */ + $previousResponse = $options['cookiesFrom']; + + $cookies = array_reduce( + $previousResponse->getHeader('Set-Cookie'), + function ($memo, $setCookieString) { + $setCookie = SetCookie::fromSetCookieString($setCookieString); + $memo[$setCookie->getName()] = $setCookie->getValue(); + return $memo; + }, + [] + ); + + $request = $request->withCookieParams($cookies); + } + + return $request; + } }