test_import_tool.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. """Tests for CLI import-tool command."""
  2. from pathlib import Path
  3. import pytest
  4. from agency_swarm.cli.import_tool import import_tool_command
  5. def test_import_tool_list_available_tools(capsys: pytest.CaptureFixture[str]) -> None:
  6. """List flag should display all available tools."""
  7. exit_code = import_tool_command(list_tools=True)
  8. assert exit_code == 0
  9. captured = capsys.readouterr()
  10. assert "Available built-in tools:" in captured.out
  11. assert "IPythonInterpreter" in captured.out
  12. assert "PersistentShellTool" in captured.out
  13. assert "LoadFileAttachment" in captured.out
  14. def test_import_tool_unknown_tool_name(tmp_path: Path) -> None:
  15. """Import should fail when tool name is unknown."""
  16. exit_code = import_tool_command(tool_name="UnknownTool", directory=str(tmp_path / "tools"))
  17. assert exit_code == 1
  18. def test_import_tool_no_tool_name_provided(tmp_path: Path) -> None:
  19. """Import should fail when no tool name is provided."""
  20. exit_code = import_tool_command(tool_name=None, directory=str(tmp_path / "tools"))
  21. assert exit_code == 1
  22. def test_import_tool_successful_copy(tmp_path: Path) -> None:
  23. """Built-in tool should be successfully copied to destination."""
  24. dest_dir = tmp_path / "tools"
  25. exit_code = import_tool_command(tool_name="IPythonInterpreter", directory=str(dest_dir))
  26. assert exit_code == 0
  27. assert (dest_dir / "IPythonInterpreter.py").exists()
  28. # Verify it's actual Python code
  29. content = (dest_dir / "IPythonInterpreter.py").read_text()
  30. assert "class IPythonInterpreter" in content or "IPythonInterpreter" in content
  31. def test_import_tool_creates_destination_directory(tmp_path: Path) -> None:
  32. """Tool import should create destination directory if it doesn't exist."""
  33. dest_dir = tmp_path / "nested" / "tools"
  34. exit_code = import_tool_command(tool_name="PersistentShellTool", directory=str(dest_dir))
  35. assert exit_code == 0
  36. assert dest_dir.exists()
  37. assert (dest_dir / "PersistentShellTool.py").exists()
  38. def test_import_tool_all_built_in_tools(tmp_path: Path) -> None:
  39. """All built-in tools should be importable."""
  40. from agency_swarm.cli.import_tool import _get_available_tools
  41. dest_dir = tmp_path / "tools"
  42. available_tools = _get_available_tools()
  43. # Should have at least the 3 custom built-in tools
  44. assert len(available_tools) >= 3, "Should have at least 3 built-in tools"
  45. for tool_name in available_tools:
  46. exit_code = import_tool_command(tool_name=tool_name, directory=str(dest_dir))
  47. assert exit_code == 0, f"Failed to import {tool_name}"
  48. assert (dest_dir / f"{tool_name}.py").exists(), f"{tool_name}.py was not created"
  49. def test_import_tool_overwrites_existing_file_with_confirmation(
  50. tmp_path: Path, monkeypatch: pytest.MonkeyPatch
  51. ) -> None:
  52. """Tool should overwrite existing file when user confirms."""
  53. dest_dir = tmp_path / "tools"
  54. dest_dir.mkdir()
  55. existing_file = dest_dir / "LoadFileAttachment.py"
  56. existing_file.write_text("# Old content\n")
  57. # Simulate user confirming overwrite
  58. monkeypatch.setattr("builtins.input", lambda _: "y")
  59. exit_code = import_tool_command(tool_name="LoadFileAttachment", directory=str(dest_dir))
  60. assert exit_code == 0
  61. # Should contain actual tool code, not old content
  62. assert existing_file.read_text() != "# Old content\n"
  63. def test_import_tool_cancels_on_overwrite_rejection(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
  64. """Tool should not overwrite existing file when user rejects."""
  65. dest_dir = tmp_path / "tools"
  66. dest_dir.mkdir()
  67. existing_file = dest_dir / "IPythonInterpreter.py"
  68. existing_file.write_text("# Old content\n")
  69. # Simulate user rejecting overwrite
  70. monkeypatch.setattr("builtins.input", lambda _: "n")
  71. exit_code = import_tool_command(tool_name="IPythonInterpreter", directory=str(dest_dir))
  72. assert exit_code == 0
  73. assert existing_file.read_text() == "# Old content\n"