sdlc-hub/tests/test_projects.py
Andrey Epifancev a88bb1e6e8 refactor(sdlc-rename): пакет sdlc_hub, CLI sdlc-hub, каталог данных sdlc-hub
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 11:27:17 +04:00

151 lines
6.9 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 sdlc_hub.core import api, projects, settings
from sdlc_hub.modules.jira import mirror
from sdlc_hub.modules.jira import projects as jira_projects
@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: новый проект на известной доске
jira_projects.create(conn, "AWPCA", "a", 4216)
jira_projects.record_board_types(conn, {"4216": "scrum"})
jira_projects.create(conn, "NEW", "n", 4216)
assert api.project_rows(conn, ["NEW"])[0]["board_type"] is None
assert jira_projects.boards(conn) == [{"id": 4216, "type": None}]
jira_projects.record_board_types(conn, {"4216": "scrum"})
assert jira_projects.boards(conn) == [{"id": 4216, "type": "scrum"}]
assert [p["board_type"] for p in api.project_rows(conn)] == ["scrum", "scrum"]
def test_boards_diverged_types_first_by_order(conn):
jira_projects.create(conn, "A", "a", 7); jira_projects.create(conn, "B", "b", 7)
conn.execute("UPDATE jira_project SET board_type = 'kanban' WHERE label = 'B'")
conn.execute("UPDATE jira_project SET board_type = 'scrum' WHERE label = 'A'")
assert jira_projects.boards(conn) == [{"id": 7, "type": "scrum"}]
def test_light_list_same_order_no_count(conn):
jira_projects.create(conn, "B", "b", 1); jira_projects.create(conn, "A", "a")
got = jira_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:
jira_projects.create(conn, "AWPCA", "АРМ КА", board)
assert e.value.field == "board_id"
assert projects.list_projects(conn) == []
def test_create_and_list(conn):
a = jira_projects.create(conn, "AWPCA", " АРМ КА ", 4216)
assert a == {"label": "AWPCA", "name": "АРМ КА", "created_at": a["created_at"]}
jira_projects.create(conn, "STOCKS_DRRK", "Запасы ДРРК")
mirror.apply_state(conn, [{"key": "A-1", "labels": ["AWPCA"]}, {"key": "A-2", "labels": ["awpca", "x"]}], [])
got = api.project_rows(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 jira_projects.base_jql(conn) is None
projects.create(conn, "AWPCA", "АРМ КА"); projects.create(conn, "STOCKS_DRRK", "Запасы ДРРК")
assert jira_projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA", "STOCKS_DRRK")'
settings.set_(conn, "project_key", "AUR")
assert jira_projects.base_jql(conn).startswith("project = AUR AND")
def test_base_jql_single_and_reserved_words(conn):
projects.create(conn, "AWPCA", "АРМ КА")
assert jira_projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA")'
projects.create(conn, "EMPTY", "Пустой") # зарезервированное слово JQL — в кавычках
assert jira_projects.base_jql(conn) == 'project = AURORA AND labels in ("AWPCA", "EMPTY")'
def test_boards_dedup_and_types(conn):
jira_projects.create(conn, "AWPCA", "a", 4216); jira_projects.create(conn, "B", "b", 5120)
jira_projects.create(conn, "C", "c", 4216); jira_projects.create(conn, "D", "d")
jira_projects.record_board_types(conn, {"4216": "scrum"})
assert jira_projects.boards(conn) == [{"id": 4216, "type": "scrum"}, {"id": 5120, "type": None}]
assert api.project_rows(conn, ["C"])[0]["board_type"] == "scrum" # тип — у всех проектов с этой доской
@pytest.mark.parametrize("boards", [{"5120": None}, {"5120": "simple"}, {"x": "kanban"}, ["5120"], None, {}])
def test_record_board_types_ignores(conn, boards):
jira_projects.create(conn, "B", "b", 5120)
assert jira_projects.record_board_types(conn, boards) == 0
assert api.project_rows(conn, ["B"])[0]["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 jira_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 jira_projects.ensure_legacy(conn, 4216) is True
assert api.project_rows(conn, ["AWPCA"])[0]["board_id"] == 4216 and projects.get(conn, "AWPCA")["name"] == "АРМ КА"
assert jira_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 jira_projects.ensure_legacy(c, 4216) is False
c2 = open_db()
settings.ensure_defaults(c2)
assert jira_projects.ensure_legacy(c2, "oops") is True and api.project_rows(c2, ["AWPCA"])[0]["board_id"] is None