Add PHP unit tests and page tests.
Run "composer install", then "composer test".
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user