v7.0.0-beta.1 release
This commit is contained in:
commit
6595fd0eb5
3967 files changed
+1875383
No files matched your search
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Unit\Extension\Helpers;
|
||||
|
||||
use App\Extension\Helpers\ZipInstallHelper;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ZipInstallHelperTest extends TestCase
|
||||
{
|
||||
private string $tempDir;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->tempDir = storage_path('app/temp/test-zip-helper-'.uniqid());
|
||||
File::ensureDirectoryExists($this->tempDir);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (File::isDirectory($this->tempDir)) {
|
||||
File::deleteDirectory($this->tempDir);
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// extractZip
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
#[Test]
|
||||
public function extractZip_유효한_zip_파일을_추출합니다(): void
|
||||
{
|
||||
$zipPath = $this->createTestZip(['module.json' => '{"identifier":"test-module"}']);
|
||||
$extractPath = $this->tempDir.'/extracted';
|
||||
|
||||
ZipInstallHelper::extractZip($zipPath, $extractPath);
|
||||
|
||||
$this->assertTrue(File::exists($extractPath.'/module.json'));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function extractZip_존재하지_않는_파일이면_RuntimeException을_던집니다(): void
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
ZipInstallHelper::extractZip('/nonexistent/path.zip', $this->tempDir.'/extracted');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function extractZip_손상된_zip이면_RuntimeException을_던집니다(): void
|
||||
{
|
||||
$fakePath = $this->tempDir.'/corrupted.zip';
|
||||
File::put($fakePath, 'this is not a valid zip file');
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
ZipInstallHelper::extractZip($fakePath, $this->tempDir.'/extracted');
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// findManifest
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
#[Test]
|
||||
public function findManifest_루트에_있는_manifest를_찾습니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/module.json', '{}');
|
||||
|
||||
$result = ZipInstallHelper::findManifest($this->tempDir, 'module.json');
|
||||
|
||||
$this->assertNotNull($result);
|
||||
$this->assertStringEndsWith('module.json', $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findManifest_1단계_하위_디렉토리에서_manifest를_찾습니다(): void
|
||||
{
|
||||
$subDir = $this->tempDir.'/owner-repo-abc123';
|
||||
File::ensureDirectoryExists($subDir);
|
||||
File::put($subDir.'/module.json', '{}');
|
||||
|
||||
$result = ZipInstallHelper::findManifest($this->tempDir, 'module.json');
|
||||
|
||||
$this->assertNotNull($result);
|
||||
$this->assertStringContainsString('owner-repo-abc123', $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findManifest_manifest가_없으면_null을_반환합니다(): void
|
||||
{
|
||||
$result = ZipInstallHelper::findManifest($this->tempDir, 'module.json');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findManifest_2단계_이상_하위에서는_찾지_않습니다(): void
|
||||
{
|
||||
$deepDir = $this->tempDir.'/level1/level2';
|
||||
File::ensureDirectoryExists($deepDir);
|
||||
File::put($deepDir.'/module.json', '{}');
|
||||
|
||||
$result = ZipInstallHelper::findManifest($this->tempDir, 'module.json');
|
||||
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// findAndValidateManifest
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_유효한_모듈_manifest를_검증합니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/module.json', json_encode([
|
||||
'identifier' => 'test-module',
|
||||
'name' => 'Test Module',
|
||||
]));
|
||||
|
||||
$result = ZipInstallHelper::findAndValidateManifest($this->tempDir, 'module.json', 'modules');
|
||||
|
||||
$this->assertSame('test-module', $result['identifier']);
|
||||
$this->assertArrayHasKey('config', $result);
|
||||
$this->assertArrayHasKey('sourcePath', $result);
|
||||
$this->assertSame('Test Module', $result['config']['name']);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_유효한_플러그인_manifest를_검증합니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/plugin.json', json_encode([
|
||||
'identifier' => 'test-plugin',
|
||||
'name' => 'Test Plugin',
|
||||
]));
|
||||
|
||||
$result = ZipInstallHelper::findAndValidateManifest($this->tempDir, 'plugin.json', 'plugins');
|
||||
|
||||
$this->assertSame('test-plugin', $result['identifier']);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_유효한_템플릿_manifest를_검증합니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/template.json', json_encode([
|
||||
'identifier' => 'test-template',
|
||||
'name' => 'Test Template',
|
||||
]));
|
||||
|
||||
$result = ZipInstallHelper::findAndValidateManifest($this->tempDir, 'template.json', 'templates');
|
||||
|
||||
$this->assertSame('test-template', $result['identifier']);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_manifest가_없으면_RuntimeException을_던집니다(): void
|
||||
{
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
ZipInstallHelper::findAndValidateManifest($this->tempDir, 'module.json', 'modules');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_identifier가_누락되면_RuntimeException을_던집니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/module.json', json_encode([
|
||||
'name' => 'No Identifier Module',
|
||||
]));
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
ZipInstallHelper::findAndValidateManifest($this->tempDir, 'module.json', 'modules');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_잘못된_json이면_RuntimeException을_던집니다(): void
|
||||
{
|
||||
File::put($this->tempDir.'/module.json', 'this is not valid json {{{');
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
|
||||
ZipInstallHelper::findAndValidateManifest($this->tempDir, 'module.json', 'modules');
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function findAndValidateManifest_github_아카이브_구조를_처리합니다(): void
|
||||
{
|
||||
// GitHub ZIP은 owner-repo-hash/ 형태로 추출됨
|
||||
$subDir = $this->tempDir.'/owner-repo-abc123';
|
||||
File::ensureDirectoryExists($subDir);
|
||||
File::put($subDir.'/module.json', json_encode([
|
||||
'identifier' => 'github-module',
|
||||
]));
|
||||
|
||||
$result = ZipInstallHelper::findAndValidateManifest($this->tempDir, 'module.json', 'modules');
|
||||
|
||||
$this->assertSame('github-module', $result['identifier']);
|
||||
$this->assertSame(realpath($subDir), realpath($result['sourcePath']));
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// extractAndValidate
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
#[Test]
|
||||
public function extractAndValidate_zip_추출_후_manifest를_검증합니다(): void
|
||||
{
|
||||
$zipPath = $this->createTestZip(['module.json' => json_encode([
|
||||
'identifier' => 'zip-module',
|
||||
'name' => 'ZIP Module',
|
||||
])]);
|
||||
$extractPath = $this->tempDir.'/extract';
|
||||
|
||||
$result = ZipInstallHelper::extractAndValidate($zipPath, $extractPath, 'module.json', 'modules');
|
||||
|
||||
$this->assertSame('zip-module', $result['identifier']);
|
||||
$this->assertSame('ZIP Module', $result['config']['name']);
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// moveToPending
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
#[Test]
|
||||
public function moveToPending_소스를_pending_디렉토리로_이동합니다(): void
|
||||
{
|
||||
// 소스 준비
|
||||
$sourcePath = $this->tempDir.'/source';
|
||||
File::ensureDirectoryExists($sourcePath);
|
||||
File::put($sourcePath.'/module.json', '{"identifier":"test"}');
|
||||
|
||||
$pendingBase = $this->tempDir.'/pending';
|
||||
|
||||
$result = ZipInstallHelper::moveToPending($sourcePath, $pendingBase, 'test-module');
|
||||
|
||||
$this->assertSame($pendingBase.'/test-module', $result);
|
||||
$this->assertTrue(File::exists($result.'/module.json'));
|
||||
$this->assertFalse(File::isDirectory($sourcePath));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function moveToPending_이미_존재하는_대상을_덮어씁니다(): void
|
||||
{
|
||||
// 소스 준비
|
||||
$sourcePath = $this->tempDir.'/source';
|
||||
File::ensureDirectoryExists($sourcePath);
|
||||
File::put($sourcePath.'/new_file.txt', 'new content');
|
||||
|
||||
// 기존 pending 대상 준비
|
||||
$pendingBase = $this->tempDir.'/pending';
|
||||
$existingTarget = $pendingBase.'/test-module';
|
||||
File::ensureDirectoryExists($existingTarget);
|
||||
File::put($existingTarget.'/old_file.txt', 'old content');
|
||||
|
||||
$result = ZipInstallHelper::moveToPending($sourcePath, $pendingBase, 'test-module');
|
||||
|
||||
$this->assertTrue(File::exists($result.'/new_file.txt'));
|
||||
$this->assertFalse(File::exists($result.'/old_file.txt'));
|
||||
}
|
||||
|
||||
// ──────────────────────────────────────────
|
||||
// 헬퍼 메서드
|
||||
// ──────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* 테스트용 ZIP 파일을 생성합니다.
|
||||
*
|
||||
* @param array<string, string> $files 파일명 => 내용 매핑
|
||||
* @return string 생성된 ZIP 파일 경로
|
||||
*/
|
||||
private function createTestZip(array $files): string
|
||||
{
|
||||
$zipPath = $this->tempDir.'/test.zip';
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($zipPath, \ZipArchive::CREATE);
|
||||
|
||||
foreach ($files as $name => $content) {
|
||||
$zip->addFromString($name, $content);
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
return $zipPath;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user