Add PHP unit tests and page tests.

Run "composer install", then "composer test".
This commit is contained in:
tim
2026-09-26 03:48:09 +02:00
parent 848c447c5b
commit ed959888b4
42 changed files with 5522 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
<?php
namespace Xxx\Tests\Unit;
use Xxx\Tests\Support\TestCase;
// purify_story() in lib/purify.inc.php and sanitise() in publish/post.lib.php
class SanitiseTest extends TestCase {
public function testPurifyKeepsTheEditorMarkup(): void {
$html = '<p style="text-align: center;">A <strong>b</strong> <em>c</em> <u>d</u> <sup>2</sup><sub>3</sub></p>'
. '<blockquote style="margin-left: 40px;"><p>q</p></blockquote>'
. '<p style="padding-left: 40px;">in</p><ul><li>one</li></ul><ol><li>two</li></ol>'
. '<p><a href="https://example.org/" title="t">link</a> <a href="mailto:a@example.org">mail</a><br /></p><hr />';
// HTML Purifier writes the styles without spaces
$this->assertSame(str_replace(': ', ':', $html), purify_story($html));
}
public function testPurifyRemovesScriptsAndHandlers(): void {
$this->assertSame('<p>hi</p>', purify_story('<p onclick="x()">hi<script>alert(1)</script></p>'));
$this->assertSame('<p>x</p>', purify_story('<p>x<img src="a" onerror="alert(1)" /></p>'));
$this->assertSame('', purify_story('<iframe src="https://example.org/"></iframe><style>p{}</style>'));
}
public function testPurifyRemovesUnsafeLinks(): void {
$this->assertSame('<a>x</a>', purify_story('<a href="javascript:alert(1)">x</a>'));
$this->assertSame('<a>x</a>', purify_story('<a href="data:text/html,hi">x</a>'));
$this->assertSame('<a href="https://example.org/">x</a>', purify_story('<a href="https://example.org/" target="_blank" onclick="y()" id="z">x</a>'));
}
public function testPurifyKeepsOnlySomeStyles(): void {
$this->assertSame('<p style="text-align:right;">x</p>', purify_story('<p style="text-align: right; color: red; position: fixed">x</p>'));
$this->assertSame('<span>x</span>', purify_story('<span style="background: url(javascript:alert(1))">x</span>'));
}
public function testPurifyClosesOpenTags(): void {
$this->assertSame('<p><strong>x</strong></p>', purify_story('<p><strong>x'));
$this->assertSame('', purify_story(NULL));
}
public function testSanitiseLeavesAnEmptyStory(): void {
$this->assertSame('', sanitise(''));
$this->assertNull(sanitise(NULL));
}
// SmartyPants writes numeric entities, and HTML Purifier turns them into characters
public function testNumberRangesGetEnDashesInTextOnly(): void {
$this->assertSame('<p>pages 10–20 and 3–4</p>', sanitise('<p>pages 10-20 and 3--4</p>'));
$this->assertSame('<p><a href="https://example.org/1-2">1–2</a></p>', sanitise('<p><a href="https://example.org/1-2">1-2</a></p>'));
}
public function testDoubleHyphensBecomeEmDashes(): void {
$this->assertSame('<p>a — b and c—d</p>', sanitise('<p>a -- b and c--d</p>'));
}
public function testThreeDotsBecomeAnEllipsis(): void {
$this->assertSame('<p>a.b.c and 1..2</p>', sanitise('<p>a.b.c and 1..2</p>'));
$this->assertSame('<p>Wait… what… now</p>', sanitise('<p>Wait... what. . . now</p>'));
}
public function testQuotesBecomeCurly(): void {
$this->assertSame('<p>“Hi,” she said. It’s ‘fine’.</p>',
sanitise('<p>"Hi," she said. It\'s \'fine\'.</p>'));
}
public function testScriptsAndCommentsAreRemoved(): void {
$this->assertSame('<p>ab</p>', sanitise("<p>a<script type=\"text/javascript\">\nalert('x');\n</script>b</p>"));
$this->assertSame('<p>ab</p>', sanitise("<p>a<!-- a\ncomment -->b</p>"));
}
public function testTheResultIsPurified(): void {
$this->assertSame('<p>x</p>', sanitise('<p onmouseover="steal()">x</p>'));
$this->assertSame('<a>x</a>', sanitise('<a href="javascript:steal()">x</a>'));
}
}