Ensure ToolCommand is authenticated

This commit is contained in:
Vinicius Brasil
2025-05-02 10:55:26 -03:00
parent 183b18a006
commit f2f6747b74
2 changed files with 34 additions and 46 deletions

View File

@@ -20,7 +20,7 @@ class PlusAPIMixin:
try:
telemetry.set_tracer()
self.plus_api_client = PlusAPI(api_key=get_auth_token())
except Exception:
except Exception as e:
self._deploy_signup_error_span = telemetry.deploy_signup_error_span()
console.print(
"Please sign up/login to CrewAI+ before using the CLI.",

View File

@@ -6,8 +6,10 @@ from contextlib import contextmanager
from unittest import mock
from unittest.mock import MagicMock, patch
import pytest
from pytest import raises
from crewai.cli.authentication.utils import TokenManager
from crewai.cli.tools.main import ToolCommand
@@ -22,14 +24,20 @@ def in_temp_dir():
os.chdir(original_dir)
@patch("crewai.cli.tools.main.subprocess.run")
def test_create_success(mock_subprocess, capsys):
with in_temp_dir():
tool_command = ToolCommand()
@pytest.fixture
def tool_command():
TokenManager().save_tokens("test-token", 36000)
tool_command = ToolCommand()
with patch.object(tool_command, "login"):
yield tool_command
with patch.object(tool_command, "login") as mock_login:
tool_command.create("test-tool")
output = capsys.readouterr().out
@patch("crewai.cli.tools.main.subprocess.run")
def test_create_success(mock_subprocess, capsys, tool_command):
with in_temp_dir():
tool_command.create("test-tool")
output = capsys.readouterr().out
assert "Creating custom tool test_tool..." in output
assert os.path.isdir("test_tool")
assert os.path.isfile(os.path.join("test_tool", "README.md"))
@@ -43,15 +51,12 @@ def test_create_success(mock_subprocess, capsys):
content = f.read()
assert "class TestTool" in content
mock_login.assert_called_once()
mock_subprocess.assert_called_once_with(["git", "init"], check=True)
assert "Creating custom tool test_tool..." in output
@patch("crewai.cli.tools.main.subprocess.run")
@patch("crewai.cli.plus_api.PlusAPI.get_tool")
def test_install_success(mock_get, mock_subprocess_run, capsys):
def test_install_success(mock_get, mock_subprocess_run, capsys, tool_command):
mock_get_response = MagicMock()
mock_get_response.status_code = 200
mock_get_response.json.return_value = {
@@ -61,9 +66,9 @@ def test_install_success(mock_get, mock_subprocess_run, capsys):
mock_get.return_value = mock_get_response
mock_subprocess_run.return_value = MagicMock(stderr=None)
tool_command = ToolCommand()
tool_command.install("sample-tool")
output = capsys.readouterr().out
assert "Successfully installed sample-tool" in output
mock_get.assert_has_calls([mock.call("sample-tool"), mock.call().json()])
mock_subprocess_run.assert_any_call(
@@ -80,49 +85,38 @@ def test_install_success(mock_get, mock_subprocess_run, capsys):
env=unittest.mock.ANY,
)
assert "Successfully installed sample-tool" in output
@patch("crewai.cli.plus_api.PlusAPI.get_tool")
def test_install_tool_not_found(mock_get, capsys):
def test_install_tool_not_found(mock_get, capsys, tool_command):
mock_get_response = MagicMock()
mock_get_response.status_code = 404
mock_get.return_value = mock_get_response
tool_command = ToolCommand()
try:
with raises(SystemExit):
tool_command.install("non-existent-tool")
except SystemExit:
pass
output = capsys.readouterr().out
assert "No tool found with this name" in output
mock_get.assert_called_once_with("non-existent-tool")
assert "No tool found with this name" in output
@patch("crewai.cli.plus_api.PlusAPI.get_tool")
def test_install_api_error(mock_get, capsys):
def test_install_api_error(mock_get, capsys, tool_command):
mock_get_response = MagicMock()
mock_get_response.status_code = 500
mock_get.return_value = mock_get_response
tool_command = ToolCommand()
try:
with raises(SystemExit):
tool_command.install("error-tool")
except SystemExit:
pass
output = capsys.readouterr().out
assert "Failed to get tool details" in output
mock_get.assert_called_once_with("error-tool")
assert "Failed to get tool details" in output
@patch("crewai.cli.tools.main.git.Repository.is_synced", return_value=False)
def test_publish_when_not_in_sync(mock_is_synced, capsys):
def test_publish_when_not_in_sync(mock_is_synced, capsys, tool_command):
with raises(SystemExit):
tool_command = ToolCommand()
tool_command.publish(is_public=True)
output = capsys.readouterr().out
@@ -150,13 +144,13 @@ def test_publish_when_not_in_sync_and_force(
mock_get_project_description,
mock_get_project_version,
mock_get_project_name,
tool_command,
):
mock_publish_response = MagicMock()
mock_publish_response.status_code = 200
mock_publish_response.json.return_value = {"handle": "sample-tool"}
mock_publish.return_value = mock_publish_response
tool_command = ToolCommand()
tool_command.publish(is_public=True, force=True)
mock_get_project_name.assert_called_with(require=True)
@@ -198,13 +192,13 @@ def test_publish_success(
mock_get_project_description,
mock_get_project_version,
mock_get_project_name,
tool_command,
):
mock_publish_response = MagicMock()
mock_publish_response.status_code = 200
mock_publish_response.json.return_value = {"handle": "sample-tool"}
mock_publish.return_value = mock_publish_response
tool_command = ToolCommand()
tool_command.publish(is_public=True)
mock_get_project_name.assert_called_with(require=True)
@@ -245,24 +239,21 @@ def test_publish_failure(
mock_get_project_version,
mock_get_project_name,
capsys,
tool_command,
):
mock_publish_response = MagicMock()
mock_publish_response.status_code = 422
mock_publish_response.json.return_value = {"name": ["is already taken"]}
mock_publish.return_value = mock_publish_response
tool_command = ToolCommand()
try:
with raises(SystemExit):
tool_command.publish(is_public=True)
except SystemExit:
pass
output = capsys.readouterr().out
mock_publish.assert_called_once()
assert "Failed to complete operation" in output
assert "Name is already taken" in output
mock_publish.assert_called_once()
@patch("crewai.cli.tools.main.get_project_name", return_value="sample-tool")
@patch("crewai.cli.tools.main.get_project_version", return_value="1.0.0")
@@ -284,6 +275,7 @@ def test_publish_api_error(
mock_get_project_version,
mock_get_project_name,
capsys,
tool_command,
):
mock_response = MagicMock()
mock_response.status_code = 500
@@ -291,13 +283,9 @@ def test_publish_api_error(
mock_response.ok = False
mock_publish.return_value = mock_response
tool_command = ToolCommand()
try:
with raises(SystemExit):
tool_command.publish(is_public=True)
except SystemExit:
pass
output = capsys.readouterr().out
assert "Request to Enterprise API failed" in output
mock_publish.assert_called_once()
assert "Request to Enterprise API failed" in output