File size: 3,069 Bytes
d4f8959
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from backend.recommendations import evaluate_recommendation, recommend_from_red_flags


class FakeGraph:
    def __init__(self, data):
        self._data = data

    def get_company_metrics(self, company):
        return self._data.get(company, {})


FAKE_DATA = {
    # clean bank, zero flags -> BUY
    "ICICI Bank": {
        "2023": {"deposits": {"value": 1_000_000_00_00_000, "confidence": "high"}},
        "2024": {
            "profit_after_tax": {"value": 400_000_00_00_000, "confidence": "high"},
            "deposits": {"value": 1_050_000_00_00_000, "confidence": "high"},
            "gross_npa_pct": 1.1, "net_npa_pct": 0.3,
            "casa_ratio": 42.0, "capital_adequacy": 17.0,
        },
    },
    # one severe flag only (negative net income) -> AVOID even though
    # aggregate score is under the AVOID threshold
    "Infosys": {
        "2023": {"revenue": {"value": 1_500_000_000_000, "confidence": "high"}},
        "2024": {
            "revenue": {"value": 1_490_000_000_000, "confidence": "high"},
            "net_income": {"value": -50_000_000, "confidence": "high"},
            "attrition": 18.0,
        },
    },
    # only low-severity CASA flag -> HOLD
    "AxisBank": {
        "2023": {"deposits": {"value": 900_000_00_00_000, "confidence": "high"}},
        "2024": {
            "profit_after_tax": {"value": 200_000_00_00_000, "confidence": "high"},
            "deposits": {"value": 920_000_00_00_000, "confidence": "high"},
            "gross_npa_pct": 2.0, "net_npa_pct": 0.8,
            "casa_ratio": 25.0, "capital_adequacy": 16.0,
        },
    },
    "SunPharma": {
        "2024": {
            "revenue": {"value": 500_000_000_000, "confidence": "high"},
            "r_and_d": {"value": 30_000_000_000, "confidence": "high"},
            "net_income": {"value": 60_000_000_000, "confidence": "high"},
        },
    },
}


def _rec(company, year, sector):
    return evaluate_recommendation(FakeGraph(FAKE_DATA), company, year, sector=sector)


def test_clean_company_is_buy():
    assert _rec("ICICI Bank", "2024", "BANK")["recommendation"] == "BUY"


def test_single_severe_flag_forces_avoid():
    result = _rec("Infosys", "2024", "IT")
    assert result["recommendation"] == "AVOID"
    assert "high-severity" in result["reason"]


def test_minor_flags_only_is_hold():
    assert _rec("AxisBank", "2024", "BANK")["recommendation"] == "HOLD"


def test_unsupported_sector_is_skip():
    result = _rec("SunPharma", "2024", "PHARMA")
    assert result["recommendation"] == "SKIP"


def test_missing_company_is_skip_with_reason():
    result = _rec("NoSuchCompany", "2024", "BANK")
    assert result["recommendation"] == "SKIP"
    assert result["reason"]


def test_low_confidence_forces_skip():
    payload = {
        "company": "X", "year": "2024", "sector": "BANK",
        "flags_triggered": [
            {"flag": "LOW_CASA", "message": "m", "confidence": "low"}
        ],
        "risk_score": 10,
        "confidence": "low",
    }
    assert recommend_from_red_flags(payload)["recommendation"] == "SKIP"