test(05-03): add failing shared-volume attachment contract tests

- cover room-safe Matrix inbox paths under /agents workspaces
- assert /workspace and /agents file paths normalize to relative workspace paths
This commit is contained in:
Mikhail Putilovskij 2026-04-28 01:04:31 +03:00
parent 26eb27b01e
commit cafb0ec9e4
2 changed files with 52 additions and 0 deletions

View file

@ -48,3 +48,20 @@ async def test_download_matrix_attachment_persists_file_and_returns_workspace_pa
assert saved.workspace_path is not None assert saved.workspace_path is not None
assert saved.workspace_path.endswith("20260420-153000-report.pdf") assert saved.workspace_path.endswith("20260420-153000-report.pdf")
assert (tmp_path / saved.workspace_path).read_bytes() == b"%PDF-1.7" assert (tmp_path / saved.workspace_path).read_bytes() == b"%PDF-1.7"
def test_build_workspace_attachment_path_keeps_room_safe_agents_relative_contract(tmp_path: Path):
rel_path, abs_path = build_workspace_attachment_path(
workspace_root=tmp_path / "agents" / "7",
matrix_user_id="@alice+bob:example.org",
room_id="!room/ops:example.org",
filename="quarterly status (final).pdf",
timestamp="20260420-153000",
)
assert rel_path == (
"surfaces/matrix/alice_bob_example.org/room_ops_example.org/inbox/"
"20260420-153000-quarterly_status_final_.pdf"
)
assert not Path(rel_path).is_absolute()
assert abs_path == tmp_path / "agents" / "7" / rel_path

View file

@ -190,6 +190,7 @@ async def test_real_platform_client_forwards_attachments_to_chat_api():
agent_api = FakeAgentApiFactory(chat_api_cls=AttachmentTrackingChatAgentApi) agent_api = FakeAgentApiFactory(chat_api_cls=AttachmentTrackingChatAgentApi)
client = make_real_platform_client(agent_api) client = make_real_platform_client(agent_api)
attachment = Attachment( attachment = Attachment(
url="/agents/7/surfaces/matrix/alice/room/inbox/report.pdf",
workspace_path="surfaces/matrix/alice/room/inbox/report.pdf", workspace_path="surfaces/matrix/alice/room/inbox/report.pdf",
mime_type="application/pdf", mime_type="application/pdf",
filename="report.pdf", filename="report.pdf",
@ -210,6 +211,20 @@ async def test_real_platform_client_forwards_attachments_to_chat_api():
assert result.tokens_used == 0 assert result.tokens_used == 0
def test_attachment_paths_normalize_workspace_roots_to_relative_paths():
attachments = [
Attachment(workspace_path="/workspace/output/report.pdf"),
Attachment(workspace_path="/agents/7/output/report.csv"),
Attachment(workspace_path="surfaces/matrix/alice/room/inbox/note.txt"),
]
assert RealPlatformClient._attachment_paths(attachments) == [
"output/report.pdf",
"output/report.csv",
"surfaces/matrix/alice/room/inbox/note.txt",
]
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_real_platform_client_preserves_send_file_events_in_sync_result(monkeypatch): async def test_real_platform_client_preserves_send_file_events_in_sync_result(monkeypatch):
class FileEventAgentApi(AttachmentTrackingChatAgentApi): class FileEventAgentApi(AttachmentTrackingChatAgentApi):
@ -239,6 +254,26 @@ async def test_real_platform_client_preserves_send_file_events_in_sync_result(mo
] ]
@pytest.mark.parametrize(
("location", "expected_workspace_path"),
[
("/workspace/output/report.pdf", "output/report.pdf"),
("/agents/7/output/report.pdf", "output/report.pdf"),
("surfaces/matrix/alice/room/inbox/report.pdf", "surfaces/matrix/alice/room/inbox/report.pdf"),
],
)
def test_attachment_from_send_file_event_normalizes_shared_volume_paths(
location: str, expected_workspace_path: str
):
attachment = RealPlatformClient._attachment_from_send_file_event(
MsgEventSendFile(path=location)
)
assert attachment.url == location
assert attachment.workspace_path == expected_workspace_path
assert attachment.filename == "report.pdf"
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_real_platform_client_uses_fresh_agent_connection_per_request(): async def test_real_platform_client_uses_fresh_agent_connection_per_request():
agent_api = FakeAgentApiFactory() agent_api = FakeAgentApiFactory()