113 lines
4.6 KiB
Python
113 lines
4.6 KiB
Python
"""Unit tests for the deterministic regex prescreen extractor."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import pytest
|
||
|
||
from contract_check.worker_prescreen.extractor import extract_contract_meta
|
||
|
||
SIMPLE_SUPPLY = """\
|
||
|
||
ДОГОВОР ПОСТАВКИ № 42
|
||
|
||
г. Москва
|
||
|
||
Общество с ограниченной ответственностью «Продавец»,
|
||
именуемое в дальнейшем «Поставщик», в лице директора Иванова И.И.,
|
||
с одной стороны, и
|
||
Общество с ограниченной ответственностью «Покупатель»,
|
||
именуемое в дальнейшем «Покупатель», с другой стороны,
|
||
заключили настоящий договор о нижеследующем.
|
||
|
||
1. Предмет договора
|
||
Поставщик обязуется передать в собственность Покупателю товар.
|
||
|
||
2. Цена и порядок расчётов
|
||
2.1. Общая стоимость товара составляет 1 250 000 (один миллион двести пятьдесят тысяч) рублей.
|
||
|
||
3. Срок действия договора
|
||
3.1. Настоящий договор вступает в силу с 01.09.2025 и действует по 31.08.2026.
|
||
|
||
4. Ответственность сторон
|
||
4.1. За просрочку поставки Поставщик уплачивает неустойку в размере 0,1% от стоимости.
|
||
|
||
5. Порядок разрешения споров
|
||
5.1. Споры подлежат рассмотрению в Арбитражном суде г. Москвы.
|
||
"""
|
||
|
||
|
||
MINIMAL = """\
|
||
Договор оказания услуг между ИП Петров Петр Петрович и ООО «Клиент».
|
||
Стоимость услуг составляет 50 000 рублей.
|
||
"""
|
||
|
||
|
||
def test_supply_extraction() -> None:
|
||
meta = extract_contract_meta(SIMPLE_SUPPLY)
|
||
|
||
assert meta.contract_type == "supply"
|
||
assert "Продавец" in (meta.party_a or "")
|
||
assert "Покупатель" in (meta.party_b or "")
|
||
assert meta.total_amount == 1250000.0
|
||
assert meta.currency == "RUB"
|
||
assert meta.start_date == "2025-09-01"
|
||
assert meta.end_date == "2026-08-31"
|
||
assert meta.has_penalty_clause is True
|
||
assert meta.has_termination_clause is False
|
||
assert meta.has_arbitration is True
|
||
assert meta.confidence_score > 0.6
|
||
|
||
|
||
def test_minimal_extraction() -> None:
|
||
meta = extract_contract_meta(MINIMAL)
|
||
|
||
assert meta.contract_type == "services"
|
||
assert "ИП Петров" in (meta.party_a or "")
|
||
assert "ООО «Клиент»" in (meta.party_b or "")
|
||
assert meta.total_amount == 50000.0
|
||
assert meta.currency == "RUB"
|
||
|
||
|
||
def test_confidence_score_bounds() -> None:
|
||
meta = extract_contract_meta("")
|
||
assert meta.confidence_score == 0.0
|
||
assert 0.0 <= meta.confidence_score <= 1.0
|
||
|
||
|
||
def test_party_extraction_handles_whitespace() -> None:
|
||
text = "Договор между ООО «Альфа» и ООО «Бета»"
|
||
meta = extract_contract_meta(text)
|
||
assert "Альфа" in (meta.party_a or "")
|
||
assert "Бета" in (meta.party_b or "")
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
("clause", "expected"),
|
||
[
|
||
("Стороны вправе расторгнуть договор в одностороннем порядке", "has_termination_clause"),
|
||
("В случае нарушения Покупатель уплачивает штраф", "has_penalty_clause"),
|
||
("Споры рассматриваются в Арбитражном суде", "has_arbitration"),
|
||
],
|
||
)
|
||
def test_boolean_flags(clause: str, expected: str) -> None:
|
||
meta = extract_contract_meta(f"Договор поставки. {clause}.")
|
||
assert getattr(meta, expected) is True
|
||
|
||
|
||
def test_shim_defaults_to_heuristic_v2() -> None:
|
||
meta = extract_contract_meta(SIMPLE_SUPPLY)
|
||
assert meta.confidence_score > 0.6
|
||
|
||
|
||
def test_keep_regex_flag_routes_to_regex_v1(monkeypatch: pytest.MonkeyPatch) -> None:
|
||
"""PRESCREEN_KEEP_REGEX=true keeps the legacy regex path alive (plan §5)."""
|
||
from contract_check.worker_prescreen.extractor import _extract_contract_meta_regex
|
||
|
||
monkeypatch.setenv("PRESCREEN_KEEP_REGEX", "true")
|
||
meta = extract_contract_meta(SIMPLE_SUPPLY)
|
||
legacy = _extract_contract_meta_regex(SIMPLE_SUPPLY.replace("\n", " "))
|
||
# Identical extraction semantics on the ported fixtures.
|
||
assert meta.model_dump() == legacy.model_dump()
|
||
|
||
monkeypatch.setenv("PRESCREEN_KEEP_REGEX", "false")
|
||
assert extract_contract_meta(SIMPLE_SUPPLY).model_dump() == meta.model_dump()
|