import pytest from aiohttp import web from aiohttp.test_utils import TestClient, TestServer from gateway.config import PlatformConfig from gateway.platforms.api_server import APIServerAdapter, cors_middleware, security_headers_middleware def _make_adapter(api_key: str = '') -> APIServerAdapter: extra = {'key': api_key} if api_key else {} return APIServerAdapter(PlatformConfig(enabled=True, extra=extra)) def _create_app(adapter: APIServerAdapter) -> web.Application: mws = [mw for mw in (cors_middleware, security_headers_middleware) if mw is not None] app = web.Application(middlewares=mws) app['api_server_adapter'] = adapter adapter._register_routes(app) return app class TestWebConsoleRoutes: @pytest.mark.asyncio async def test_root_serves_web_console_html(self): adapter = _make_adapter() app = _create_app(adapter) async with TestClient(TestServer(app)) as cli: resp = await cli.get('/') assert resp.status == 200 text = await resp.text() assert 'Hermes Web Console' in text assert '/api/gui/browser/status' in text assert '/api/gui/browser/heal' in text @pytest.mark.asyncio async def test_browser_status_returns_json(self): adapter = _make_adapter() app = _create_app(adapter) async with TestClient(TestServer(app)) as cli: from unittest.mock import patch with patch('gateway.platforms.api_server_ui.browser_runtime_status', return_value={'mode': 'local', 'session_count': 0, 'available': True}): resp = await cli.get('/api/gui/browser/status') assert resp.status == 200 data = await resp.json() assert data['mode'] == 'local' assert data['session_count'] == 0 @pytest.mark.asyncio async def test_browser_status_requires_auth_when_key_set(self): adapter = _make_adapter(api_key='sk-secret') app = _create_app(adapter) async with TestClient(TestServer(app)) as cli: resp = await cli.get('/api/gui/browser/status') assert resp.status == 401 @pytest.mark.asyncio async def test_browser_heal_invokes_runtime_heal(self): adapter = _make_adapter() app = _create_app(adapter) async with TestClient(TestServer(app)) as cli: from unittest.mock import patch with patch('gateway.platforms.api_server_ui.browser_runtime_heal', return_value={'success': True, 'before': {'session_count': 1}, 'after': {'session_count': 0}}) as mock_heal: resp = await cli.post('/api/gui/browser/heal') assert resp.status == 200 data = await resp.json() assert data['success'] is True assert data['after']['session_count'] == 0 mock_heal.assert_called_once_with()