from pathlib import Path from datetime import timedelta import pytest from backend.src.services import config as config_module from backend.src.services.auth import AuthError, AuthService @pytest.fixture(autouse=True) def restore_config_cache(): config_module.reload_config() yield config_module.reload_config() def test_auth_service_requires_secret(monkeypatch, tmp_path: Path) -> None: monkeypatch.delenv("JWT_SECRET_KEY", raising=False) monkeypatch.setenv("VAULT_BASE_PATH", str(tmp_path)) cfg = config_module.reload_config() service = AuthService(config=cfg) with pytest.raises(AuthError) as excinfo: service.create_jwt("user-123") assert excinfo.value.error == "missing_jwt_secret" def test_auth_service_signs_and_validates_with_secret(monkeypatch, tmp_path: Path) -> None: secret = "a-secure-secret-value-123" monkeypatch.setenv("JWT_SECRET_KEY", secret) monkeypatch.setenv("VAULT_BASE_PATH", str(tmp_path)) cfg = config_module.reload_config() service = AuthService(config=cfg) token = service.create_jwt("user-123") payload = service.validate_jwt(token) assert payload.sub == "user-123" def test_auth_service_accepts_local_dev_token_without_secret(monkeypatch, tmp_path: Path) -> None: monkeypatch.delenv("JWT_SECRET_KEY", raising=False) monkeypatch.setenv("VAULT_BASE_PATH", str(tmp_path)) monkeypatch.setenv("LOCAL_DEV_TOKEN", "dev-token-123") cfg = config_module.reload_config() service = AuthService(config=cfg) payload = service.validate_jwt("dev-token-123") assert payload.sub == "local-dev" def test_auth_service_rejects_expired_token(monkeypatch, tmp_path: Path) -> None: monkeypatch.setenv("JWT_SECRET_KEY", "another-secure-secret-value-456") monkeypatch.setenv("VAULT_BASE_PATH", str(tmp_path)) cfg = config_module.reload_config() service = AuthService(config=cfg) expired_token = service.create_jwt("user-expired", expires_in=timedelta(seconds=-1)) with pytest.raises(AuthError) as excinfo: service.validate_jwt(expired_token) assert excinfo.value.error == "token_expired"