free-claude-code/tests/messaging/test_handler_format.py
2026-02-27 19:50:21 -08:00

132 lines
4 KiB
Python

from unittest.mock import MagicMock
import pytest
from messaging.rendering.telegram_markdown import (
escape_md_v2,
escape_md_v2_code,
mdv2_bold,
mdv2_code_inline,
render_markdown_to_mdv2,
)
from messaging.transcript import RenderCtx, TranscriptBuffer
@pytest.fixture
def handler():
platform = MagicMock()
cli = MagicMock()
store = MagicMock()
# Kept for backwards test structure; transcript rendering is now separate.
return (platform, cli, store)
def _ctx() -> RenderCtx:
return RenderCtx(
bold=mdv2_bold,
code_inline=mdv2_code_inline,
escape_code=escape_md_v2_code,
escape_text=escape_md_v2,
render_markdown=render_markdown_to_mdv2,
)
def test_transcript_structure_and_order(handler):
"""Verify ordered transcript rendering (thinking/tool/subagent/text/error/status)."""
status = "✅ *Complete*"
t = TranscriptBuffer()
# Apply in a deliberate sequence.
t.apply({"type": "thinking_chunk", "text": "Thinking process..."})
t.apply(
{"type": "tool_use", "id": "t1", "name": "list_files", "input": {"path": "."}}
)
# Subagent marker (Task tool).
t.apply(
{
"type": "tool_use",
"id": "task1",
"name": "Task",
"input": {"description": "Searching codebase..."},
}
)
t.apply(
{"type": "tool_use", "id": "t2", "name": "read_file", "input": {"path": "x.py"}}
)
t.apply({"type": "tool_result", "tool_use_id": "task1", "content": "done"})
t.apply({"type": "text_chunk", "text": "Here is the file content."})
t.apply({"type": "error", "message": "Some error happened"})
msg = t.render(_ctx(), limit_chars=3900, status=status)
print(f"Generated Message:\n{msg}")
# Check existence
assert "Thinking process..." in msg
assert "list_files" in msg
assert "read_file" in msg
assert "Searching codebase..." in msg
assert escape_md_v2("Here is the file content.") in msg
assert "Some error happened" in msg
assert "✅ *Complete*" in msg
# Check headers/markers used in the transcript.
assert "💭 *Thinking*" in msg
assert "🛠 *Tool call:*" in msg
assert "🤖 *Subagent:*" in msg
assert "⚠️ *Error:*" in msg
# Check Order: Thinking -> Tool call -> Subagent -> Content -> Errors -> Status
p_thinking = msg.find("Thinking process...")
p_tool_call = msg.find("🛠 *Tool call:*")
p_subagent = msg.find("🤖 *Subagent:*")
p_content = msg.find(escape_md_v2("Here is the file content."))
p_errors = msg.find("⚠️ *Error:*")
p_status = msg.find("✅ *Complete*")
assert p_thinking < p_tool_call, "Thinking should come before tool calls"
assert p_tool_call < p_subagent, "Tool calls should come before subagent marker"
assert p_subagent < p_content, "Subagent should come before Content"
assert p_content < p_errors, "Content should come before Errors"
assert p_errors < p_status, "Errors should come before Status"
def test_transcript_simple(handler):
"""Verify simple transcript with just text + status."""
t = TranscriptBuffer()
t.apply({"type": "text_chunk", "text": "Simple message."})
msg = t.render(_ctx(), limit_chars=3900, status="Ready")
assert escape_md_v2("Simple message.") in msg
assert "Ready" in msg
assert "💭" not in msg
assert "🛠" not in msg
def test_subagents_formatting(handler):
"""Verify subagent formatting (Task tool)."""
t = TranscriptBuffer()
t.apply(
{
"type": "tool_use",
"id": "task_1",
"name": "Task",
"input": {"description": "Task 1"},
}
)
t.apply({"type": "tool_result", "tool_use_id": "task_1", "content": "done"})
t.apply(
{
"type": "tool_use",
"id": "task_2",
"name": "Task",
"input": {"description": "Task 2"},
}
)
msg = t.render(_ctx(), limit_chars=3900, status=None)
assert "🤖 *Subagent:* `Task 1`" in msg
assert "🤖 *Subagent:* `Task 2`" in msg