File size: 5,288 Bytes
cc2ed2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""ВСсты Π½Π° BusinessVocabulary (Ρ€Π°Π·Π΄Π΅Π» 3.6 ΠΏΠΎΡΡΠ½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ записки)."""

from pathlib import Path

import pytest

from src.business.vocabulary import BusinessVocabulary


# ──────────────────────────────────────────────────────────────────────
# Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ°
# ──────────────────────────────────────────────────────────────────────

def test_empty_vocabulary_is_falsy():
    vocab = BusinessVocabulary.empty()
    assert not vocab
    assert vocab.render_system_context() == ""


def test_from_dict_basic():
    vocab = BusinessVocabulary.from_dict(
        {
            "company": "ООО ВСст",
            "terms": {"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount)"},
            "filters": {"paid": "status='paid'"},
            "notes": ["ΠŸΠ΅Ρ€ΠΈΠΎΠ΄: 2025-01-01β€”2026-04-30"],
        }
    )
    assert bool(vocab)
    assert vocab.company == "ООО ВСст"
    assert vocab.terms == {"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount)"}
    assert vocab.filters == {"paid": "status='paid'"}
    assert vocab.notes == ["ΠŸΠ΅Ρ€ΠΈΠΎΠ΄: 2025-01-01β€”2026-04-30"]


def test_from_yaml_roundtrip(tmp_path: Path):
    original = BusinessVocabulary(
        company="ООО Ромашка",
        terms={"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(orders.amount)"},
        filters={"paid_only": "orders.status='paid'"},
        notes=["amount Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² orders"],
    )
    path = tmp_path / "vocab.yaml"
    original.save_yaml(path)

    loaded = BusinessVocabulary.from_yaml(path)
    assert loaded.company == original.company
    assert loaded.terms == original.terms
    assert loaded.filters == original.filters
    assert loaded.notes == original.notes


def test_from_yaml_missing_file(tmp_path: Path):
    with pytest.raises(FileNotFoundError):
        BusinessVocabulary.from_yaml(tmp_path / "does_not_exist.yaml")


# ──────────────────────────────────────────────────────────────────────
# enrich_prompt β€” обратная ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒ со старым Streamlit-ΠΊΠΎΠ΄ΠΎΠΌ
# ──────────────────────────────────────────────────────────────────────

def test_enrich_prompt_pass_through_when_empty():
    vocab = BusinessVocabulary.empty()
    assert vocab.enrich_prompt("Какая Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°?") == "Какая Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°?"


def test_enrich_prompt_adds_term_definition():
    vocab = BusinessVocabulary(
        terms={"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount) WHERE status='paid'"},
    )
    enriched = vocab.enrich_prompt("Какая Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ° Π·Π° ΡΠ½Π²Π°Ρ€ΡŒ?")
    assert "Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°" in enriched
    assert "SUM(amount)" in enriched
    assert "Какая Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ° Π·Π° ΡΠ½Π²Π°Ρ€ΡŒ?" in enriched


def test_enrich_prompt_case_insensitive_match():
    vocab = BusinessVocabulary(terms={"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount)"})
    enriched = vocab.enrich_prompt("Π’Π«Π Π£Π§ΠšΠ Π² этом мСсяцС?")
    assert "SUM(amount)" in enriched


def test_enrich_prompt_ignores_unrelated_terms():
    vocab = BusinessVocabulary(
        terms={
            "Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount)",
            "Ρ‚ΠΎΠΏ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠ²": "ORDER BY SUM(amount) DESC",
        },
    )
    enriched = vocab.enrich_prompt("Какая Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°?")
    # Π Π΅Π»Π΅Π²Π°Π½Ρ‚Π½Ρ‹ΠΉ Ρ‚Π΅Ρ€ΠΌΠΈΠ½ подмСшан, посторонний β€” Π½Π΅Ρ‚
    assert "SUM(amount)" in enriched
    assert "ORDER BY SUM(amount) DESC" not in enriched


# ──────────────────────────────────────────────────────────────────────
# render_system_context β€” Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄ΠΌΠ΅ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π² system-сообщСниС
# ──────────────────────────────────────────────────────────────────────

def test_render_system_context_empty():
    assert BusinessVocabulary.empty().render_system_context() == ""


def test_render_system_context_with_company():
    vocab = BusinessVocabulary(
        company="ООО Ромашка",
        terms={"Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°": "SUM(amount)"},
    )
    ctx = vocab.render_system_context()
    assert "ООО Ромашка" in ctx
    assert "Π²Ρ‹Ρ€ΡƒΡ‡ΠΊΠ°" in ctx
    assert "SUM(amount)" in ctx


def test_render_system_context_with_filters_and_notes():
    vocab = BusinessVocabulary(
        filters={"Ρ‚ΠΎΠ»ΡŒΠΊΠΎ_ΠΎΠΏΠ»Π°Ρ‡Π΅Π½Π½Ρ‹Π΅": "orders.status='paid'"},
        notes=["amount Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² orders"],
    )
    ctx = vocab.render_system_context()
    assert "Ρ‚ΠΎΠ»ΡŒΠΊΠΎ_ΠΎΠΏΠ»Π°Ρ‡Π΅Π½Π½Ρ‹Π΅" in ctx
    assert "orders.status='paid'" in ctx
    assert "amount Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² orders" in ctx