Files
Gnuboard7/tests/Feature/Extension/ExtensionTestIsolationGdprAllowedTest.php
T
HeuJung c0e0d82459 refactor(extension): 확장 미들웨어 선언적 self-gate 정규화
확장이 SP Kernel 미들웨어 그룹을 직접 조작하거나 라우트 파일에 미들웨어
FQCN 을 직접 부착하던 임시 방식을, 확장이 부착 대상(targets)을 명시 선언하고
코어가 요청 시점에 라우트명·URI 로 매칭해 실행하는 self-gate 로 정규화.
번들 7건(ecommerce/gdpr/pay 3종) 이전, audit 룰 3건·문서·버전 동기화 동반.

부수적으로 generate-skills.cjs 가 재생성 시 신의성실(부수의무) 섹션을 소실
시키던 회귀를 수정 — 스킬별 불릿을 스크립트 SSoT 로 편입해 재생성에도 보존.
2026-07-16 10:22:51 +09:00

118 lines
4.5 KiB
PHP

<?php
namespace Tests\Feature\Extension;
use App\Contracts\Extension\ExtensionMiddlewareRegistryInterface;
use App\Enums\ExtensionStatus;
use App\Extension\ExtensionMiddlewareRegistry;
use App\Extension\PluginManager;
use App\Extension\Testing\ExtensionTestAllowlist;
use App\Http\Middleware\ExtensionMiddlewareGate;
use App\Models\Plugin;
use Illuminate\Contracts\Http\Kernel as HttpKernelContract;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Plugins\Sirsoft\Gdpr\Http\Middleware\CookieConsentMiddleware;
use Plugins\Sirsoft\Gdpr\Providers\GdprServiceProvider;
use Tests\TestCase;
/**
* 테스트 환경 확장 격리 회귀 테스트 — allowlist 포함 시나리오
*
* requiredExtensions 에 GDPR 플러그인을 명시하면 해당 플러그인의 ServiceProvider 가 로드되고,
* 코어 self-gate 게이트가 GDPR 이 getMiddleware() 로 선언한 CookieConsentMiddleware 를 실행한다.
* (이관 전: SP boot 이 web/api 그룹에 직접 prepend. 이관 후: getMiddleware() 선언 + 게이트 실행)
*/
class ExtensionTestIsolationGdprAllowedTest extends TestCase
{
use RefreshDatabase;
/**
* GDPR 플러그인을 allowlist 에 명시.
*
* @var array<string>
*/
protected array $requiredExtensions = [
'plugins/sirsoft-gdpr',
];
/**
* @effects allowlisted_plugin_service_provider_is_registered
*/
public function test_allowlisted_plugin_service_provider_is_registered(): void
{
$this->assertTrue(ExtensionTestAllowlist::isAllowed('plugin', 'sirsoft-gdpr'));
$this->assertTrue(
$this->app->providerIsLoaded(GdprServiceProvider::class),
'allowlist 에 명시된 GdprServiceProvider 가 등록되지 않았습니다'
);
}
/**
* @effects allowlisted_plugin_middleware_is_registered_in_web_group
*/
public function test_self_gate_wrapper_is_registered_in_web_and_api_groups(): void
{
// 코어 게이트 래퍼는 항상 web/api 그룹에 등록된다 (확장 미들웨어를 요청 시점에 실행).
$kernel = $this->app->make(HttpKernelContract::class);
$this->assertInstanceOf(HttpKernel::class, $kernel);
$groups = $kernel->getMiddlewareGroups();
foreach (['web', 'api'] as $group) {
$hasGate = collect($groups[$group] ?? [])
->contains(fn ($m) => is_string($m) && str_starts_with($m, ExtensionMiddlewareGate::class));
$this->assertTrue($hasGate, "{$group} 그룹에 ExtensionMiddlewareGate 래퍼가 등록되어야 합니다.");
}
}
/**
* @effects allowlisted_plugin_middleware_is_registered_in_web_group
*/
public function test_gate_resolves_gdpr_cookie_consent_when_active(): void
{
// GDPR 을 활성 상태로 등록하면, 게이트가 CookieConsentMiddleware 를
// 모든 요청(everything/before_core)에서 매칭한다 (EDPB §16 광역 타게팅).
$this->activateGdprForGate();
ExtensionMiddlewareRegistry::flush();
$registry = $this->app->make(ExtensionMiddlewareRegistryInterface::class);
foreach (['web', 'api'] as $group) {
$matched = $registry->resolveForRoute('any.route.name', 'any/path', $group, 'before_core');
$this->assertContains(
CookieConsentMiddleware::class,
$matched,
"GDPR 활성 시 {$group}/before_core 에서 CookieConsentMiddleware 가 매칭되어야 합니다.",
);
}
ExtensionMiddlewareRegistry::flush();
}
/**
* GDPR 플러그인을 활성 상태로 등록해 게이트가 그 미들웨어를 수집하도록 합니다.
*/
private function activateGdprForGate(): void
{
Plugin::query()->updateOrCreate(
['identifier' => 'sirsoft-gdpr'],
[
'vendor' => 'sirsoft',
'name' => json_encode(['ko' => 'GDPR', 'en' => 'GDPR']),
'version' => '1.0.0',
'status' => ExtensionStatus::Active->value,
]
);
PluginManager::invalidatePluginStatusCache();
$pluginManager = $this->app->make(PluginManager::class);
$property = new \ReflectionProperty($pluginManager, 'plugins');
$property->setAccessible(true);
$plugins = $property->getValue($pluginManager);
$plugins['sirsoft-gdpr'] = new \Plugins\Sirsoft\Gdpr\Plugin;
$property->setValue($pluginManager, $plugins);
}
}