sdlc-hub/tests/test_mirror.py

104 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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_partial_load_never_lowers_neighbor():
conn = db.connect(":memory:")
mirror.apply_state(conn, [issue("B-9")], [], neighbor_keys={"B-9"})
mirror.apply_state(conn, [issue("B-9", summary="новая")], [], authoritative=False) # refresh {keys}
assert mirror.get_issue(conn, "B-9")["neighbor"] is True
mirror.apply_state(conn, [issue("B-9")], [], authoritative=True) # полный прогон: вошла в базовую
assert mirror.get_issue(conn, "B-9")["neighbor"] is False
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
def test_rename_note_same_key_keeps_note():
conn = db.connect(":memory:")
mirror.apply_state(conn, [issue("A-1")], [])
mirror.set_note(conn, "A-1", {"fact_status": "В работе"}, "x")
mirror.rename_note(conn, "A-1", "A-1")
assert mirror.get_note(conn, "A-1")["fact_status"] == "В работе"
def test_rename_note_missing_is_noop():
conn = db.connect(":memory:")
mirror.rename_note(conn, "new:404", "A-9") # заметки нет — не падает
assert mirror.get_note(conn, "new:404") is None
assert mirror.get_note(conn, "A-9") is None
def test_set_note_partial_keeps_other_fields():
conn = db.connect(":memory:")
mirror.set_note(conn, "A-1", {"work_kind": "разработка", "done_text": "сделано"}, "x")
got = mirror.set_note(conn, "A-1", {"fact_status": "Готово"}, "y")
assert got["work_kind"] == "разработка" and got["done_text"] == "сделано"
assert got["fact_status"] == "Готово" and got["updated_by"] == "y"