"""Unit tests for app.replay.models.""" from __future__ import annotations import pytest pytestmark = pytest.mark.unit class TestStepType: def test_all_step_types_exist(self) -> None: from app.replay.models import StepType assert StepType.user_message assert StepType.supervisor_routing assert StepType.tool_call assert StepType.tool_result assert StepType.agent_response assert StepType.interrupt def test_step_type_values(self) -> None: from app.replay.models import StepType assert StepType.user_message.value == "user_message" assert StepType.tool_call.value == "tool_call" assert StepType.agent_response.value == "agent_response" class TestReplayStep: def test_minimal_replay_step(self) -> None: from app.replay.models import ReplayStep, StepType step = ReplayStep(step=1, type=StepType.user_message, timestamp="2026-01-01T00:00:00Z") assert step.step == 1 assert step.type == StepType.user_message assert step.timestamp == "2026-01-01T00:00:00Z" assert step.content == "" assert step.agent is None assert step.tool is None assert step.params is None assert step.result is None assert step.reasoning is None assert step.tokens is None assert step.duration_ms is None def test_full_replay_step(self) -> None: from app.replay.models import ReplayStep, StepType step = ReplayStep( step=2, type=StepType.tool_call, timestamp="2026-01-01T00:00:01Z", content="calling get_order", agent="order_agent", tool="get_order_status", params={"order_id": "ORD-123"}, result={"status": "shipped"}, reasoning="user asked about order", tokens=50, duration_ms=200, ) assert step.step == 2 assert step.agent == "order_agent" assert step.tool == "get_order_status" assert step.params == {"order_id": "ORD-123"} assert step.tokens == 50 def test_replay_step_is_frozen(self) -> None: from app.replay.models import ReplayStep, StepType step = ReplayStep(step=1, type=StepType.user_message, timestamp="2026-01-01T00:00:00Z") with pytest.raises((AttributeError, TypeError)): step.step = 99 # type: ignore[misc] def test_replay_step_params_is_immutable_copy(self) -> None: from app.replay.models import ReplayStep, StepType params = {"key": "value"} step = ReplayStep( step=1, type=StepType.tool_call, timestamp="2026-01-01T00:00:00Z", params=params, ) # Modifying original dict should not affect step params["new_key"] = "new_value" assert "new_key" not in (step.params or {}) class TestReplayPage: def test_replay_page_construction(self) -> None: from app.replay.models import ReplayPage, ReplayStep, StepType steps = ( ReplayStep(step=1, type=StepType.user_message, timestamp="2026-01-01T00:00:00Z"), ReplayStep(step=2, type=StepType.agent_response, timestamp="2026-01-01T00:00:01Z"), ) page = ReplayPage( thread_id="thread-123", total_steps=2, page=1, per_page=20, steps=steps, ) assert page.thread_id == "thread-123" assert page.total_steps == 2 assert page.page == 1 assert page.per_page == 20 assert len(page.steps) == 2 def test_replay_page_is_frozen(self) -> None: from app.replay.models import ReplayPage page = ReplayPage( thread_id="t1", total_steps=0, page=1, per_page=20, steps=(), ) with pytest.raises((AttributeError, TypeError)): page.page = 2 # type: ignore[misc] def test_replay_page_empty_steps(self) -> None: from app.replay.models import ReplayPage page = ReplayPage( thread_id="t1", total_steps=0, page=1, per_page=20, steps=(), ) assert page.steps == ()