빈 번들 503 을 "에셋을 선언한 활성 확장이 있는데 결과가 비었다" 로 판정해, 스타일 규칙이 아직 없는 0바이트 CSS 만 선언된 기본 구성이 통째로 503 이 됐다. file_get_contents 는 0바이트에서 false 가 아니라 '' 를 돌려주므로 읽기 실패 분기도 타지 않는다. 선언 축 게터는 전부 file_exists 게이트라 부재를 셀 수 없어, 존재 게이트가 없는 getDeclaredAssetAbsolutePaths 를 통로로 두고 503 의 근거를 소실 축(findMissingDeclaredAssets)으로 옮긴다. 존재하되 비었으면 빈 200 이다. 곁들여: 실패 배너 항목명을 내부 구분 키에서 사용자 어휘로(engine-v1.64.7), 봇 화면이 없는 템플릿 CSS 를 링크하지 않도록 실재 게이트, 매니페스트 자산 선언 드리프트 4건 정정.
120 lines
3.6 KiB
PHP
120 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Unit\Extension;
|
|
|
|
use App\Extension\AbstractPlugin;
|
|
use Illuminate\Support\Facades\File;
|
|
use Tests\TestCase;
|
|
|
|
/**
|
|
* AbstractPlugin::getDeclaredAssetAbsolutePaths() 단위 테스트
|
|
*
|
|
* 모듈 축과 동형이다 — 한쪽만 고쳐지면 플러그인 번들의 소실 판정이 조용히 침묵한다.
|
|
*
|
|
* @see AbstractModuleDeclaredAssetsTest
|
|
*/
|
|
class AbstractPluginDeclaredAssetsTest extends TestCase
|
|
{
|
|
private string $pluginDir;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->pluginDir = storage_path('framework/testing/declared-assets-plugin/vendor-sample');
|
|
File::ensureDirectoryExists($this->pluginDir);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
File::deleteDirectory(dirname($this->pluginDir));
|
|
parent::tearDown();
|
|
}
|
|
|
|
/**
|
|
* 임시 디렉토리를 플러그인 루트로 쓰는 익명 서브클래스를 만든다.
|
|
*
|
|
* @param array<string, mixed> $assets 매니페스트 assets 선언
|
|
*/
|
|
private function pluginWithAssets(array $assets): AbstractPlugin
|
|
{
|
|
File::put(
|
|
$this->pluginDir.'/plugin.json',
|
|
json_encode(['name' => 'sample', 'version' => '1.0.0', 'assets' => $assets], JSON_UNESCAPED_UNICODE)
|
|
);
|
|
|
|
$root = $this->pluginDir;
|
|
|
|
return new class($root) extends AbstractPlugin
|
|
{
|
|
public function __construct(private readonly string $root) {}
|
|
|
|
protected function getPluginPath(): string
|
|
{
|
|
return $this->root;
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 산출물이 하나도 없어도 선언한 kind 마다 절대 경로가 나온다.
|
|
*/
|
|
public function test_returns_declared_paths_even_when_files_are_absent(): void
|
|
{
|
|
$plugin = $this->pluginWithAssets([
|
|
'js' => ['output' => 'dist/js/plugin.iife.js'],
|
|
'css' => ['output' => 'dist/css/plugin.css'],
|
|
]);
|
|
|
|
$this->assertSame(
|
|
[
|
|
'js' => $this->pluginDir.'/dist/js/plugin.iife.js',
|
|
'css' => $this->pluginDir.'/dist/css/plugin.css',
|
|
],
|
|
$plugin->getDeclaredAssetAbsolutePaths()
|
|
);
|
|
$this->assertSame([], $plugin->getBuiltAssetAbsolutePaths());
|
|
}
|
|
|
|
/**
|
|
* 선언하지 않은 kind 는 키 자체가 없다.
|
|
*/
|
|
public function test_omits_undeclared_kinds(): void
|
|
{
|
|
$plugin = $this->pluginWithAssets(['css' => ['output' => 'dist/css/plugin.css']]);
|
|
|
|
$declared = $plugin->getDeclaredAssetAbsolutePaths();
|
|
|
|
$this->assertArrayHasKey('css', $declared);
|
|
$this->assertArrayNotHasKey('js', $declared);
|
|
}
|
|
|
|
/**
|
|
* `output` 이 비어 있으면 선언으로 보지 않는다.
|
|
*/
|
|
public function test_treats_empty_output_as_undeclared(): void
|
|
{
|
|
$plugin = $this->pluginWithAssets([
|
|
'js' => ['output' => ''],
|
|
'css' => [],
|
|
]);
|
|
|
|
$this->assertSame([], $plugin->getDeclaredAssetAbsolutePaths());
|
|
}
|
|
|
|
/**
|
|
* 산출물이 존재하되 0바이트여도 경로는 그대로 나온다.
|
|
*/
|
|
public function test_returns_path_for_present_zero_byte_artifact(): void
|
|
{
|
|
$plugin = $this->pluginWithAssets(['css' => ['output' => 'dist/css/plugin.css']]);
|
|
File::ensureDirectoryExists($this->pluginDir.'/dist/css');
|
|
File::put($this->pluginDir.'/dist/css/plugin.css', '');
|
|
|
|
$path = $plugin->getDeclaredAssetAbsolutePaths()['css'];
|
|
|
|
$this->assertSame($this->pluginDir.'/dist/css/plugin.css', $path);
|
|
$this->assertTrue(is_file($path));
|
|
$this->assertSame(0, filesize($path));
|
|
}
|
|
}
|