1
0
mirror of https://github.com/flarum/core.git synced 2025-08-11 10:55:47 +02:00

chore: adapt test infra

This commit is contained in:
Sami Mazouz
2023-08-11 15:04:30 +01:00
parent cca5725fe4
commit 3b3efc7cbb
7 changed files with 61 additions and 57 deletions

View File

@@ -9,12 +9,12 @@
namespace Flarum\Foundation; namespace Flarum\Foundation;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Foundation\Application as ApplicationContract;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
interface AppInterface interface AppInterface
{ {
public function getContainer(): Container; public function getContainer(): ApplicationContract;
public function getMiddlewareStack(): array; public function getMiddlewareStack(): array;

View File

@@ -12,6 +12,7 @@ namespace Flarum\Foundation;
use Flarum\Foundation\Concerns\InteractsWithLaravel; use Flarum\Foundation\Concerns\InteractsWithLaravel;
use Flarum\Http\RoutingServiceProvider; use Flarum\Http\RoutingServiceProvider;
use Illuminate\Container\Container as IlluminateContainer; use Illuminate\Container\Container as IlluminateContainer;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Foundation\Application as LaravelApplication; use Illuminate\Contracts\Foundation\Application as LaravelApplication;
use Illuminate\Events\EventServiceProvider; use Illuminate\Events\EventServiceProvider;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
@@ -70,7 +71,7 @@ class Application extends IlluminateContainer implements LaravelApplication
IlluminateContainer::setInstance($this); IlluminateContainer::setInstance($this);
$this->instance('app', $this); $this->instance('app', $this);
$this->instance('container', $this); $this->instance(Container::class, $this);
$this->instance('flarum', $this); $this->instance('flarum', $this);
$this->instance('flarum.paths', $this->paths); $this->instance('flarum.paths', $this->paths);
} }

View File

