getMiddleware(); $detect = collect($declarations)->firstWhere('class', DetectDevice::class); $this->assertNotNull($detect, 'Module::getMiddleware() 가 DetectDevice 를 선언해야 합니다.'); $this->assertSame(['web'], $detect['groups'], 'DetectDevice 는 web 그룹 선언이어야 합니다.'); $this->assertContains('/', $detect['targets'], 'DetectDevice 는 무명 SSR 셸용 URI 패턴 "/" 로 타게팅해야 합니다.'); } /** * @scenario mark_form=badge, requires_ios=true, device=non_ios * * @effects server_ua_sets_is_ios */ public function test_gate_resolves_detect_device_for_root_uri(): void { ExtensionMiddlewareRegistry::flush(); $registry = $this->app->make(ExtensionMiddlewareRegistryInterface::class); // 무명 SSR 셸 catch-all: routeName='' + path '/' → web/after_core 에서 DetectDevice 매칭. $matched = $registry->resolveForRoute('', '/', 'web', 'after_core'); $this->assertContains( DetectDevice::class, $matched, '코어 게이트가 루트 URI(무명 라우트) 요청에서 DetectDevice 를 매칭해야 SSR 셸에서 실행된다.' ); ExtensionMiddlewareRegistry::flush(); } /** * @scenario mark_form=badge, requires_ios=true, device=non_ios * * @effects server_ua_sets_is_ios */ public function test_gate_does_not_match_detect_device_for_api_group(): void { ExtensionMiddlewareRegistry::flush(); $registry = $this->app->make(ExtensionMiddlewareRegistryInterface::class); // DetectDevice 는 web 그룹만 선언 → api 그룹 조회에서는 매칭되지 않는다. $matched = $registry->resolveForRoute('', '/', 'api', 'after_core'); $this->assertNotContains(DetectDevice::class, $matched); ExtensionMiddlewareRegistry::flush(); } }