kin: KIN-048 Post-pipeline hook: автокоммит после успешного завершения задачи. git add -A && git commit -m 'kin: TASK_ID TITLE'. Срабатывает автоматически как rebuild-frontend.
This commit is contained in:
parent
8a6f280cbd
commit
ae21e48b65
13 changed files with 1554 additions and 65 deletions
|
|
@ -53,6 +53,55 @@ def test_update_project_tech_stack_json(conn):
|
|||
assert updated["tech_stack"] == ["python", "fastapi"]
|
||||
|
||||
|
||||
# -- validate_completion_mode (KIN-063) --
|
||||
|
||||
def test_validate_completion_mode_valid_auto_complete():
|
||||
"""validate_completion_mode принимает 'auto_complete'."""
|
||||
assert models.validate_completion_mode("auto_complete") == "auto_complete"
|
||||
|
||||
|
||||
def test_validate_completion_mode_valid_review():
|
||||
"""validate_completion_mode принимает 'review'."""
|
||||
assert models.validate_completion_mode("review") == "review"
|
||||
|
||||
|
||||
def test_validate_completion_mode_invalid_fallback():
|
||||
"""validate_completion_mode возвращает 'review' для невалидных значений (фоллбэк)."""
|
||||
assert models.validate_completion_mode("auto") == "review"
|
||||
assert models.validate_completion_mode("") == "review"
|
||||
assert models.validate_completion_mode("unknown") == "review"
|
||||
|
||||
|
||||
# -- get_effective_mode (KIN-063) --
|
||||
|
||||
def test_get_effective_mode_task_overrides_project(conn):
|
||||
"""Task execution_mode имеет приоритет над project execution_mode."""
|
||||
models.create_project(conn, "p1", "P1", "/p1", execution_mode="review")
|
||||
models.create_task(conn, "P1-001", "p1", "Task", execution_mode="auto_complete")
|
||||
mode = models.get_effective_mode(conn, "p1", "P1-001")
|
||||
assert mode == "auto_complete"
|
||||
|
||||
|
||||
def test_get_effective_mode_falls_back_to_project(conn):
|
||||
"""Если задача без execution_mode — применяется project execution_mode."""
|
||||
models.create_project(conn, "p1", "P1", "/p1", execution_mode="auto_complete")
|
||||
models.create_task(conn, "P1-001", "p1", "Task") # execution_mode=None
|
||||
mode = models.get_effective_mode(conn, "p1", "P1-001")
|
||||
assert mode == "auto_complete"
|
||||
|
||||
|
||||
def test_get_effective_mode_project_review_overrides_default(conn):
|
||||
"""Project execution_mode='review' + task без override → возвращает 'review'.
|
||||
|
||||
Сценарий: PM хотел auto_complete, но проект настроен на review человеком.
|
||||
get_effective_mode должен вернуть project-level 'review'.
|
||||
"""
|
||||
models.create_project(conn, "p1", "P1", "/p1", execution_mode="review")
|
||||
models.create_task(conn, "P1-001", "p1", "Task") # нет task-level override
|
||||
mode = models.get_effective_mode(conn, "p1", "P1-001")
|
||||
assert mode == "review"
|
||||
|
||||
|
||||
# -- Tasks --
|
||||
|
||||
def test_create_and_get_task(conn):
|
||||
|
|
@ -238,3 +287,46 @@ def test_cost_summary(conn):
|
|||
def test_cost_summary_empty(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
assert models.get_cost_summary(conn, days=7) == []
|
||||
|
||||
|
||||
# -- add_decision_if_new --
|
||||
|
||||
def test_add_decision_if_new_adds_new_decision(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
d = models.add_decision_if_new(conn, "p1", "gotcha", "Use WAL mode", "description")
|
||||
assert d is not None
|
||||
assert d["title"] == "Use WAL mode"
|
||||
assert d["type"] == "gotcha"
|
||||
|
||||
|
||||
def test_add_decision_if_new_skips_exact_duplicate(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
models.add_decision(conn, "p1", "gotcha", "Use WAL mode", "desc1")
|
||||
result = models.add_decision_if_new(conn, "p1", "gotcha", "Use WAL mode", "desc2")
|
||||
assert result is None
|
||||
# Existing decision not duplicated
|
||||
assert len(models.get_decisions(conn, "p1")) == 1
|
||||
|
||||
|
||||
def test_add_decision_if_new_skips_case_insensitive_duplicate(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
models.add_decision(conn, "p1", "decision", "Use UUID for task IDs", "desc")
|
||||
result = models.add_decision_if_new(conn, "p1", "decision", "use uuid for task ids", "other desc")
|
||||
assert result is None
|
||||
assert len(models.get_decisions(conn, "p1")) == 1
|
||||
|
||||
|
||||
def test_add_decision_if_new_allows_same_title_different_type(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
models.add_decision(conn, "p1", "gotcha", "SQLite WAL", "desc")
|
||||
result = models.add_decision_if_new(conn, "p1", "convention", "SQLite WAL", "other desc")
|
||||
assert result is not None
|
||||
assert len(models.get_decisions(conn, "p1")) == 2
|
||||
|
||||
|
||||
def test_add_decision_if_new_skips_whitespace_duplicate(conn):
|
||||
models.create_project(conn, "p1", "P1", "/p1")
|
||||
models.add_decision(conn, "p1", "convention", "Run tests after each change", "desc")
|
||||
result = models.add_decision_if_new(conn, "p1", "convention", " Run tests after each change ", "desc2")
|
||||
assert result is None
|
||||
assert len(models.get_decisions(conn, "p1")) == 1
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue