feat: add match view server-rendered shell
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BattleForge\Http\Handlers;
|
||||
|
||||
use BattleForge\Http\Request;
|
||||
use BattleForge\Http\Response;
|
||||
|
||||
final class GetMatchView
|
||||
{
|
||||
/** @param array<string, string> $params */
|
||||
public function handle(Request $request, array $params): Response
|
||||
{
|
||||
$csrf = $request->cookies['__csrf'] ?? '';
|
||||
|
||||
ob_start();
|
||||
require_once __DIR__ . '/../../Views/layout.php';
|
||||
require __DIR__ . '/../../Views/match.php';
|
||||
$body = (string) ob_get_clean();
|
||||
|
||||
return Response::html(200, $body);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use BattleForge\Http\Escape;
|
||||
|
||||
/** @var string $csrf Provided by the front controller. */
|
||||
?><?php
|
||||
render_layout(static function (): void {
|
||||
$a = static fn (string $v): string => Escape::attr($v);
|
||||
?>
|
||||
<header id="bf-match-header" data-bf-active-team="" data-bf-round="0">
|
||||
<h1>Battle</h1>
|
||||
<p>
|
||||
Active team: <strong id="bf-active-team">—</strong>
|
||||
· Round: <strong id="bf-round">0</strong>
|
||||
</p>
|
||||
<p>
|
||||
<button id="bf-end-turn" type="button">End Turn</button>
|
||||
</p>
|
||||
</header>
|
||||
<main>
|
||||
<div id="bf-grid" class="bf-grid" data-bf-width="0" data-bf-height="0"></div>
|
||||
<aside id="bf-panel" class="bf-panel">
|
||||
<p>Selected: <span id="bf-selected-unit">none</span></p>
|
||||
<p>
|
||||
<button id="bf-action-move" type="button" disabled>Move</button>
|
||||
<button id="bf-action-attack" type="button" disabled>Attack</button>
|
||||
<button id="bf-action-ability" type="button" disabled>Ability</button>
|
||||
</p>
|
||||
<div id="bf-ability-options"></div>
|
||||
</aside>
|
||||
</main>
|
||||
<section id="bf-log" class="bf-log" aria-label="Action log"></section>
|
||||
<section id="bf-result" class="bf-result" hidden>
|
||||
<h2>Match over</h2>
|
||||
<p>Winner: <strong id="bf-winner"></strong></p>
|
||||
<p><a id="bf-return-home" href="/">Return to home</a></p>
|
||||
</section>
|
||||
<div id="bf-toast-host"></div>
|
||||
<script type="module" src="<?= $a('/js/match.js') ?>"></script>
|
||||
<?php
|
||||
}, $csrf, 'Battle');
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BattleForge\Tests\Integration;
|
||||
|
||||
use BattleForge\Http\Handlers\GetMatchView;
|
||||
use BattleForge\Http\Request;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class GetMatchViewTest extends TestCase
|
||||
{
|
||||
public function testItRendersTheMatchShellWithSecurityHeaders(): void
|
||||
{
|
||||
$handler = new GetMatchView();
|
||||
$request = new Request([], [], [], [], [], '', 'GET', '/matches/current', 'text/html', '');
|
||||
$response = $handler->handle($request, []);
|
||||
|
||||
self::assertSame(200, $response->status);
|
||||
self::assertStringContainsString('text/html', $response->headers['Content-Type'] ?? '');
|
||||
self::assertSame('nosniff', $response->headers['X-Content-Type-Options']);
|
||||
self::assertStringContainsString('default-src', $response->headers['Content-Security-Policy']);
|
||||
|
||||
self::assertStringContainsString('id="bf-match-header"', $response->body);
|
||||
self::assertStringContainsString('id="bf-end-turn"', $response->body);
|
||||
self::assertStringContainsString('id="bf-grid"', $response->body);
|
||||
self::assertStringContainsString('id="bf-panel"', $response->body);
|
||||
self::assertStringContainsString('id="bf-action-move"', $response->body);
|
||||
self::assertStringContainsString('id="bf-action-attack"', $response->body);
|
||||
self::assertStringContainsString('id="bf-action-ability"', $response->body);
|
||||
self::assertStringContainsString('id="bf-selected-unit"', $response->body);
|
||||
self::assertStringContainsString('id="bf-log"', $response->body);
|
||||
self::assertStringContainsString('id="bf-result"', $response->body);
|
||||
self::assertStringContainsString('id="bf-winner"', $response->body);
|
||||
self::assertStringContainsString('id="bf-return-home"', $response->body);
|
||||
self::assertStringContainsString('src="/js/match.js"', $response->body);
|
||||
self::assertStringContainsString('name="csrf-token"', $response->body);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user