mirror of
https://github.com/himanshudongre/smriti.git
synced 2026-10-08 03:08:17 +00:00
184 lines
6.4 KiB
Python
184 lines
6.4 KiB
Python
"""Integration tests for branch disposition / lifecycle.
|
|
|
|
Covers:
|
|
- Setting disposition to integrated, abandoned, active
|
|
- Disposition filters branches from /state active_branches
|
|
- Disposition filters branches from /state divergence signal
|
|
- Reversibility: integrated → active re-shows the branch
|
|
- Nonexistent branch returns 404
|
|
- Invalid disposition returns 400
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
|
|
def _create_repo(client, name="Disposition Test"):
|
|
r = client.post("/api/v2/repos", json={"name": name})
|
|
assert r.status_code == 201, r.text
|
|
return r.json()["id"]
|
|
|
|
|
|
def _create_session(client, repo_id, title="test"):
|
|
r = client.post(
|
|
f"/api/v4/chat/spaces/{repo_id}/sessions",
|
|
json={"title": title, "provider": "openrouter", "model": "mock"},
|
|
)
|
|
assert r.status_code == 201, r.text
|
|
return r.json()["id"]
|
|
|
|
|
|
def _commit(client, repo_id, session_id, message="checkpoint", **kwargs):
|
|
payload = {"repo_id": repo_id, "session_id": session_id, "message": message, **kwargs}
|
|
r = client.post("/api/v4/chat/commit", json=payload)
|
|
assert r.status_code == 201, r.text
|
|
return r.json()
|
|
|
|
|
|
def _fork(client, space_id, checkpoint_id, branch_name=""):
|
|
r = client.post(
|
|
"/api/v5/lineage/sessions/fork",
|
|
json={
|
|
"space_id": space_id,
|
|
"checkpoint_id": checkpoint_id,
|
|
"branch_name": branch_name,
|
|
},
|
|
)
|
|
assert r.status_code == 201, r.text
|
|
return r.json()
|
|
|
|
|
|
def _set_disposition(client, space_id, branch_name, disposition):
|
|
r = client.patch(
|
|
"/api/v5/lineage/branches/disposition",
|
|
json={
|
|
"space_id": space_id,
|
|
"branch_name": branch_name,
|
|
"disposition": disposition,
|
|
},
|
|
)
|
|
return r
|
|
|
|
|
|
def _get_state(client, repo_id):
|
|
r = client.get(f"/api/v4/chat/spaces/{repo_id}/state")
|
|
assert r.status_code == 200, r.text
|
|
return r.json()
|
|
|
|
|
|
# ── Tests ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
def test_set_disposition_integrated(client):
|
|
repo_id = _create_repo(client, "Integrated")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(client, repo_id, session_id, "base", decisions=["D1"])
|
|
|
|
fork = _fork(client, repo_id, base["id"], branch_name="side-work")
|
|
_commit(client, repo_id, fork["session_id"], "fork commit", decisions=["D2"])
|
|
|
|
r = _set_disposition(client, repo_id, "side-work", "integrated")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["disposition"] == "integrated"
|
|
assert data["sessions_updated"] == 1
|
|
|
|
|
|
def test_integrated_branch_hidden_from_state(client):
|
|
"""An integrated branch should not appear in active_branches or divergence."""
|
|
repo_id = _create_repo(client, "Hidden After Integrated")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(client, repo_id, session_id, "base", decisions=["Use Pydantic"])
|
|
|
|
fork = _fork(client, repo_id, base["id"], branch_name="experiment")
|
|
_commit(
|
|
client, repo_id, fork["session_id"],
|
|
"experiment commit", decisions=["Use dataclasses"],
|
|
)
|
|
|
|
# Before disposition: branch visible
|
|
state_before = _get_state(client, repo_id)
|
|
assert len(state_before["active_branches"]) == 1
|
|
assert state_before["active_branches"][0]["branch_name"] == "experiment"
|
|
|
|
# Mark integrated
|
|
_set_disposition(client, repo_id, "experiment", "integrated")
|
|
|
|
# After disposition: branch hidden
|
|
state_after = _get_state(client, repo_id)
|
|
assert len(state_after["active_branches"]) == 0
|
|
assert state_after["divergence"] is None
|
|
|
|
|
|
def test_abandoned_branch_hidden_from_state(client):
|
|
repo_id = _create_repo(client, "Hidden After Abandoned")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(client, repo_id, session_id, "base")
|
|
|
|
fork = _fork(client, repo_id, base["id"], branch_name="dead-end")
|
|
_commit(client, repo_id, fork["session_id"], "dead end commit")
|
|
|
|
_set_disposition(client, repo_id, "dead-end", "abandoned")
|
|
|
|
state = _get_state(client, repo_id)
|
|
assert len(state["active_branches"]) == 0
|
|
|
|
|
|
def test_reversibility_active_restores_branch(client):
|
|
"""Setting back to active re-shows the branch."""
|
|
repo_id = _create_repo(client, "Reversible")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(client, repo_id, session_id, "base")
|
|
|
|
fork = _fork(client, repo_id, base["id"], branch_name="temp")
|
|
_commit(client, repo_id, fork["session_id"], "temp commit")
|
|
|
|
_set_disposition(client, repo_id, "temp", "integrated")
|
|
state_hidden = _get_state(client, repo_id)
|
|
assert len(state_hidden["active_branches"]) == 0
|
|
|
|
_set_disposition(client, repo_id, "temp", "active")
|
|
state_restored = _get_state(client, repo_id)
|
|
assert len(state_restored["active_branches"]) == 1
|
|
assert state_restored["active_branches"][0]["branch_name"] == "temp"
|
|
|
|
|
|
def test_nonexistent_branch_returns_404(client):
|
|
repo_id = _create_repo(client, "No Branch")
|
|
r = _set_disposition(client, repo_id, "ghost-branch", "integrated")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_invalid_disposition_returns_400(client):
|
|
repo_id = _create_repo(client, "Bad Disposition")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(client, repo_id, session_id, "base")
|
|
fork = _fork(client, repo_id, base["id"], branch_name="b1")
|
|
|
|
r = _set_disposition(client, repo_id, "b1", "archived")
|
|
assert r.status_code == 400
|
|
assert "disposition" in r.json()["detail"].lower()
|
|
|
|
|
|
def test_only_active_branches_generate_divergence(client):
|
|
"""Integrated branches should not trigger the divergence signal."""
|
|
repo_id = _create_repo(client, "Divergence Filter")
|
|
session_id = _create_session(client, repo_id)
|
|
base = _commit(
|
|
client, repo_id, session_id, "base",
|
|
decisions=["Main decision"],
|
|
)
|
|
|
|
fork = _fork(client, repo_id, base["id"], branch_name="alt")
|
|
_commit(
|
|
client, repo_id, fork["session_id"],
|
|
"alt commit", decisions=["Alt decision"],
|
|
)
|
|
|
|
# Divergence exists before disposition
|
|
state_before = _get_state(client, repo_id)
|
|
assert state_before["divergence"] is not None
|
|
|
|
_set_disposition(client, repo_id, "alt", "integrated")
|
|
|
|
# Divergence gone after disposition
|
|
state_after = _get_state(client, repo_id)
|
|
assert state_after["divergence"] is None
|