from __future__ import annotations from unittest.mock import AsyncMock, patch import pytest from app.agents.folder_agent import read_project_folder_file pytestmark = pytest.mark.asyncio async def test_happy_path(): with patch( "app.agents.folder_agent.execute_on_client", new=AsyncMock(return_value={"content": "file body"}), ): out = await read_project_folder_file.ainvoke({"project_id": "p1", "relative_path": "docs/x.md"}) assert out == "file body" async def test_traversal_rejected(): out = await read_project_folder_file.ainvoke({"project_id": "p1", "relative_path": "../../etc/passwd"}) assert out == "Access denied" async def test_absolute_path_rejected(): out = await read_project_folder_file.ainvoke({"project_id": "p1", "relative_path": "C:\\Windows\\foo"}) assert out == "Access denied" async def test_missing_file(): with patch( "app.agents.folder_agent.execute_on_client", new=AsyncMock(return_value={"content": ""}), ): out = await read_project_folder_file.ainvoke({"project_id": "p1", "relative_path": "ghost.md"}) assert "not found" in out.lower()