dd/tests/Unit/Freenode/ReleaseStoreTest.php

46 lines
3.0 KiB
PHP

<?php
namespace Tests\Unit\Freenode;
use App\Services\Freenode\ReleaseStore;
use PHPUnit\Framework\TestCase;
use RuntimeException;
final class ReleaseStoreTest extends TestCase
{
private string $dir;
protected function setUp(): void { $this->dir = sys_get_temp_dir().'/fn-store-test-'.bin2hex(random_bytes(6)); mkdir($this->dir, 0700); }
protected function tearDown(): void {
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->dir, \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $f) { if ($f->isDir()) rmdir($f->getPathname()); else unlink($f->getPathname()); }
rmdir($this->dir);
}
private function fixture(string $value, int $count = 10): array { return ['files' => ['site/v2ray' => $value], 'report' => ['counts' => ['v2ray' => $count]]]; }
public function testRollbackRestoresPreviousReleaseAndPublicFile(): void {
$store = new ReleaseStore($this->dir.'/private', $this->dir.'/public');
$a = $store->stage($this->fixture('first'), date('Y-m-d')); $store->publishPrepared();
$b = $store->stage($this->fixture('second'), date('Y-m-d')); $store->publishPrepared();
self::assertSame(['v2ray' => 'second'], $store->readSite('site', ['v2ray']));
$store->activate($store->previous()['id']);
self::assertSame($a['id'], $store->current()['id']);
self::assertSame('first', file_get_contents($this->dir.'/public/site/v2ray/'.date('Y-m-d').'.txt'));
}
public function testCountDropDoesNotReplaceCurrent(): void {
$store = new ReleaseStore($this->dir.'/private', $this->dir.'/public');
$a = $store->stage($this->fixture('first'), date('Y-m-d')); $store->publishPrepared();
try { $store->stage($this->fixture('empty', 1), date('Y-m-d')); self::fail(); } catch (RuntimeException $e) { self::assertStringContainsString('count_drop_guard', $e->getMessage()); }
self::assertSame($a['id'], $store->current()['id']);
}
public function testTamperedFilesCannotBePublished(): void {
$store = new ReleaseStore($this->dir.'/private', $this->dir.'/public');
$a = $store->stage($this->fixture('first'), date('Y-m-d'));
file_put_contents($this->dir.'/private/versions/'.$a['id'].'/site/v2ray/'.date('Y-m-d').'.txt', 'tampered');
$this->expectException(RuntimeException::class); $store->publishPrepared();
}
public function testFirstPublishCapturesLegacyBytesForRollback(): void {
$public = $this->dir.'/public/site/v2ray'; mkdir($public, 0700, true); file_put_contents($public.'/'.date('Y-m-d').'.txt', 'legacy');
$store = new ReleaseStore($this->dir.'/private', $this->dir.'/public');
$store->stage($this->fixture('new'), date('Y-m-d')); $store->publishPrepared();
$legacy = $store->previous(); self::assertFalse($legacy['validated']);
$store->activate($legacy['id']); self::assertSame('legacy', file_get_contents($public.'/'.date('Y-m-d').'.txt'));
}
}