Files
Gnuboard7/tests/Unit/Extension/ExtensionCacheVersionStoreConsistencyTest.php
T
2026-07-01 10:30:32 +09:00

105 lines
4.1 KiB
PHP

<?php
namespace Tests\Unit\Extension;
use App\Extension\Traits\ClearsTemplateCaches;
use Illuminate\Support\Facades\Config;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
/**
* `ext.cache_version` 캐시 스토어 일관성 회귀.
*
* 배경: `ext.cache_version` 은 확장 업데이트/설치/레이아웃 변경 시 bump 되어
* 프론트엔드 fetch URL(`?v=`)을 무효화하는 코어 소유 좌표 키다. 값은
* `ClearsTemplateCaches::incrementExtensionCacheVersion()`(write)과
* `getExtensionCacheVersion()`(read)가 **반드시 같은 캐시 스토어**를 써야 한다.
*
* 결함(재현): 종전 구현은 스토어를 `config('cache.default')` 로 매번 해소했다.
* 그런데 `SettingsServiceProvider::applyCacheConfig` 가 부팅 중 admin 설정값
* (`g7_core_settings('cache.driver')`)으로 `cache.default` 를 **런타임 오버라이드**한다.
* 따라서 settings 로드 타이밍/컨텍스트(웹 vs CLI vs 큐, 설정 미시드 환경)에 따라
* write 와 read 가 **서로 다른 스토어**(예: write=database(.env), read=file(settings))를
* 가리키면, bump 한 버전이 read 경로에서 보이지 않아 프론트엔드가 영구 stale 캐시를
* 받는다(편집기 데이터소스 명칭/레이아웃 변경 미반영).
*
* 본 테스트는 write 직후 read 사이에 `config('cache.default')` 가 바뀌어도(설정
* 오버라이드 시뮬레이션) 값이 일관되게 보존됨을 잠근다.
*/
class ExtensionCacheVersionStoreConsistencyTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
// 스토어 메모 초기화 — 각 테스트가 자기 cache.default 기준으로 1회 해소하도록.
ClearsTemplateCaches::resetExtensionCacheStoreMemo();
}
protected function tearDown(): void
{
ClearsTemplateCaches::resetExtensionCacheStoreMemo();
parent::tearDown();
}
/** trait protected 메서드 노출용 더블 */
private function makeSubject(): object
{
return new class
{
use ClearsTemplateCaches;
public function bump(): void
{
$this->incrementExtensionCacheVersion();
}
public function read(): int
{
return self::getExtensionCacheVersion();
}
};
}
#[Test]
public function version_bump_is_readable_after_cache_default_changes(): void
{
$subject = $this->makeSubject();
// write 시점 — 한 스토어(예: array)
Config::set('cache.default', 'array');
$subject->bump();
$written = $subject->read();
$this->assertGreaterThan(0, $written, 'bump 직후 같은 스토어에서 읽혀야 함');
// read 시점 — settings 오버라이드로 cache.default 가 바뀐 상황 시뮬레이션
Config::set('cache.default', 'file');
$afterChange = $subject->read();
// 핵심 불변식: write 와 read 가 같은 고정 스토어를 쓰므로 cache.default 변경에
// 영향받지 않고 동일 값이 보여야 한다(스토어 분기 = stale 캐시 회귀).
$this->assertSame(
$written,
$afterChange,
'ext.cache_version 은 cache.default 변경과 무관하게 동일 스토어로 일관 read/write 되어야 함'
);
}
#[Test]
public function version_written_under_one_default_is_visible_under_another(): void
{
$subject = $this->makeSubject();
// database(.env 기본) 스토어 컨텍스트에서 write
Config::set('cache.default', 'database');
$subject->bump();
$v1 = $subject->read();
// file(settings 오버라이드) 스토어 컨텍스트에서 read — 같은 값이어야 함
Config::set('cache.default', 'file');
$v2 = $subject->read();
$this->assertSame($v1, $v2, 'write/read 컨텍스트의 cache.default 가 달라도 같은 버전이 보여야 함');
$this->assertGreaterThan(0, $v2, 'read 컨텍스트에서 0(미설정)으로 떨어지면 stale 캐시 회귀');
}
}