Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Typ5sXWNMFirr2va2uL8o
72 lines
4.0 KiB
Python
72 lines
4.0 KiB
Python
import pytest
|
||
|
||
from jira_hub import db, mirror
|
||
|
||
|
||
def issue(key, **over):
|
||
base = {"key": key, "id": "1", "issue_type": "Задача", "summary": f"Тема {key}", "description": "h3. Контекст",
|
||
"status": "Ожидание разработки", "priority": "Средний", "assignee": None, "reporter": "me",
|
||
"duedate": "2026-10-23", "planned_start": None, "planned_end": "2026-10-23", "epic_key": "AURORA-1350",
|
||
"labels": ["AWPCA"], "sprint": "Спринт 2", "created": "2026-10-10T12:00:00.000+0300",
|
||
"jira_updated": "2026-10-11T12:00:00.000+0300"}
|
||
base.update(over)
|
||
return base
|
||
|
||
|
||
def test_apply_state_upserts_and_replaces_links():
|
||
conn = db.connect(":memory:")
|
||
links = [{"source_key": "A-1", "target_key": "A-2", "link_type": "ASUPR_Блокер_Начала"}]
|
||
out = mirror.apply_state(conn, [issue("A-1"), issue("A-2")], links)
|
||
assert out == {"issues": 2, "links": 1}
|
||
mirror.apply_state(conn, [issue("A-1", summary="Новая тема")],
|
||
[{"source_key": "A-1", "target_key": "A-2", "link_type": "ASUPR_Связанные"}])
|
||
got = mirror.get_issue(conn, "A-1")
|
||
assert got["summary"] == "Новая тема" and got["labels"] == ["AWPCA"]
|
||
assert got["links_out"] == [{"target_key": "A-2", "link_type": "ASUPR_Связанные"}]
|
||
assert mirror.get_issue(conn, "A-2")["links_in"] == [{"source_key": "A-1", "link_type": "ASUPR_Связанные"}]
|
||
|
||
|
||
def test_links_from_other_source_survive():
|
||
conn = db.connect(":memory:")
|
||
mirror.apply_state(conn, [issue("A-1"), issue("A-2")],
|
||
[{"source_key": "A-2", "target_key": "A-1", "link_type": "ASUPR_Связанные"}])
|
||
mirror.apply_state(conn, [issue("A-1")], []) # пришла только A-1 без связей
|
||
assert mirror.get_issue(conn, "A-1")["links_in"] == [{"source_key": "A-2", "link_type": "ASUPR_Связанные"}]
|
||
|
||
|
||
def test_apply_state_marks_neighbors():
|
||
conn = db.connect(":memory:")
|
||
mirror.apply_state(conn, [issue("A-1"), issue("B-9")], [], neighbor_keys={"B-9"})
|
||
assert mirror.get_issue(conn, "B-9")["neighbor"] is True
|
||
assert mirror.get_issue(conn, "A-1")["neighbor"] is False
|
||
mirror.apply_state(conn, [issue("B-9")], []) # вошла в базовую JQL
|
||
assert mirror.get_issue(conn, "B-9")["neighbor"] is False
|
||
assert mirror.known_keys(conn) == ["A-1", "B-9"]
|
||
|
||
|
||
def test_note_survives_refresh_and_renames():
|
||
conn = db.connect(":memory:")
|
||
mirror.set_note(conn, "new:7", {"fact_status": "В работе", "work_kind": "разработка"}, "import")
|
||
mirror.rename_note(conn, "new:7", "A-5")
|
||
mirror.apply_state(conn, [issue("A-5")], [])
|
||
got = mirror.get_issue(conn, "A-5")
|
||
assert got["note"]["fact_status"] == "В работе" and got["note"]["updated_by"] == "import"
|
||
assert mirror.get_note(conn, "new:7") is None
|
||
with pytest.raises(ValueError):
|
||
mirror.set_note(conn, "A-5", {"summary": "нельзя"}, "x")
|
||
|
||
|
||
def test_list_issues_filters():
|
||
conn = db.connect(":memory:")
|
||
mirror.apply_state(conn, [issue("A-1", sprint="Спринт 2", assignee="ivanov", duedate="2026-10-20"),
|
||
issue("A-2", sprint="Спринт 1", labels=["AWPCA", "fact-done"]),
|
||
issue("A-3", sprint="Спринт 2", duedate=None)], [])
|
||
mirror.set_note(conn, "A-3", {"work_kind": "тестирование"}, "x")
|
||
keys = [i["key"] for i in mirror.list_issues(conn, {"sprint": "Спринт 2"})]
|
||
assert keys == ["A-1", "A-3"] # без срока — последней
|
||
assert [i["key"] for i in mirror.list_issues(conn, {"label": "fact-done"})] == ["A-2"]
|
||
assert [i["key"] for i in mirror.list_issues(conn, {"work_kind": "тестирование"})] == ["A-3"]
|
||
assert [i["key"] for i in mirror.list_issues(conn, {"q": "A-2"})] == ["A-2"]
|
||
assert mirror.list_issues(conn, {"assignee": "ivanov"})[0]["work_kind"] is None
|
||
assert len(mirror.list_issues(conn, None, limit=1)) == 1
|