kin: auto-commit after pipeline
This commit is contained in:
parent
63002a2018
commit
cfc4a6ba7d
1 changed files with 77 additions and 0 deletions
|
|
@ -932,3 +932,80 @@ def test_get_pipeline_logs_ordered_asc(pipeline_conn):
|
||||||
logs = models.get_pipeline_logs(db, pid)
|
logs = models.get_pipeline_logs(db, pid)
|
||||||
ids = [log["id"] for log in logs]
|
ids = [log["id"] for log in logs]
|
||||||
assert ids == sorted(ids)
|
assert ids == sorted(ids)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# KIN-UI-018: Защита от circular references в has_open_children /
|
||||||
|
# _check_parent_completion (decision #816, #817)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_circular_reference_protection_has_open_children_returns_false(conn):
|
||||||
|
"""KIN-UI-018 (decision #816): has_open_children возвращает False при циклической ссылке A→B→A.
|
||||||
|
|
||||||
|
Задачи A и B создаются напрямую в БД с взаимными parent_task_id.
|
||||||
|
Ожидаемый результат: False (не True, не RecursionError).
|
||||||
|
"""
|
||||||
|
models.create_project(conn, "p1", "P1", "/p1")
|
||||||
|
# Создаём задачи без parent сначала
|
||||||
|
models.create_task(conn, "P1-CYC-A", "p1", "Task A")
|
||||||
|
models.create_task(conn, "P1-CYC-B", "p1", "Task B")
|
||||||
|
# Устанавливаем цикл напрямую в БД, минуя валидацию API
|
||||||
|
conn.execute("UPDATE tasks SET parent_task_id = 'P1-CYC-B' WHERE id = 'P1-CYC-A'")
|
||||||
|
conn.execute("UPDATE tasks SET parent_task_id = 'P1-CYC-A' WHERE id = 'P1-CYC-B'")
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
result_a = models.has_open_children(conn, "P1-CYC-A")
|
||||||
|
result_b = models.has_open_children(conn, "P1-CYC-B")
|
||||||
|
|
||||||
|
assert result_a is False
|
||||||
|
assert result_b is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_circular_reference_protection_check_parent_completion_returns_without_error(conn):
|
||||||
|
"""KIN-UI-018 (decision #817): _check_parent_completion не падает и не зависает при цикле A→B→A.
|
||||||
|
|
||||||
|
Задачи A и B в статусе 'revising' с взаимными parent_task_id.
|
||||||
|
Ожидаемый результат: возврат без RecursionError, статус задач не изменился.
|
||||||
|
"""
|
||||||
|
models.create_project(conn, "p1", "P1", "/p1")
|
||||||
|
models.create_task(conn, "P1-CPC-A", "p1", "Task A", status="revising")
|
||||||
|
models.create_task(conn, "P1-CPC-B", "p1", "Task B", status="revising")
|
||||||
|
# Устанавливаем цикл напрямую в БД
|
||||||
|
conn.execute("UPDATE tasks SET parent_task_id = 'P1-CPC-B' WHERE id = 'P1-CPC-A'")
|
||||||
|
conn.execute("UPDATE tasks SET parent_task_id = 'P1-CPC-A' WHERE id = 'P1-CPC-B'")
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
# Не должно бросить RecursionError или зависнуть
|
||||||
|
models._check_parent_completion(conn, "P1-CPC-A")
|
||||||
|
models._check_parent_completion(conn, "P1-CPC-B")
|
||||||
|
|
||||||
|
# Статусы не изменились — цикл обнаружен и прерван
|
||||||
|
task_a = models.get_task(conn, "P1-CPC-A")
|
||||||
|
task_b = models.get_task(conn, "P1-CPC-B")
|
||||||
|
assert task_a["status"] == "revising"
|
||||||
|
assert task_b["status"] == "revising"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# KIN-UI-020: VALID_TASK_STATUSES — frozenset membership checks
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def test_valid_task_statuses_is_frozenset():
|
||||||
|
"""KIN-UI-020: VALID_TASK_STATUSES должен быть frozenset, не list."""
|
||||||
|
assert isinstance(models.VALID_TASK_STATUSES, frozenset)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("status", [
|
||||||
|
"pending", "in_progress", "review", "done",
|
||||||
|
"blocked", "decomposed", "cancelled", "revising",
|
||||||
|
])
|
||||||
|
def test_valid_task_statuses_membership(status):
|
||||||
|
"""KIN-UI-020: каждый валидный статус присутствует в VALID_TASK_STATUSES (membership check)."""
|
||||||
|
assert status in models.VALID_TASK_STATUSES
|
||||||
|
|
||||||
|
|
||||||
|
def test_invalid_status_not_in_valid_task_statuses():
|
||||||
|
"""KIN-UI-020: невалидный статус отсутствует в VALID_TASK_STATUSES."""
|
||||||
|
assert "invalid_status" not in models.VALID_TASK_STATUSES
|
||||||
|
assert "" not in models.VALID_TASK_STATUSES
|
||||||
|
assert "active" not in models.VALID_TASK_STATUSES
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue