import unittest from fastapi.testclient import TestClient from admin_app.api.dependencies import get_auth_service, get_current_panel_staff_context from admin_app.api.panel_session import PANEL_ACCESS_COOKIE_NAME, PANEL_REFRESH_COOKIE_NAME from admin_app.app_factory import create_app from admin_app.core import ( AdminAuthenticatedSession, AdminSettings, AuthenticatedStaffContext, AuthenticatedStaffPrincipal, ) from shared.contracts import StaffRole class _FakePanelAuthService: def login(self, email: str, password: str, *, ip_address: str | None, user_agent: str | None): if email == "admin@empresa.com" and password == "SenhaMuitoSegura!123": principal = AuthenticatedStaffPrincipal( id=1, email="admin@empresa.com", display_name="Administrador", role=StaffRole.ADMIN, is_active=True, ) return AdminAuthenticatedSession( session_id=77, access_token="panel-access-token", refresh_token="panel-refresh-token", token_type="bearer", expires_in_seconds=1800, principal=principal, ) return None def refresh_session(self, refresh_token: str, *, ip_address: str | None, user_agent: str | None): if refresh_token == "panel-refresh-token": principal = AuthenticatedStaffPrincipal( id=1, email="admin@empresa.com", display_name="Administrador", role=StaffRole.ADMIN, is_active=True, ) return AdminAuthenticatedSession( session_id=77, access_token="panel-access-token-next", refresh_token="panel-refresh-token-next", token_type="bearer", expires_in_seconds=1800, principal=principal, ) return None def get_authenticated_context(self, access_token: str) -> AuthenticatedStaffContext: if access_token in {"panel-access-token", "panel-access-token-next"}: return AuthenticatedStaffContext( principal=AuthenticatedStaffPrincipal( id=1, email="admin@empresa.com", display_name="Administrador", role=StaffRole.ADMIN, is_active=True, ), session_id=77, ) raise ValueError("invalid token") def logout( self, session_id: int, *, actor_staff_account_id: int | None, ip_address: str | None, user_agent: str | None, ) -> bool: return session_id == 77 def logout_by_refresh_token( self, refresh_token: str, *, ip_address: str | None, user_agent: str | None, ) -> int | None: if refresh_token in {"panel-refresh-token", "panel-refresh-token-next"}: return 77 return None class AdminPanelAuthWebTests(unittest.TestCase): def setUp(self): app = create_app(AdminSettings(admin_auth_token_secret="test-secret")) app.dependency_overrides[get_auth_service] = lambda: _FakePanelAuthService() self.client = TestClient(app) self.app = app def tearDown(self): self.app.dependency_overrides.clear() def test_panel_login_sets_http_only_cookies_and_returns_session_payload(self): response = self.client.post( "/panel/auth/login", json={"email": "admin@empresa.com", "password": "SenhaMuitoSegura!123"}, ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["session_id"], 77) self.assertEqual(response.json()["redirect_to"], "/panel/admin") self.assertEqual(response.cookies.get(PANEL_ACCESS_COOKIE_NAME), "panel-access-token") self.assertEqual(response.cookies.get(PANEL_REFRESH_COOKIE_NAME), "panel-refresh-token") set_cookie_headers = response.headers.get_list("set-cookie") self.assertTrue(any("HttpOnly" in header for header in set_cookie_headers)) def test_panel_refresh_rotates_cookie_backed_session(self): self.client.cookies.set(PANEL_REFRESH_COOKIE_NAME, "panel-refresh-token") response = self.client.post("/panel/auth/refresh") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["message"], "Sessao administrativa web renovada.") self.assertEqual(response.cookies.get(PANEL_ACCESS_COOKIE_NAME), "panel-access-token-next") self.assertEqual(response.cookies.get(PANEL_REFRESH_COOKIE_NAME), "panel-refresh-token-next") def test_panel_session_reads_authenticated_staff_from_cookie_context(self): app = create_app(AdminSettings(admin_auth_token_secret="test-secret")) app.dependency_overrides[get_current_panel_staff_context] = lambda: AuthenticatedStaffContext( principal=AuthenticatedStaffPrincipal( id=1, email="admin@empresa.com", display_name="Administrador", role=StaffRole.ADMIN, is_active=True, ), session_id=77, ) client = TestClient(app) try: response = client.get("/panel/auth/session") finally: app.dependency_overrides.clear() self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["staff_account"]["email"], "admin@empresa.com") self.assertEqual(response.json()["session_id"], 77) def test_panel_logout_clears_cookies_and_returns_login_redirect(self): self.client.cookies.set(PANEL_ACCESS_COOKIE_NAME, "panel-access-token") self.client.cookies.set(PANEL_REFRESH_COOKIE_NAME, "panel-refresh-token") response = self.client.post("/panel/auth/logout") self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["redirect_to"], "/login") set_cookie_headers = response.headers.get_list("set-cookie") self.assertTrue(any(PANEL_ACCESS_COOKIE_NAME in header and "Max-Age=0" in header for header in set_cookie_headers)) self.assertTrue(any(PANEL_REFRESH_COOKIE_NAME in header and "Max-Age=0" in header for header in set_cookie_headers)) if __name__ == "__main__": unittest.main()