telen / tests /test_bootstrap.py
haidang2405's picture
Polish TELEN source release and public API
baa1d92 verified
Raw History Blame Contribute Delete
5.53 kB
"""Bootstrap relationship and provision parsing tests."""
import pandas as pd
from telen.bootstrap import (
canonicalize_relationship,
canonicalize_relationship_frame,
contains_document_number,
extract_articles,
extract_event_mentions,
html_to_legal_text,
normalize_document_number,
)
from telen.domain import RelationType
def test_active_and_passive_labels_have_same_canonical_orientation() -> None:
active = canonicalize_relationship("new", "old", "Thay thế")
passive = canonicalize_relationship("old", "new", "Văn bản quy định hết hiệu lực")
assert active is not None
assert passive is not None
assert active.event_doc_id == passive.event_doc_id == "new"
assert active.affected_doc_id == passive.affected_doc_id == "old"
assert active.relation is RelationType.REPLACES
assert passive.relation is RelationType.TERMINATES_VERSION
def test_specific_termination_supersedes_generic_mirror() -> None:
raw = pd.DataFrame(
[
{"doc_id": "new", "other_doc_id": "old", "relationship": "Thay thế"},
{
"doc_id": "old",
"other_doc_id": "new",
"relationship": "Văn bản quy định hết hiệu lực",
},
]
)
canonical = canonicalize_relationship_frame(raw)
assert len(canonical) == 1
assert canonical.iloc[0]["event_doc_id"] == "new"
assert canonical.iloc[0]["affected_doc_id"] == "old"
assert canonical.iloc[0]["relation"] == "REPLACES"
assert canonical.iloc[0]["evidence_count"] == 2
assert "Văn bản quy định hết hiệu lực" in canonical.iloc[0]["raw_labels"]
def test_mirrored_amendment_evidence_collapses_but_retains_labels() -> None:
raw = pd.DataFrame(
[
{
"doc_id": "new",
"other_doc_id": "old",
"relationship": "Sửa đổi, bổ sung",
},
{
"doc_id": "old",
"other_doc_id": "new",
"relationship": "Văn bản sửa đổi",
},
]
)
canonical = canonicalize_relationship_frame(raw)
assert len(canonical) == 1
row = canonical.iloc[0]
assert row["relation"] == "AMENDS"
assert row["evidence_count"] == 2
assert "Sửa đổi, bổ sung" in row["raw_labels"]
assert "Văn bản sửa đổi" in row["raw_labels"]
def test_unknown_relation_is_not_silently_promoted_to_graph_fact() -> None:
assert canonicalize_relationship("a", "b", "Văn bản liên quan khác") is None
def test_html_parser_removes_scripts_and_preserves_article_lines() -> None:
html = """
<html><head><style>.bad {color:red}</style></head><body>
<p>Điều 1. Phạm vi điều chỉnh</p>
<p>Luật này quy định về thuế.</p>
<script>alert('bad')</script>
<p>Điều 2: Đối tượng áp dụng</p>
<p>Tổ chức và cá nhân.</p>
</body></html>
"""
text = html_to_legal_text(html)
articles = extract_articles(html)
assert "color:red" not in text
assert "alert" not in text
assert len(articles) == 2
assert articles[0].article_number == "1"
assert articles[0].heading == "Phạm vi điều chỉnh"
assert "Luật này quy định về thuế" in articles[0].text
assert articles[1].article_number == "2"
def test_document_number_matching_is_separator_tolerant_but_not_fuzzy() -> None:
assert normalize_document_number(" 03 / 2024 / TT-BKHCN ") == "03/2024/ttbkhcn".replace("/", "")
assert contains_document_number(
"Thông tư số 03 / 2024 / TT-BKHCN ngày 15 tháng 4",
"03/2024/TT-BKHCN",
)
assert not contains_document_number(
"Thông tư số 13/2024/TT-BKHCN", "03/2024/TT-BKHCN"
)
def test_extract_event_mentions_links_amending_clause_to_target_articles() -> None:
html = """
<p>THÔNG TƯ</p>
<p>Sửa đổi một số điều của Thông tư số 03/2024/TT-BKHCN</p>
<p>Điều 1. Sửa đổi, bổ sung khoản 1 Điều 4 như sau:</p>
<p>“Điều 4. Nội dung mới”</p>
<p>Điều 2. Bãi bỏ Điều 7 và Điều 8.</p>
<p>Điều 3. Hiệu lực thi hành</p>
"""
mentions = extract_event_mentions(html, "03/2024/TT-BKHCN")
assert len(mentions) == 2
assert mentions[0].source_article_number == "1"
assert mentions[0].target_article_numbers == ("4",)
assert mentions[0].target_document_explicit is False
assert mentions[1].action == "bãi bỏ"
assert mentions[1].target_article_numbers == ("7", "8")
def test_extract_event_mentions_requires_explicit_target_document() -> None:
html = """
<p>Điều 1. Sửa đổi Điều 4 như sau:</p>
<p>“Điều 4. Nội dung mới”</p>
"""
assert extract_event_mentions(html, "03/2024/TT-BKHCN") == ()
def test_preamble_fallback_is_disabled_for_ambiguous_multiple_targets() -> None:
html = """
<p>Số: 80/2026/NĐ-CP</p>
<p>Sửa đổi Nghị định số 142/2017/NĐ-CP và Nghị định số 139/2021/NĐ-CP</p>
<p>Căn cứ Luật số 01/2020/QH14</p>
<p>Điều 1. Sửa đổi Điều 4 như sau:</p>
<p>Điều 2. Sửa đổi Điều 8 của Nghị định số 139/2021/NĐ-CP.</p>
"""
mentions = extract_event_mentions(html, "139/2021/NĐ-CP")
assert len(mentions) == 1
assert mentions[0].source_article_number == "2"
assert mentions[0].target_document_explicit is True