FinSight / tests /test_red_flags.py
Sanjam19's picture
Deploy FinSight demo (single-container Docker Space)
d4f8959 verified
Raw
History Blame Contribute Delete
2.94 kB
from backend.red_flags import (
evaluate_red_flags,
compute_risk_score,
overall_confidence,
get_value,
FLAG_SEVERITY,
)
class FakeGraph:
def __init__(self, data):
self._data = data
def get_company_metrics(self, company):
return self._data.get(company, {})
FAKE_DATA = {
"HDFC Bank": {
"2023": {
"deposits": {"value": 1_900_000_00_00_000, "confidence": "high"},
"gross_npa_pct": 1.3, "net_npa_pct": 0.4,
"casa_ratio": 44.0, "capital_adequacy": 18.9,
},
"2024": {
"profit_after_tax": {"value": 608_120_00_00_000, "confidence": "high"},
"deposits": {"value": 1_500_000_00_00_000, "confidence": "high"},
"gross_npa_pct": 6.2, "net_npa_pct": 0.33,
"casa_ratio": 28.0, "capital_adequacy": 19.3,
},
},
"Infosys": {
"2023": {"revenue": {"value": 1_500_000_000_000, "confidence": "high"}},
"2024": {
"revenue": {"value": 1_300_000_000_000, "confidence": "high"},
"net_income": {"value": -50_000_000, "confidence": "medium"},
"attrition": 27.5,
},
},
}
def test_get_value_normalizes_both_shapes():
assert get_value({"value": 5.0, "confidence": "high"}) == (5.0, "high")
assert get_value(3.2) == (3.2, "medium")
assert get_value(None) == (None, None)
def test_bank_flags_trigger():
result = evaluate_red_flags(FakeGraph(FAKE_DATA), "HDFC Bank", "2024", sector="BANK")
flag_names = {f["flag"] for f in result["flags_triggered"]}
assert "HIGH_GROSS_NPA" in flag_names # 6.2 > 5
assert "LOW_CASA" in flag_names # 28 < 30
assert "DEPOSIT_DECLINE_YOY" in flag_names # 1.9e15 -> 1.5e15 is >10%
assert result["risk_score"] > 0
def test_it_flags_trigger():
result = evaluate_red_flags(FakeGraph(FAKE_DATA), "Infosys", "2024", sector="IT")
flag_names = {f["flag"] for f in result["flags_triggered"]}
assert "HIGH_ATTRITION" in flag_names # 27.5 > 25
assert "REVENUE_DECLINE_YOY" in flag_names # >5% decline
assert "NEGATIVE_NET_INCOME" in flag_names
def test_missing_filing_returns_error_not_crash():
result = evaluate_red_flags(FakeGraph(FAKE_DATA), "Nobody", "2024", sector="BANK")
assert result["risk_score"] is None
assert "error" in result
def test_risk_score_capped_at_100():
flags = [{"flag": "HIGH_GROSS_NPA"}] * 10
assert compute_risk_score(flags) == 100
def test_overall_confidence_is_weakest_link():
flags = [
{"flag": "A", "confidence": "high"},
{"flag": "B", "confidence": "low"},
]
assert overall_confidence(flags) == "low"
assert overall_confidence([]) == "high"
def test_severity_table_has_entries_for_core_flags():
for flag in ("HIGH_GROSS_NPA", "NEGATIVE_PAT", "HIGH_ATTRITION", "HIGH_DEBT_EQUITY"):
assert flag in FLAG_SEVERITY