"""Unit tests for app.replay.transformer.""" from __future__ import annotations import pytest pytestmark = pytest.mark.unit def _make_row(messages: list[dict], metadata: dict | None = None) -> dict: """Helper to build a checkpoint row with the given messages.""" return { "thread_id": "thread-abc", "checkpoint_id": "cp-001", "checkpoint": {"channel_values": {"messages": messages}}, "metadata": metadata or {}, } class TestTransformCheckpoints: def test_empty_rows_returns_empty_list(self) -> None: from app.replay.transformer import transform_checkpoints result = transform_checkpoints([]) assert result == [] def test_human_message_produces_user_message_step(self) -> None: from app.replay.models import StepType from app.replay.transformer import transform_checkpoints rows = [_make_row([{"type": "human", "content": "Hello, I need help"}])] steps = transform_checkpoints(rows) assert len(steps) == 1 assert steps[0].type == StepType.user_message assert steps[0].content == "Hello, I need help" assert steps[0].step == 1 def test_ai_message_with_content_produces_agent_response(self) -> None: from app.replay.models import StepType from app.replay.transformer import transform_checkpoints rows = [ _make_row( [{"type": "ai", "content": "I can help you with that.", "tool_calls": []}], metadata={"writes": {"some_agent": "response"}}, ) ] steps = transform_checkpoints(rows) assert len(steps) == 1 assert steps[0].type == StepType.agent_response assert steps[0].content == "I can help you with that." def test_ai_message_with_tool_calls_produces_tool_call_step(self) -> None: from app.replay.models import StepType from app.replay.transformer import transform_checkpoints rows = [ _make_row( [ { "type": "ai", "content": "", "tool_calls": [ { "name": "get_order_status", "args": {"order_id": "ORD-123"}, "id": "call_abc", } ], } ] ) ] steps = transform_checkpoints(rows) assert len(steps) == 1 assert steps[0].type == StepType.tool_call assert steps[0].tool == "get_order_status" assert steps[0].params == {"order_id": "ORD-123"} def test_tool_message_produces_tool_result_step(self) -> None: from app.replay.models import StepType from app.replay.transformer import transform_checkpoints rows = [ _make_row( [ { "type": "tool", "content": '{"status": "shipped"}', "name": "get_order_status", } ] ) ] steps = transform_checkpoints(rows) assert len(steps) == 1 assert steps[0].type == StepType.tool_result assert steps[0].tool == "get_order_status" def test_multiple_messages_sequential_steps(self) -> None: from app.replay.transformer import transform_checkpoints rows = [ _make_row( [ {"type": "human", "content": "Help"}, {"type": "ai", "content": "Sure!", "tool_calls": []}, ] ) ] steps = transform_checkpoints(rows) assert len(steps) == 2 assert steps[0].step == 1 assert steps[1].step == 2 def test_unknown_message_type_skipped(self) -> None: from app.replay.transformer import transform_checkpoints rows = [_make_row([{"type": "unknown_type", "content": "test"}])] steps = transform_checkpoints(rows) # Should not crash; unknown types may be skipped assert isinstance(steps, list) def test_row_missing_checkpoint_skipped(self) -> None: from app.replay.transformer import transform_checkpoints rows = [{"thread_id": "t1", "checkpoint_id": "cp1", "checkpoint": None, "metadata": {}}] steps = transform_checkpoints(rows) assert isinstance(steps, list) def test_row_missing_messages_key_skipped(self) -> None: from app.replay.transformer import transform_checkpoints rows = [{"thread_id": "t1", "checkpoint_id": "cp1", "checkpoint": {}, "metadata": {}}] steps = transform_checkpoints(rows) assert isinstance(steps, list) def test_multiple_rows_steps_are_continuous(self) -> None: from app.replay.transformer import transform_checkpoints rows = [ _make_row([{"type": "human", "content": "Q1"}]), _make_row([{"type": "ai", "content": "A1", "tool_calls": []}]), ] steps = transform_checkpoints(rows) assert len(steps) == 2 assert steps[0].step == 1 assert steps[1].step == 2 def test_timestamps_are_strings(self) -> None: from app.replay.transformer import transform_checkpoints rows = [_make_row([{"type": "human", "content": "Hi"}])] steps = transform_checkpoints(rows) assert isinstance(steps[0].timestamp, str)