""" Unit tests for activist ownership cover-page parsing (HTML + XML). """ import pytest from app.services.activist_ownership_service import _parse_cover_html, _parse_cover_xml # Minimal 13D HTML cover page (simplified) SAMPLE_13D_HTML = """
Item 11. Aggregate Amount Beneficially Owned by Each Reporting Person12,500,000
Item 13. Percent of Class Represented by Amount in Row (11)7.2%
""" SAMPLE_13G_HTML = """

Percent of Class Represented by Amount in Row (11): 5.4 %

Aggregate Amount Beneficially Owned: 8,000,000

""" SAMPLE_COVER_XML = """ 15000000 9.1 """ SAMPLE_COVER_XML_NAMESPACED = """ 3000000 3.5 """ class TestParseCoverHtml: def test_extract_ownership_pct(self): pct, shares = _parse_cover_html(SAMPLE_13D_HTML) assert pct == pytest.approx(7.2) def test_extract_shares_owned(self): pct, shares = _parse_cover_html(SAMPLE_13D_HTML) assert shares == pytest.approx(12_500_000) def test_13g_format(self): pct, shares = _parse_cover_html(SAMPLE_13G_HTML) assert pct == pytest.approx(5.4) assert shares == pytest.approx(8_000_000) def test_empty_html(self): pct, shares = _parse_cover_html("") assert pct is None assert shares is None def test_no_pct_in_html(self): pct, shares = _parse_cover_html("

Aggregate Amount Beneficially Owned: 1,000,000

") assert pct is None assert shares == pytest.approx(1_000_000) class TestParseCoverXml: def test_structured_xml(self): pct, shares = _parse_cover_xml(SAMPLE_COVER_XML) assert pct == pytest.approx(9.1) assert shares == pytest.approx(15_000_000) def test_namespaced_xml(self): # Namespace-prefixed elements should be found via {*} wildcard search pct, shares = _parse_cover_xml(SAMPLE_COVER_XML_NAMESPACED) # Either finds or gracefully returns None — no crash assert pct is None or isinstance(pct, float) assert shares is None or isinstance(shares, float) def test_invalid_xml(self): pct, shares = _parse_cover_xml(">>") assert pct is None assert shares is None def test_empty_xml(self): pct, shares = _parse_cover_xml("") assert pct is None assert shares is None