You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
stock-oracle/tests/test_activist_ownership_par...

89 lines
2.7 KiB
Python

"""
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 = """
<html><body>
<table>
<tr><td>Item 11. Aggregate Amount Beneficially Owned by Each Reporting Person</td><td>12,500,000</td></tr>
<tr><td>Item 13. Percent of Class Represented by Amount in Row (11)</td><td>7.2%</td></tr>
</table>
</body></html>
"""
SAMPLE_13G_HTML = """
<html><body>
<p>Percent of Class Represented by Amount in Row (11): 5.4 %</p>
<p>Aggregate Amount Beneficially Owned: 8,000,000</p>
</body></html>
"""
SAMPLE_COVER_XML = """<?xml version="1.0" encoding="UTF-8"?>
<coverPage>
<aggregateAmount>15000000</aggregateAmount>
<percentClass>9.1</percentClass>
</coverPage>
"""
SAMPLE_COVER_XML_NAMESPACED = """<?xml version="1.0" encoding="UTF-8"?>
<sc13d xmlns:sc="http://www.sec.gov/sc13d">
<sc:aggregateAmount>3000000</sc:aggregateAmount>
<sc:percentClass>3.5</sc:percentClass>
</sc13d>
"""
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("<p>Aggregate Amount Beneficially Owned: 1,000,000</p>")
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("<not valid 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