Files

65 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace BattleForge\Tests\Unit\Http;
use BattleForge\Http\Escape;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
final class EscapeTest extends TestCase
{
#[DataProvider('htmlProvider')]
public function testItEscapesHtmlContext(mixed $input, string $expected): void
{
self::assertSame($expected, Escape::html($input));
}
/**
* @return iterable<string, array{mixed, string}>
*/
public static function htmlProvider(): iterable
{
yield 'plain' => ['hello', 'hello'];
yield 'less-than' => ['<script>', '&lt;script&gt;'];
yield 'ampersand' => ['a & b', 'a &amp; b'];
yield 'double-quote' => ['she said "hi"', 'she said &quot;hi&quot;'];
yield 'single-quote' => ["it's", 'it&#039;s'];
yield 'invalid-utf8-substituted' => ["a\xC0\x80b", "a\xEF\xBF\xBD\xEF\xBF\xBDb"];
yield 'integer' => [42, '42'];
yield 'null' => [null, ''];
}
#[DataProvider('attrProvider')]
public function testItEscapesAttributeContext(mixed $input, string $expected): void
{
self::assertSame($expected, Escape::attr($input));
}
/**
* @return iterable<string, array{mixed, string}>
*/
public static function attrProvider(): iterable
{
yield 'tag-breakout' => ['" onclick="', '&quot; onclick=&quot;'];
yield 'apostrophe' => ["' onclick='", '&#039; onclick=&#039;'];
}
#[DataProvider('urlProvider')]
public function testItEncodesUrls(string $input, string $expected): void
{
self::assertSame($expected, Escape::url($input));
}
/**
* @return iterable<string, array{string, string}>
*/
public static function urlProvider(): iterable
{
yield 'space' => ['hello world', 'hello%20world'];
yield 'slash' => ['a/b', 'a%2Fb'];
yield 'unicode' => ['héllo', 'h%C3%A9llo'];
}
}