"""Tests for workspace and project tools."""
from unittest.mock import patch, MagicMock
from bitbucket_mcp.tools import workspace as _mod
list_workspace_members = _mod.list_workspace_members.fn
get_default_reviewers = _mod.get_default_reviewers.fn
list_workspaces = _mod.list_workspaces.fn
get_workspace_details = _mod.get_workspace_details.fn
list_workspace_permissions = _mod.list_workspace_permissions.fn
list_projects = _mod.list_projects.fn
get_project = _mod.get_project.fn
create_project = _mod.create_project.fn
search_code = _mod.search_code.fn
from tests.conftest import make_mock_response, make_paginated_response
class TestListWorkspaceMembers:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"user": {
"uuid": "{user-uuid}",
"account_id": "123",
"display_name": "Dev",
"nickname": "dev",
}
}
],
"size": 1, "page": 1, "pagelen": 50,
})
result = list_workspace_members()
assert result["success"] is True
assert len(result["members"]) == 1
assert result["members"][0]["display_name"] == "Dev"
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_not_found(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(404)
result = list_workspace_members()
assert result["success"] is False
assert "not found" in result["error"]
class TestGetDefaultReviewers:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"uuid": "{rev-uuid}",
"display_name": "Reviewer",
"nickname": "rev",
}
]
})
result = get_default_reviewers("repo")
assert result["success"] is True
assert result["count"] == 1
assert result["default_reviewers"][0]["display_name"] == "Reviewer"
class TestListWorkspaces:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"uuid": "{ws-uuid}",
"slug": "my-ws",
"name": "My Workspace",
"is_private": False,
"created_on": "2025-01-01",
"links": {"html": {"href": "https://bb.org/my-ws"}},
}
],
"size": 1,
})
result = list_workspaces()
assert result["success"] is True
assert len(result["workspaces"]) == 1
assert result["workspaces"][0]["slug"] == "my-ws"
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_auth_failure(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(401)
result = list_workspaces()
assert result["success"] is False
assert "Authentication failed" in result["error"]
class TestGetWorkspaceDetails:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"uuid": "{ws-uuid}",
"slug": "my-ws",
"name": "My Workspace",
"is_private": False,
"created_on": "2025-01-01",
"links": {"html": {"href": "https://bb.org/my-ws"}},
})
result = get_workspace_details()
assert result["success"] is True
assert result["slug"] == "my-ws"
assert result["name"] == "My Workspace"
class TestListWorkspacePermissions:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"user": {"display_name": "Admin", "uuid": "{user-uuid}"},
"permission": "owner",
}
],
"size": 1, "page": 1, "pagelen": 50,
})
result = list_workspace_permissions()
assert result["success"] is True
assert len(result["permissions"]) == 1
assert result["permissions"][0]["permission"] == "owner"
class TestListProjects:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"key": "PROJ",
"name": "My Project",
"description": "A project",
"is_private": True,
"created_on": "2025-01-01",
"updated_on": "2025-01-02",
"links": {"html": {"href": "https://bb.org/proj"}},
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = list_projects()
assert result["success"] is True
assert len(result["projects"]) == 1
assert result["projects"][0]["key"] == "PROJ"
class TestGetProject:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"key": "PROJ",
"name": "My Project",
"description": "A project",
"is_private": True,
"created_on": "2025-01-01",
"updated_on": "2025-01-02",
"owner": {"display_name": "Owner"},
"links": {"html": {"href": "https://bb.org/proj"}},
})
result = get_project("PROJ")
assert result["success"] is True
assert result["key"] == "PROJ"
assert result["owner"] == "Owner"
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_not_found(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(404)
result = get_project("NONEXISTENT")
assert result["success"] is False
assert "not found" in result["error"]
class TestCreateProject:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.post.return_value = make_mock_response(201, {
"key": "NEW",
"name": "New Project",
"description": "desc",
"is_private": True,
"links": {"html": {"href": "https://bb.org/new"}},
})
result = create_project("New Project", "NEW", description="desc")
assert result["success"] is True
assert result["key"] == "NEW"
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_permission_denied(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.post.return_value = make_mock_response(403)
result = create_project("New", "NEW")
assert result["success"] is False
assert "Permission denied" in result["error"]
class TestSearchCode:
@patch("bitbucket_mcp.tools.workspace.httpx.Client")
def test_success(self, MockClient, saved_config):
client = MagicMock()
MockClient.return_value.__enter__ = MagicMock(return_value=client)
MockClient.return_value.__exit__ = MagicMock(return_value=False)
client.get.return_value = make_mock_response(200, {
"values": [
{
"file": {
"path": "src/main.py",
"links": {"self": {"href": "https://bb.org/ws/repo/src/main/src/main.py"}},
},
"content_matches": [
{
"lines": [
{
"line": 10,
"segments": [{"text": "def search():"}]
}
]
}
]
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = search_code("def search")
assert result["success"] is True
assert len(result["results"]) == 1
assert result["results"][0]["file_path"] == "src/main.py"
assert result["query"] == "def search"