sdlc-hub/tests/test_projects.py
Andrey Epifancev 6d7aebe01c refactor: пакеты core и modules.jira — перенос без логики (#87)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 21:50:23 +04:00

150 lines
6.7 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.core import projects, settings
from jira_hub.modules.jira import mirror
@pytest.fixture
def conn(open_db):
c = open_db()
settings.ensure_defaults(c)
return c
def test_boards_type_unknown_if_any_project_unknown(conn): # I-1: новый проект на известной доске
projects.create(conn, "AWPCA", "a", 4216)
projects.record_board_types(conn, {"4216": "scrum"})
projects.create(conn, "NEW", "n", 4216)
assert projects.get(conn, "NEW")["board_type"] is None
assert projects.boards(conn) == [{"id": 4216, "type": None}]
projects.record_board_types(conn, {"4216": "scrum"})
assert projects.boards(conn) == [{"id": 4216, "type": "scrum"}]
assert [p["board_type"] for p in projects.list_projects(conn)] == ["scrum", "scrum"]
def test_boards_diverged_types_first_by_order(conn):
projects.create(conn, "A", "a", 7); projects.create(conn, "B", "b", 7)
conn.execute("UPDATE project SET board_type = 'kanban' WHERE label = 'B'")
conn.execute("UPDATE project SET board_type = 'scrum' WHERE label = 'A'")
assert projects.boards(conn) == [{"id": 7, "type": "scrum"}]
def test_light_list_same_order_no_count(conn):
projects.create(conn, "B", "b", 1); projects.create(conn, "A", "a")
got = projects.light_list(conn)
assert [p["label"] for p in got] == [p["label"] for p in projects.list_projects(conn)]
assert all("issues_count" not in p and set(p) == {"label", "board_id", "board_type"} for p in got)
@pytest.mark.parametrize("label", ["", "STOCKS DRRK", "A\tB", "A\nB", "A\\B", "A\x00B", "A\x07B", "A\x7fB", "A,B", 'A"B', "A'B", "A(B", "A)B", "X" * 101, 5, None])
def test_bad_label(conn, label):
with pytest.raises(projects.ProjectError) as e:
projects.create(conn, label, "Название")
assert e.value.field == "label"
assert projects.list_projects(conn) == []
@pytest.mark.parametrize("name", ["", " ", "Я" * 101, None, 7])
def test_bad_name(conn, name):
with pytest.raises(projects.ProjectError) as e:
projects.create(conn, "AWPCA", name)
assert e.value.field == "name"
assert projects.list_projects(conn) == []
@pytest.mark.parametrize("board", [0, -1, True, "5120", 1.5])
def test_bad_board(conn, board):
with pytest.raises(projects.ProjectError) as e:
projects.create(conn, "AWPCA", "АРМ КА", board)
assert e.value.field == "board_id"
assert projects.list_projects(conn) == []
def test_create_and_list(conn):
a = projects.create(conn, "AWPCA", " АРМ КА ", 4216)
assert a == {"label": "AWPCA", "name": "АРМ КА", "board_id": 4216, "board_type": None, "created_at": a["created_at"]}
projects.create(conn, "STOCKS_DRRK", "Запасы ДРРК")
mirror.apply_state(conn, [{"key": "A-1", "labels": ["AWPCA"]}, {"key": "A-2", "labels": ["awpca", "x"]}], [])
got = projects.list_projects(conn)
assert [(p["label"], p["board_id"], p["issues_count"]) for p in got] == [("AWPCA", 4216, 1), ("STOCKS_DRRK", None, 0)]
def test_order_created_then_label(conn):
projects.create(conn, "ZZZ", "z"); projects.create(conn, "AAA", "a"); projects.create(conn, "MMM", "m")
conn.execute("UPDATE project SET created_at = '2026-01-01T00:00:00+00:00' WHERE label IN ('AAA', 'MMM')")
conn.execute("UPDATE project SET created_at = '2026-01-02T00:00:00+00:00' WHERE label = 'ZZZ'")
assert projects.labels(conn) == ["AAA", "MMM", "ZZZ"]
def test_same_label_other_case(conn):
projects.create(conn, "AWPCA", "АРМ КА")
with pytest.raises(projects.ProjectExists) as e:
projects.create(conn, "awpca", "…")
assert "уже есть" in str(e.value) and len(projects.list_projects(conn)) == 1
def test_base_jql(conn):
assert projects.base_jql(conn) is None
projects.create(conn, "AWPCA", "АРМ КА"); projects.create(conn, "STOCKS_DRRK", "Запасы ДРРК")
assert projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA", "STOCKS_DRRK")'
settings.set_(conn, "project_key", "AUR")
assert projects.base_jql(conn).startswith("project = AUR AND")
def test_base_jql_single_and_reserved_words(conn):
projects.create(conn, "AWPCA", "АРМ КА")
assert projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA")'
projects.create(conn, "EMPTY", "Пустой") # зарезервированное слово JQL — в кавычках
assert projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA", "EMPTY")'
def test_boards_dedup_and_types(conn):
projects.create(conn, "AWPCA", "a", 4216); projects.create(conn, "B", "b", 5120)
projects.create(conn, "C", "c", 4216); projects.create(conn, "D", "d")
projects.record_board_types(conn, {"4216": "scrum"})
assert projects.boards(conn) == [{"id": 4216, "type": "scrum"}, {"id": 5120, "type": None}]
assert projects.get(conn, "C")["board_type"] == "scrum" # тип — у всех проектов с этой доской
@pytest.mark.parametrize("boards", [{"5120": None}, {"5120": "simple"}, {"x": "kanban"}, ["5120"], None, {}])
def test_record_board_types_ignores(conn, boards):
projects.create(conn, "B", "b", 5120)
assert projects.record_board_types(conn, boards) == 0
assert projects.get(conn, "B")["board_type"] is None
@pytest.mark.parametrize("jql, labels", [
("project = AURORA AND labels = AWPCA", ["AWPCA"]),
("project = AURORA AND labels in (AWPCA, STOCKS_DRRK)", ["AWPCA", "STOCKS_DRRK"]),
("project = AURORA AND labels IN (A,B)", ["A", "B"]),
('project = AURORA AND labels = "AWPCA"', ["AWPCA"]),
("project = AURORA AND labels in (AWPCA, awpca)", ["AWPCA"]),
("project = AURORA", None),
("project = AURORA AND labels = AWPCA ORDER BY key", None),
("project = AURORA AND labels in (A B)", None),
("", None), (None, None), (5, None),
])
def test_parse_legacy_labels(jql, labels):
assert projects.parse_legacy_labels(jql) == labels
def test_add_project_fixture(conn, add_project):
p = add_project(conn)
assert (p["name"], p["board_id"], p["board_type"]) == ("АРМ КА", 4216, "scrum")
def test_ensure_legacy(conn):
assert projects.ensure_legacy(conn, 4216) is True
assert projects.get(conn, "AWPCA")["board_id"] == 4216 and projects.get(conn, "AWPCA")["name"] == "АРМ КА"
assert projects.ensure_legacy(conn, 1) is False
def test_ensure_legacy_skips_case_variant_and_bad_board(open_db):
c = open_db()
settings.ensure_defaults(c)
projects.create(c, "awpca", "x")
assert projects.ensure_legacy(c, 4216) is False
c2 = open_db()
settings.ensure_defaults(c2)
assert projects.ensure_legacy(c2, "oops") is True and projects.get(c2, "AWPCA")["board_id"] is None