shouldReceive('routeExists')->andReturn($exists); $this->app->instance(TemplateRouteResolver::class, $resolver); } /** * 미등록 user 경로는 404 + SPA 셸 본문을 반환합니다. */ public function test_unregistered_user_path_returns_404_with_shell(): void { $this->bindResolver(false); $response = $this->get('/this-does-not-exist'); $response->assertStatus(404); $response->assertSee('id="app"', false); // SPA 셸 마커 (본문은 그대로) } /** * 등록된 user 경로는 200 을 반환합니다. */ public function test_registered_user_path_returns_200(): void { $this->bindResolver(true); $response = $this->get('/some-registered-route'); $response->assertStatus(200); $response->assertSee('id="app"', false); } /** * 미등록 admin 경로는 404 + admin 셸 본문을 반환합니다. */ public function test_unregistered_admin_path_returns_404(): void { $this->bindResolver(false); $response = $this->get('/admin/nonexistent'); $response->assertStatus(404); } /** * 등록된 admin 경로는 200 을 반환합니다. */ public function test_registered_admin_path_returns_200(): void { $this->bindResolver(true); $response = $this->get('/admin/users'); $response->assertStatus(200); } /** * 봇(Googlebot) 미등록 경로도 404 를 받습니다 (봇/비봇 일관). */ public function test_bot_unregistered_path_returns_404(): void { $this->bindResolver(false); $response = $this->get('/this-does-not-exist', [ 'User-Agent' => 'Googlebot/2.1 (+http://www.google.com/bot.html)', ]); $response->assertStatus(404); } /** * 정적 자산 확장자 경로는 catch-all 에 진입하지 않습니다 (where 정규식 제외). */ public function test_static_asset_path_not_handled_by_catchall(): void { $this->bindResolver(false); // .js 확장자는 catch-all where 정규식에서 제외 → 404(라우트 미정의)이되 // routeExists 호출 경로를 타지 않음. 상태만 확인(파일 미존재로 404). $response = $this->get('/assets/app.js'); $this->assertContains($response->getStatusCode(), [404]); } }