buildRequest(post: ['id' => 'demo']);
$response = $handler->handle($request, ['id' => 'demo']);
self::assertSame(403, $response->status);
self::assertStringContainsString('Forbidden', $response->body);
}
public function testItRejectsARequestWithAnInvalidCsrfToken(): void
{
$handler = new PostTeamEditor();
$request = $this->buildRequest(post: ['id' => 'demo', '_csrf' => 'tampered']);
$response = $handler->handle($request, ['id' => 'demo']);
self::assertSame(403, $response->status);
}
public function testItSavesAValidScenarioAndReturnsTheLocalStorageSnippet(): void
{
[$token, $cookie] = CsrfToken::issue(self::SECRET);
$handler = new PostTeamEditor();
$request = $this->buildRequest(
post: $this->validPost($token),
cookies: ['__csrf' => $cookie, '__csrf_token' => $token],
server: ['__csrf_secret' => self::SECRET],
);
$response = $handler->handle($request, ['id' => 'demo']);
self::assertSame(200, $response->status);
self::assertStringContainsString('localStorage.setItem', $response->body);
self::assertStringContainsString('scenario:"demo"', $response->body);
}
public function testItRejectsAnOutOfBoundsStatAndReRendersTheForm(): void
{
[$token, $cookie] = CsrfToken::issue(self::SECRET);
$handler = new PostTeamEditor();
$post = $this->validPost($token);
$post['teamA']['units'][0]['maxHealth'] = '9999';
$request = $this->buildRequest(
post: $post,
cookies: ['__csrf' => $cookie, '__csrf_token' => $token],
server: ['__csrf_secret' => self::SECRET],
);
$response = $handler->handle($request, ['id' => 'demo']);
self::assertSame(200, $response->status);
self::assertStringContainsString('bf-errors', $response->body);
self::assertStringContainsString('outside archetype bounds', $response->body);
}
public function testItEscapesAMaliciousIdSoItCannotBreakOutOfTheScriptBlock(): void
{
[$token, $cookie] = CsrfToken::issue(self::SECRET);
$handler = new PostTeamEditor();
$post = $this->validPost($token);
$post['id'] = '';
$request = $this->buildRequest(
post: $post,
cookies: ['__csrf' => $cookie, '__csrf_token' => $token],
server: ['__csrf_secret' => self::SECRET],
);
$response = $handler->handle($request, ['id' => $post['id']]);
self::assertSame(200, $response->status);
// The literal payload that would execute must NOT appear verbatim in the body.
self::assertStringNotContainsString('', $response->body);
// The JSON-encoded id is what we want to see, with the tag escaped to <\/.
self::assertStringContainsString('<\\/script>