Files
Gnuboard7/plugins/_bundled/sirsoft-ckeditor5/tests/Unit/PluginSettingsPublicAssetDiskValidationTest.php
HeuJung 057e002ad1 feat(core,ecommerce,ckeditor5,board,admin_basic): 공개 자산 직접 URL(CDN) 서빙 옵트인
StorageInterface::url 의 public 하드코딩을 완화하고 core.storage.filter_url 훅을
신설해, 완전 공개 자산(상품·카테고리·리뷰·에디터 이미지)의 직접 URL 서빙을 옵트인으로
열었다. 미설정 시 기존 스트리밍 100% 보존.

디스크 결정은 확장 개별 설정 > 코어 전역 > 미설정 순이며, 서빙·삭제·이동은 행에 기록된
disk 를 따라 전환 전후 자산이 혼재해도 각자 실제 저장 위치를 향한다. 고아 disk(공급
플러그인 비활성화)는 스트리밍으로 폴백해 500 이 되지 않는다.

공개 이슈 (@lyg-kaban 건의) 대응.
2026-08-14 08:05:54 +09:00

120 lines
4.0 KiB
PHP

<?php
namespace Plugins\Sirsoft\Ckeditor5\Tests\Unit;
use App\Extension\AbstractPlugin;
use App\Extension\PluginManager;
use App\Http\Requests\Admin\UpdatePluginSettingsRequest;
use Illuminate\Validation\ValidationException;
use PHPUnit\Framework\Attributes\Test;
use Plugins\Sirsoft\Ckeditor5\Tests\PluginTestCase;
/**
* 플러그인 공개 자산 디스크 저장 검증 테스트 (공개#100)
*
* 코어가 카탈로그를 부착하는 게이트(스키마에 public_asset_disk 선언)와 동일한
* 조건에서 값 검증도 걸린다. 선택지를 내려주는 표면과 값을 받는 표면의 강도가
* 갈리면, 오타 디스크명이 200 으로 저장된 뒤 런타임 폴백만 남아 운영자에게는
* "저장은 됐는데 CDN 이 안 붙는" 무증상 상태로만 보인다.
*
* 스키마 타입만으로는 검증할 수 없다 — 선택지가 코어 3종 + 플러그인 훅 등록
* 디스크라 런타임에만 확정되기 때문이다.
*
* @effects invalid_disk_rejected_with_422
*/
class PluginSettingsPublicAssetDiskValidationTest extends PluginTestCase
{
/**
* 플러그인 설정 저장 요청을 해석합니다.
*
* @param string $disk public_asset_disk 값
*/
private function resolve(string $disk): UpdatePluginSettingsRequest
{
$request = UpdatePluginSettingsRequest::create('/', 'PUT', [
'public_asset_disk' => $disk,
]);
$request->setContainer($this->app)->setRedirector($this->app['redirect']);
$request->setRouteResolver(fn () => new class
{
public function parameter(string $key, $default = null): string
{
return 'sirsoft-ckeditor5';
}
});
$request->validateResolved();
return $request;
}
#[Test]
public function core_catalog_disk_is_accepted(): void
{
$request = $this->resolve('public');
$this->assertSame('public', $request->validated()['public_asset_disk']);
}
#[Test]
public function empty_value_is_accepted_as_follow_core(): void
{
$request = $this->resolve('');
$this->assertSame('', $request->validated()['public_asset_disk'] ?? '');
}
#[Test]
public function unknown_disk_is_rejected(): void
{
$this->expectException(ValidationException::class);
try {
$this->resolve('nonexistent_disk');
} catch (ValidationException $e) {
$this->assertArrayHasKey(
'public_asset_disk',
$e->validator->errors()->toArray(),
'카탈로그에 없는 디스크는 public_asset_disk 오류를 내야 한다'
);
throw $e;
}
}
#[Test]
public function validation_gate_is_closed_when_schema_lacks_the_key(): void
{
// 이 키를 선언하지 않은 플러그인에는 검증도 붙지 않아야 한다 —
// 부착 게이트(PluginSettingsController)와 검증 게이트가 같은 조건이어야 한다.
$plugin = $this->createMock(AbstractPlugin::class);
$plugin->method('getSettingsSchema')->willReturn([
'some_other_key' => ['type' => 'string'],
]);
$manager = $this->createMock(PluginManager::class);
$manager->method('getPlugin')->willReturn($plugin);
$this->app->instance(PluginManager::class, $manager);
$request = UpdatePluginSettingsRequest::create('/', 'PUT', [
'some_other_key' => 'value',
]);
$request->setContainer($this->app)->setRedirector($this->app['redirect']);
$request->setRouteResolver(fn () => new class
{
public function parameter(string $key, $default = null): string
{
return 'other-plugin';
}
});
$this->assertArrayNotHasKey('public_asset_disk', $request->rules());
}
protected function tearDown(): void
{
$this->app->forgetInstance(PluginManager::class);
parent::tearDown();
}
}