feat: add step cutoff and mid-session export support

- max_step_index slices decisions in all 4 export formats
- Only set exported=True when session is completed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael Chihlas
2026-02-13 08:58:03 -05:00
parent 69c95065b6
commit 8797ae0261
3 changed files with 159 additions and 8 deletions

View File

@@ -1184,3 +1184,138 @@ class TestSessions:
content = response.text
assert "## Resolution" not in content
assert "Should not appear" not in content
@pytest.mark.asyncio
async def test_export_max_step_index(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""Test max_step_index limits exported steps."""
create_response = await client.post(
"/api/v1/sessions",
json={"tree_id": test_tree["id"]},
headers=auth_headers
)
session_id = create_response.json()["id"]
decisions = [
{"node_id": "n1", "question": "Step one?", "answer": "Yes", "timestamp": "2026-02-13T10:00:00Z", "attachments": []},
{"node_id": "n2", "question": "Step two?", "answer": "No", "timestamp": "2026-02-13T10:01:00Z", "attachments": []},
{"node_id": "n3", "question": "Step three?", "answer": "Maybe", "timestamp": "2026-02-13T10:02:00Z", "attachments": []},
]
await client.put(
f"/api/v1/sessions/{session_id}",
json={"decisions": decisions},
headers=auth_headers
)
response = await client.post(
f"/api/v1/sessions/{session_id}/export",
json={"format": "markdown", "max_step_index": 2},
headers=auth_headers
)
content = response.text
assert "Step one?" in content
assert "Step two?" in content
assert "Step three?" not in content
@pytest.mark.asyncio
async def test_export_max_step_index_exceeds_count(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""Test max_step_index larger than decision count returns all steps."""
create_response = await client.post(
"/api/v1/sessions",
json={"tree_id": test_tree["id"]},
headers=auth_headers
)
session_id = create_response.json()["id"]
decisions = [
{"node_id": "n1", "question": "Only step", "answer": "Done", "timestamp": "2026-02-13T10:00:00Z", "attachments": []},
]
await client.put(
f"/api/v1/sessions/{session_id}",
json={"decisions": decisions},
headers=auth_headers
)
response = await client.post(
f"/api/v1/sessions/{session_id}/export",
json={"format": "markdown", "max_step_index": 100},
headers=auth_headers
)
assert response.status_code == 200
assert "Only step" in response.text
@pytest.mark.asyncio
async def test_export_max_step_index_zero_returns_422(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""Test max_step_index=0 returns validation error."""
create_response = await client.post(
"/api/v1/sessions",
json={"tree_id": test_tree["id"]},
headers=auth_headers
)
session_id = create_response.json()["id"]
response = await client.post(
f"/api/v1/sessions/{session_id}/export",
json={"format": "markdown", "max_step_index": 0},
headers=auth_headers
)
assert response.status_code == 422
@pytest.mark.asyncio
async def test_export_in_progress_session_does_not_mark_exported(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""Test that exporting an in-progress session does NOT set exported=True."""
create_response = await client.post(
"/api/v1/sessions",
json={"tree_id": test_tree["id"]},
headers=auth_headers
)
session_id = create_response.json()["id"]
await client.post(
f"/api/v1/sessions/{session_id}/export",
json={"format": "markdown"},
headers=auth_headers
)
response = await client.get(
f"/api/v1/sessions/{session_id}",
headers=auth_headers
)
assert response.json()["exported"] is False
@pytest.mark.asyncio
async def test_export_completed_session_marks_exported(
self, client: AsyncClient, auth_headers: dict, test_tree: dict
):
"""Test that exporting a completed session sets exported=True."""
create_response = await client.post(
"/api/v1/sessions",
json={"tree_id": test_tree["id"]},
headers=auth_headers
)
session_id = create_response.json()["id"]
await client.post(
f"/api/v1/sessions/{session_id}/complete",
json={"outcome": "resolved"},
headers=auth_headers
)
await client.post(
f"/api/v1/sessions/{session_id}/export",
json={"format": "markdown"},
headers=auth_headers
)
response = await client.get(
f"/api/v1/sessions/{session_id}",
headers=auth_headers
)
assert response.json()["exported"] is True