@@ -9,34 +9,29 @@
namespace Flarum\Foundation; namespace Flarum\Foundation;
use Flarum\Http\Middleware as HttpMiddleware;
use Flarum\Settings\SettingsRepositoryInterface; use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Console\Command; use Illuminate\Console\Command;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Foundation\Application as ApplicationContract;
use Laminas\Stratigility\Middleware\OriginalMessages; use Laminas\Stratigility\Middleware\OriginalMessages;
use Laminas\Stratigility\MiddlewarePipe;
use Middlewares\BasePath; use Middlewares\BasePath;
use Middlewares\BasePathRouter;
use Middlewares\RequestHandler;
use Psr\Http\Server\RequestHandlerInterface;
class InstalledApp implements AppInterface class InstalledApp implements AppInterface
{ {
public function __construct( public function __construct(
protected Container $container, protected ApplicationContract $app,
protected Config $config protected Config $config
) { ) {
} }
public function getContainer(): Container public function getContainer(): ApplicationContract
{ {
return $this->container; return $this->app;
} }
public function getMiddlewareStack(): array public function getMiddlewareStack(): array
{ {
// if ($this->config->inMaintenanceMode()) { // if ($this->config->inMaintenanceMode()) {
// return $this->container->make('flarum.maintenance.handler'); // return $this->app->make('flarum.maintenance.handler');
// } // }
return match ($this->needsUpdate()) { return match ($this->needsUpdate()) {
@@ -47,7 +42,7 @@ class InstalledApp implements AppInterface
protected function needsUpdate(): bool protected function needsUpdate(): bool
{ {
$settings = $this->container->make(SettingsRepositoryInterface::class); $settings = $this->app->make(SettingsRepositoryInterface::class);
$version = $settings->get('version'); $version = $settings->get('version');
return $version !== Application::VERSION; return $version !== Application::VERSION;
@@ -76,13 +71,13 @@ class InstalledApp implements AppInterface
public function getConsoleCommands(): array public function getConsoleCommands(): array
{ {
return array_map(function ($command) { return array_map(function ($command) {
$command = $this->container->make($command); $command = $this->app->make($command);
if ($command instanceof Command) { if ($command instanceof Command) {
$command->setLaravel($this->container); $command->setLaravel($this->app);
} }
return $command; return $command;
}, $this->container->make('flarum.console.commands')); }, $this->app->make('flarum.console.commands'));
} }
} }

View File

@@ -40,6 +40,7 @@ use Illuminate\Config\Repository as ConfigRepository;
use Illuminate\Contracts\Cache\Repository; use Illuminate\Contracts\Cache\Repository;
use Illuminate\Contracts\Cache\Store; use Illuminate\Contracts\Cache\Store;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
use Illuminate\Filesystem\Filesystem; use Illuminate\Filesystem\Filesystem;
use Illuminate\Hashing\HashServiceProvider; use Illuminate\Hashing\HashServiceProvider;
use Illuminate\Validation\ValidationServiceProvider; use Illuminate\Validation\ValidationServiceProvider;
@@ -87,7 +88,7 @@ class InstalledSite implements SiteInterface
return $this; return $this;
} }
protected function bootLaravel(): Container protected function bootLaravel(): ApplicationContract
{ {
$app = new Application($this->paths); $app = new Application($this->paths);

View File

@@ -13,30 +13,36 @@ use Flarum\Foundation\AppInterface;
use Flarum\Foundation\ErrorHandling\LogReporter; use Flarum\Foundation\ErrorHandling\LogReporter;
use Flarum\Foundation\SiteInterface; use Flarum\Foundation\SiteInterface;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Routing\Pipeline; use Illuminate\Routing\Pipeline;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Throwable; use Throwable;
class Server class Server
{ {
public function __construct( public function __construct(
private readonly SiteInterface $site private readonly ?SiteInterface $site = null
) { ) {
} }
public function listen(): void public function listen(): void
{ {
$request = Request::capture();
$siteApp = $this->safelyBoot(); $siteApp = $this->safelyBoot();
$container = $siteApp->getContainer(); $app = $siteApp->getContainer();
$globalMiddleware = $siteApp->getMiddlewareStack(); $globalMiddleware = $siteApp->getMiddlewareStack();
(new Pipeline($container)) $this->send(Request::capture(), $app, $globalMiddleware);
}
public function send(Request $request, Application $app, array $globalMiddleware): Response
{
return (new Pipeline($app))
->send($request) ->send($request)
->through($globalMiddleware) ->through($globalMiddleware)
->then(function (Request $request) use ($container) { ->then(function (Request $request) use ($app) {
return $container->make(Router::class)->dispatch($request); return $app->make(Router::class)->dispatch($request);
}); });
} }

View File

@@ -10,12 +10,11 @@
namespace Flarum\Testing\integration; namespace Flarum\Testing\integration;
use Carbon\Carbon; use Carbon\Carbon;
use Dflydev\FigCookies\SetCookie; use Illuminate\Http\Request;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Laminas\Diactoros\CallbackStream; use Symfony\Component\HttpFoundation\Cookie;
use Psr\Http\Message\ResponseInterface as Response; use Symfony\Component\HttpFoundation\ParameterBag;
use Psr\Http\Message\ServerRequestInterface; use Symfony\Component\HttpFoundation\Response;
use Psr\Http\Message\ServerRequestInterface as Request;
/** /**
* A collection of helpers for building PSR-7 requests for integration tests. * A collection of helpers for building PSR-7 requests for integration tests.
@@ -24,13 +23,10 @@ trait BuildsHttpRequests
{ {
protected function requestWithJsonBody(Request $req, array $json): Request protected function requestWithJsonBody(Request $req, array $json): Request
{ {
return $req $req->headers->set('Content-Type', 'application/json');
->withHeader('Content-Type', 'application/json') $req->setJson(new ParameterBag($json));
->withBody(
new CallbackStream(function () use ($json) { return $req;
return json_encode($json);
})
);
} }
protected function requestAsUser(Request $req, int $userId): Request protected function requestAsUser(Request $req, int $userId): Request
@@ -49,36 +45,41 @@ trait BuildsHttpRequests
'type' => 'session' 'type' => 'session'
]); ]);
return $req $req->headers->set('Authorization', "Token {$token}");
->withAddedHeader('Authorization', "Token {$token}")
// We save the token as an attribute so that we can retrieve it for test purposes. // We save the token as an attribute so that we can retrieve it for test purposes.
->withAttribute('tests_token', $token); $req->attributes->set('tests_token', $token);
return $req;
} }
protected function requestWithCookiesFrom(Request $req, Response $previous): Request protected function requestWithCookiesFrom(Request $req, Response $previous): Request
{ {
$cookies = array_reduce( $cookies = array_reduce(
$previous->getHeader('Set-Cookie'), $previous->headers->all('Set-Cookie'),
function ($memo, $setCookieString) { function ($memo, $setCookieString) {
$setCookie = SetCookie::fromSetCookieString($setCookieString); $cookie = Cookie::fromString($setCookieString);
$memo[$setCookie->getName()] = $setCookie->getValue(); $memo[$cookie->getName()] = $cookie->getValue();
return $memo; return $memo;
}, },
[] []
); );
return $req->withCookieParams($cookies); $req->cookies->add($cookies);
return $req;
} }
protected function requestWithCsrfToken(ServerRequestInterface $request): ServerRequestInterface protected function requestWithCsrfToken(Request $request): Request
{ {
$initial = $this->send( $initial = $this->send(
$this->request('GET', '/') $this->request('GET', '/')
); );
$token = $initial->getHeaderLine('X-CSRF-Token'); $token = $initial->headers->get('X-CSRF-Token');
$request->headers->set('X-CSRF-Token', $token);
return $this->requestWithCookiesFrom($request->withHeader('X-CSRF-Token', $token), $initial); return $this->requestWithCookiesFrom($request, $initial);
} }
} }

View File

@@ -10,14 +10,14 @@
namespace Flarum\Testing\integration; namespace Flarum\Testing\integration;
use Flarum\Extend\ExtenderInterface; use Flarum\Extend\ExtenderInterface;
use Flarum\Http\Server;
use Flarum\Testing\integration\Setup\Bootstrapper; use Flarum\Testing\integration\Setup\Bootstrapper;
use Illuminate\Contracts\Cache\Store; use Illuminate\Contracts\Cache\Store;
use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionInterface;
use Illuminate\Http\Request;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Laminas\Diactoros\ServerRequest;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use Symfony\Component\HttpFoundation\Response;
abstract class TestCase extends \PHPUnit\Framework\TestCase abstract class TestCase extends \PHPUnit\Framework\TestCase
{ {
@@ -156,10 +156,10 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
*/ */
protected $server; protected $server;
protected function server(): RequestHandlerInterface protected function server(): Server
{ {
if (is_null($this->server)) { if (is_null($this->server)) {
$this->server = $this->app()->getRequestHandler(); $this->server = new Server();
} }
return $this->server; return $this->server;
@@ -213,9 +213,9 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
/** /**
* Send a full HTTP request through Flarum's middleware stack. * Send a full HTTP request through Flarum's middleware stack.
*/ */
protected function send(ServerRequestInterface $request): ResponseInterface protected function send(Request $request): Response
{ {
return $this->server()->handle($request); return $this->server()->send($request, $this->app->getContainer(), []);
} }
/** /**
@@ -240,11 +240,11 @@ abstract class TestCase extends \PHPUnit\Framework\TestCase
* interaction. All cookies returned from the server in that response * interaction. All cookies returned from the server in that response
* (via the "Set-Cookie" header) will be copied to the cookie params of * (via the "Set-Cookie" header) will be copied to the cookie params of
* the new request. * the new request.
* @return ServerRequestInterface * @return Request
*/ */
protected function request(string $method, string $path, array $options = []): ServerRequestInterface protected function request(string $method, string $path, array $options = []): Request
{ {
$request = new ServerRequest([], [], $path, $method); $request = Request::create($path, $method);
// Do we want a JSON request body? // Do we want a JSON request body?
if (isset($options['json'])) { if (isset($options['json'])) {