Files
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

127 lines
3.8 KiB
PHP

<?php
namespace Plugins\Sirsoft\Ckeditor5\Tests\Unit;
use App\Extension\HookManager;
use Illuminate\Support\Facades\Config;
use PHPUnit\Framework\Attributes\Test;
use Plugins\Sirsoft\Ckeditor5\Models\Ckeditor5ImageUpload;
use Plugins\Sirsoft\Ckeditor5\Tests\PluginTestCase;
/**
* Ckeditor5ImageUpload download_url(직접 URL/폴백) 단위 테스트
*
* file_path 의 첫 세그먼트=카테고리 일반형 분해와 행 storage_disk 기준
* 직접 URL/스트리밍 폴백을 검증합니다.
*/
class Ckeditor5ImageUploadUrlTest extends PluginTestCase
{
protected function setUp(): void
{
parent::setUp();
Config::set('filesystems.disks.fake_cdn', [
'driver' => 'local',
'root' => storage_path('framework/testing/disks/fake_cdn'),
'url' => 'https://cdn.test/assets',
]);
Ckeditor5ImageUpload::flushStorageCache();
}
protected function tearDown(): void
{
Ckeditor5ImageUpload::flushStorageCache();
HookManager::resetAll();
parent::tearDown();
}
/**
* @scenario consumer=editor, disk_setting=public, e2e=ecommerce_settings_field, hook=unregistered, override=follow_core, row_state=legacy_local_row
*
* @effects download_url_falls_back_to_api_path_when_direct_unavailable
*/
#[Test]
public function it_falls_back_to_api_url_for_plugins_disk_row(): void
{
$image = new Ckeditor5ImageUpload([
'hash' => 'aaaabbbbcccc',
'file_path' => 'images/2026/01/01/a.jpg',
'storage_disk' => 'plugins',
]);
$this->assertSame(
'/api/plugins/sirsoft-ckeditor5/images/aaaabbbbcccc',
$image->download_url
);
}
#[Test]
public function it_returns_direct_url_for_cdn_disk_row(): void
{
$image = new Ckeditor5ImageUpload([
'hash' => 'aaaabbbbcccc',
'file_path' => 'images/2026/01/01/a.jpg',
'storage_disk' => 'fake_cdn',
]);
$this->assertSame(
'https://cdn.test/assets/sirsoft-ckeditor5/images/2026/01/01/a.jpg',
$image->download_url
);
}
#[Test]
public function it_decomposes_non_images_prefix_generically(): void
{
// ApiDocSampleService 등 외부 생성 행 — 첫 세그먼트=카테고리 일반형
$image = new Ckeditor5ImageUpload([
'hash' => 'aaaabbbbcccc',
'file_path' => 'ckeditor5/apidoc-sample.png',
'storage_disk' => 'fake_cdn',
]);
$this->assertSame(
'https://cdn.test/assets/sirsoft-ckeditor5/ckeditor5/apidoc-sample.png',
$image->download_url
);
}
#[Test]
public function it_falls_back_when_file_path_has_no_prefix(): void
{
$image = new Ckeditor5ImageUpload([
'hash' => 'aaaabbbbcccc',
'file_path' => 'orphan.png',
'storage_disk' => 'fake_cdn',
]);
$this->assertSame(
'/api/plugins/sirsoft-ckeditor5/images/aaaabbbbcccc',
$image->download_url
);
}
/**
* @scenario consumer=editor, disk_setting=fake_cdn, e2e=drivers_tab_card, hook=block, override=module_override, row_state=legacy_local_row
*
* @effects hook_supply_modify_block_respected
*/
#[Test]
public function hook_block_falls_back_to_api_url(): void
{
HookManager::addFilter('core.storage.filter_url', fn ($url) => '');
$image = new Ckeditor5ImageUpload([
'hash' => 'aaaabbbbcccc',
'file_path' => 'images/2026/01/01/a.jpg',
'storage_disk' => 'fake_cdn',
]);
$this->assertSame(
'/api/plugins/sirsoft-ckeditor5/images/aaaabbbbcccc',
$image->download_url
);
}
}