From f8d61a20759f3833484674173ccb9264d474b6c2 Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Sun, 14 Jun 2026 02:36:26 -0700 Subject: test: add filings backend tests --- backend/tests/test_api.py | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'backend') diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index 230182e..d898ee2 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -22,6 +22,8 @@ def clear_service_caches() -> None: data_service.HIST_RATIOS_CACHE.clear() data_service.RATIOS_ENDPOINT_CACHE.clear() data_service.SECTOR_BENCHMARK_CACHE.clear() + data_service.INSIDERS_CACHE.clear() + data_service.FILINGS_CACHE.clear() def quarterly_frame(rows: dict[str, list[float]]) -> pd.DataFrame: @@ -1310,3 +1312,117 @@ def test_ticker_ratios_route(monkeypatch) -> None: assert result["pe_ttm"]["value"] == pytest.approx(24.3) assert result["gross_margin"]["spark"] == [] assert result["dividend_yield"]["vs_sector"] is None + + +# ── Filings ─────────────────────────────────────────────────────────────────── + +_MOCK_YF_FILINGS = [ + { + "date": "2024-10-31", + "type": "10-K", + "title": "Annual report", + "edgarUrl": "https://www.sec.gov/Archives/10k.htm", + "exhibits": {"10-K": "https://www.sec.gov/Archives/10k.htm"}, + }, + { + "date": "2024-07-31", + "type": "10-Q", + "title": "Quarterly report", + "edgarUrl": "https://www.sec.gov/Archives/10q.htm", + "exhibits": {}, + }, + { + "date": "2024-06-15", + "type": "8-K", + "title": "Material event disclosure", + "edgarUrl": "https://www.sec.gov/Archives/8k.htm", + "exhibits": {}, + }, + { + "date": "2024-05-01", + "type": "10-Q", + "title": "Quarterly report", + "edgarUrl": "https://www.sec.gov/Archives/10q2.htm", + "exhibits": {}, + }, +] + + +class _MockTicker: + def __init__(self, sym): + self.sec_filings = _MOCK_YF_FILINGS + + +def test_get_sec_filings_kpis(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + kpis = result["kpis"] + assert kpis["total"] == 4 + assert kpis["count_10k"] == 1 + assert kpis["count_10q"] == 2 + assert kpis["count_8k"] == 1 + assert kpis["distinct_forms"] == 3 + + +def test_get_sec_filings_sorted_descending(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + dates = [f["date"] for f in result["filings"]] + assert dates == sorted(dates, reverse=True) + + +def test_get_sec_filings_url_from_exhibit(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + # 10-K filing should use exhibit URL + ten_k = next(f for f in result["filings"] if f["form"] == "10-K") + assert ten_k["url"] == "https://www.sec.gov/Archives/10k.htm" + + +def test_get_sec_filings_cadence(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + months = [c["month"] for c in result["cadence"]] + assert "2024-10" in months + assert "2024-07" in months + + +def test_get_sec_filings_form_mix(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + top_form = result["form_mix"][0]["form"] + assert top_form == "10-Q" # 2 count vs 1 each for 10-K and 8-K + + +def test_get_sec_filings_readout(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = data_service.get_sec_filings("AAPL") + assert "10-Q" in result["readout"] + assert "2024-10-31" in result["readout"] + + +def test_get_sec_filings_empty(monkeypatch): + data_service.FILINGS_CACHE.clear() + + class _EmptyTicker: + def __init__(self, sym): + self.sec_filings = [] + + monkeypatch.setattr(data_service.yf, "Ticker", _EmptyTicker) + result = data_service.get_sec_filings("AAPL") + assert result["kpis"]["total"] == 0 + assert result["filings"] == [] + assert "No SEC filings found" in result["readout"] + + +def test_ticker_filings_route(monkeypatch): + data_service.FILINGS_CACHE.clear() + monkeypatch.setattr(data_service.yf, "Ticker", _MockTicker) + result = main.ticker_filings("AAPL") + assert result["kpis"]["total"] == 4 -- cgit v1.3-2-g0d8e