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
+115
View File
@@ -0,0 +1,115 @@
<?php
namespace Xxx\Tests\Unit;
use Xxx\Tests\Support\TestCase;
// The upload directory and the pending upload in get_data.lib.php and publish/post.lib.php
class UploadTest extends TestCase {
private function pending(string $content = ''): string {
$name = bin2hex(random_bytes(16));
$file = upload_dir() . '/' . $name;
file_put_contents($file, $content === '' ? self::png() : $content);
$_SESSION['pending_upload'] = $name;
return $file;
}
public function testUploadDirIsMadeFromTheConfiguration(): void {
$this->assertSame($this->tmp . '/uploads', upload_dir());
$this->assertDirectoryExists($this->tmp . '/uploads');
$this->assertSame(0700, fileperms($this->tmp . '/uploads') & 0777);
}
public function testUploadDirLosesATrailingSlash(): void {
$this->setEnv('UPLOAD_DIR', $this->tmp . '/other/');
$this->assertSame($this->tmp . '/other', upload_dir());
}
public function testUploadDirDefaultsToTheTempDirectory(): void {
$this->setEnv('UPLOAD_DIR', '');
$this->assertSame(sys_get_temp_dir() . '/xxx-uploads', upload_dir());
}
public function testUploadNamesAre32HexDigits(): void {
$this->assertTrue((bool)is_upload_name(str_repeat('a0', 16)));
$this->assertFalse((bool)is_upload_name(str_repeat('a0', 15)));
$this->assertFalse((bool)is_upload_name(str_repeat('A0', 16)));
$this->assertFalse((bool)is_upload_name('../' . str_repeat('a', 29)));
$this->assertFalse((bool)is_upload_name(str_repeat('a', 32) . "\n"));
$this->assertFalse((bool)is_upload_name(array()));
$this->assertFalse((bool)is_upload_name(NULL));
}
public function testStoreUploadRefusesAFileThatWasNotUploaded(): void {
$file = $this->tmp . '/local';
file_put_contents($file, 'x');
$this->assertFalse(store_upload($file));
$this->assertFileExists($file);
$this->assertArrayNotHasKey('pending_upload', $_SESSION);
}
public function testPendingUploadFindsTheSessionFile(): void {
$file = $this->pending();
$this->assertSame($file, pending_upload());
}
public function testPendingUploadNeedsAValidNameAndAFile(): void {
$this->assertFalse(pending_upload());
$_SESSION['pending_upload'] = '../../etc/passwd';
$this->assertFalse(pending_upload());
$_SESSION['pending_upload'] = str_repeat('b', 32);
$this->assertFalse(pending_upload());
}
public function testPendingUploadUrlHasTheStartOfTheName(): void {
$_SESSION['pending_upload'] = '0123456789abcdef0123456789abcdef';
$this->assertSame('/display?pending=01234567', pending_upload_url());
unset($_SESSION['pending_upload']);
$this->assertSame('/display?pending=', pending_upload_url());
}
public function testMimeTypeComesFromTheImage(): void {
$this->assertSame('image/png', get_mimetype($this->pending()));
$text = $this->tmp . '/text';
file_put_contents($text, 'This is not an image, but it is long enough to read.');
$this->assertNull(get_mimetype($text));
}
public function testSaveUploadedFileUsesThePendingUpload(): void {
$file = $this->pending();
$this->assertFalse(save_uploaded_file());
$_POST['uploaded'] = 'pending';
$this->assertSame($file, save_uploaded_file());
}
public function testSaveUploadedFileIgnoresAFakeUpload(): void {
$file = $this->tmp . '/fake';
file_put_contents($file, self::png());
$_FILES['upload'] = array('tmp_name' => $file, 'name' => 'a.png', 'error' => 0);
$this->assertFalse(save_uploaded_file());
}
public function testPruneDeletesTheSavedFileAndOldUploads(): void {
$saved = $this->pending();
$old = upload_dir() . '/' . str_repeat('c', 32);
$new = upload_dir() . '/' . str_repeat('d', 32);
$other = upload_dir() . '/keep-me';
foreach (array($old, $new, $other) as $file)
file_put_contents($file, 'x');
touch($old, time() - 86401);
touch($other, time() - 86401);
prune_images($saved);
$this->assertFileDoesNotExist($saved);
$this->assertFileDoesNotExist($old);
$this->assertFileExists($new);
$this->assertFileExists($other);
$this->assertArrayNotHasKey('pending_upload', $_SESSION);
}
public function testPruneLeavesFilesOutsideTheUploadDirectory(): void {
$outside = $this->tmp . '/' . str_repeat('e', 32);
file_put_contents($outside, 'x');
prune_images($outside);
$this->assertFileExists($outside);
}
}