"""Tests for CER-016 risk guard.""" from __future__ import annotations import pytest from fastapi import HTTPException from option_mcp_common.risk_guard import ( enforce_aggregate, enforce_leverage, enforce_single_notional, max_aggregate, max_leverage, max_notional, ) def test_defaults(monkeypatch): for k in ("CERBERO_MAX_NOTIONAL", "CERBERO_MAX_AGGREGATE", "CERBERO_MAX_LEVERAGE"): monkeypatch.delenv(k, raising=False) assert max_notional() == 200.0 assert max_aggregate() == 1000.0 assert max_leverage() == 3 def test_env_override(monkeypatch): monkeypatch.setenv("CERBERO_MAX_NOTIONAL", "50") monkeypatch.setenv("CERBERO_MAX_AGGREGATE", "150") monkeypatch.setenv("CERBERO_MAX_LEVERAGE", "2") assert max_notional() == 50.0 assert max_aggregate() == 150.0 assert max_leverage() == 2 def test_leverage_default_when_none(monkeypatch): monkeypatch.delenv("CERBERO_MAX_LEVERAGE", raising=False) assert enforce_leverage(None) == 3 def test_leverage_accepts_within_cap(monkeypatch): monkeypatch.delenv("CERBERO_MAX_LEVERAGE", raising=False) assert enforce_leverage(2) == 2 assert enforce_leverage(3) == 3 def test_leverage_rejects_above_cap(monkeypatch): monkeypatch.delenv("CERBERO_MAX_LEVERAGE", raising=False) with pytest.raises(HTTPException) as exc: enforce_leverage(50) assert exc.value.status_code == 403 assert exc.value.detail["error"] == "HARD_PROHIBITION" def test_leverage_rejects_below_one(monkeypatch): with pytest.raises(HTTPException): enforce_leverage(0) def test_single_notional_ok(monkeypatch): monkeypatch.delenv("CERBERO_MAX_NOTIONAL", raising=False) enforce_single_notional(100.0, exchange="deribit", instrument="BTC-PERPETUAL") def test_single_notional_rejects(monkeypatch): monkeypatch.delenv("CERBERO_MAX_NOTIONAL", raising=False) with pytest.raises(HTTPException) as exc: enforce_single_notional(335.0, exchange="hyperliquid", instrument="ETH") assert exc.value.status_code == 403 assert "335" in exc.value.detail["message"] def test_aggregate_ok(monkeypatch): monkeypatch.delenv("CERBERO_MAX_AGGREGATE", raising=False) enforce_aggregate(current_total=500.0, new_notional=200.0) def test_aggregate_rejects(monkeypatch): monkeypatch.delenv("CERBERO_MAX_AGGREGATE", raising=False) with pytest.raises(HTTPException) as exc: enforce_aggregate(current_total=900.0, new_notional=200.0) assert exc.value.status_code == 403