v7.0.0-beta.2 release
This commit is contained in:
1 parent
6595fd0eb5
commit
fa8eba7a0d
1165 files changed
+107118
-762127
No files matched your search
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Console;
|
||||
|
||||
use App\Extension\Vendor\VendorBundler;
|
||||
use App\Extension\Vendor\VendorMode;
|
||||
use App\Services\CoreUpdateService;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* core:update --vendor-mode 3 모드 Feature 테스트.
|
||||
*
|
||||
* 실제 core:update 커맨드를 풀 체인으로 검증하는 것은 마이그레이션/GitHub 연동 등
|
||||
* 사이드 이펙트가 크므로, CoreUpdateService::runVendorInstallInPending() 경로를
|
||||
* 중심으로 VendorResolver 분기 + 해시 검증 + zip 추출 동작을 격리 검증한다.
|
||||
*/
|
||||
class CoreUpdateWithBundleTest extends TestCase
|
||||
{
|
||||
private CoreUpdateService $service;
|
||||
|
||||
private string $pendingDir;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->service = app(CoreUpdateService::class);
|
||||
$this->pendingDir = storage_path('app/test-core-vendor-bundle-'.uniqid());
|
||||
File::ensureDirectoryExists($this->pendingDir);
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
if (File::isDirectory($this->pendingDir)) {
|
||||
File::deleteDirectory($this->pendingDir);
|
||||
}
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 테스트용 _pending 디렉토리에 vendor-bundle.zip 을 생성합니다.
|
||||
*/
|
||||
private function createPendingBundle(): void
|
||||
{
|
||||
File::put($this->pendingDir.'/composer.json', json_encode([
|
||||
'name' => 'test/core',
|
||||
'require' => ['php' => '^8.2'],
|
||||
]));
|
||||
|
||||
$zipPath = $this->pendingDir.'/vendor-bundle.zip';
|
||||
$zip = new \ZipArchive;
|
||||
$zip->open($zipPath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
||||
$zip->addFromString('vendor/autoload.php', '<?php // test autoload');
|
||||
$zip->addFromString('vendor/laravel/framework/src/file.php', '<?php // framework');
|
||||
$zip->close();
|
||||
|
||||
File::put($this->pendingDir.'/vendor-bundle.json', json_encode([
|
||||
'schema_version' => VendorBundler::SCHEMA_VERSION,
|
||||
'zip_sha256' => hash_file('sha256', $zipPath),
|
||||
'package_count' => 1,
|
||||
]));
|
||||
}
|
||||
|
||||
public function test_vendor_mode_bundled_extracts_bundle_zip(): void
|
||||
{
|
||||
$this->createPendingBundle();
|
||||
|
||||
$result = $this->service->runVendorInstallInPending($this->pendingDir, VendorMode::Bundled);
|
||||
|
||||
$this->assertSame(VendorMode::Bundled, $result->mode);
|
||||
$this->assertSame('bundled', $result->strategy);
|
||||
$this->assertFileExists($this->pendingDir.'/vendor/autoload.php');
|
||||
$this->assertFileExists($this->pendingDir.'/vendor/laravel/framework/src/file.php');
|
||||
}
|
||||
|
||||
public function test_vendor_mode_bundled_fails_when_bundle_missing(): void
|
||||
{
|
||||
// composer.json 은 있지만 vendor-bundle.zip 없음
|
||||
File::put($this->pendingDir.'/composer.json', json_encode(['name' => 'test/core']));
|
||||
|
||||
$this->expectException(\App\Extension\Vendor\Exceptions\VendorInstallException::class);
|
||||
$this->service->runVendorInstallInPending($this->pendingDir, VendorMode::Bundled);
|
||||
}
|
||||
|
||||
public function test_vendor_mode_bundled_fails_on_tampered_zip(): void
|
||||
{
|
||||
$this->createPendingBundle();
|
||||
|
||||
// zip 해시를 조작하여 무결성 검증 실패 유도
|
||||
$manifestPath = $this->pendingDir.'/vendor-bundle.json';
|
||||
$manifest = json_decode(File::get($manifestPath), true);
|
||||
$manifest['zip_sha256'] = hash('sha256', 'tampered');
|
||||
File::put($manifestPath, json_encode($manifest));
|
||||
|
||||
$this->expectException(\App\Extension\Vendor\Exceptions\VendorInstallException::class);
|
||||
$this->service->runVendorInstallInPending($this->pendingDir, VendorMode::Bundled);
|
||||
}
|
||||
|
||||
public function test_vendor_mode_composer_requires_composer_executor_fallback(): void
|
||||
{
|
||||
// composer 모드 요청이지만 실제 composer 실행은 스킵될 수 있는 환경
|
||||
// runVendorInstallInPending 은 내부적으로 CoreUpdateService::runComposerInstallInPending() 을
|
||||
// composerExecutor 로 전달하므로, composer 바이너리 존재 여부에 따라 동작이 달라짐.
|
||||
File::put($this->pendingDir.'/composer.json', json_encode(['name' => 'test/core']));
|
||||
|
||||
// composer 모드에서 번들 zip 없어도 composer 실행을 시도하지 — zip 무결성 검증 불필요
|
||||
// 실제 실행은 환경에 따라 실패할 수 있으므로 예외 타입만 확인
|
||||
try {
|
||||
$this->service->runVendorInstallInPending($this->pendingDir, VendorMode::Composer);
|
||||
$this->assertTrue(true); // composer 실행 성공 (거의 없음)
|
||||
} catch (\Throwable $e) {
|
||||
$this->assertNotEmpty($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function test_core_update_command_accepts_vendor_mode_option(): void
|
||||
{
|
||||
// 실제 core:update 는 풀 체인 실행이 복잡하므로 --help 출력에서 옵션 존재만 검증
|
||||
$this->artisan('core:update', ['--help' => true])
|
||||
->expectsOutputToContain('--vendor-mode')
|
||||
->assertExitCode(0);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user