"""Tests for commit and build status tools."""
from unittest.mock import patch, MagicMock
from bitbucket_mcp.tools import commits as _mod
get_file_contents = _mod.get_file_contents.fn
list_commits = _mod.list_commits.fn
get_commit = _mod.get_commit.fn
get_commit_diff = _mod.get_commit_diff.fn
get_commit_diffstat = _mod.get_commit_diffstat.fn
list_commit_statuses = _mod.list_commit_statuses.fn
create_build_status = _mod.create_build_status.fn
list_commit_comments = _mod.list_commit_comments.fn
from tests.conftest import make_mock_response
class TestGetFileContents:
@patch("bitbucket_mcp.tools.commits.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)
resp = make_mock_response(200)
resp.text = "print('hello world')"
client.get.return_value = resp
result = get_file_contents("repo", "main.py")
assert result["success"] is True
assert result["content"] == "print('hello world')"
assert result["file_path"] == "main.py"
assert result["truncated"] is False
@patch("bitbucket_mcp.tools.commits.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_file_contents("repo", "nonexistent.py")
assert result["success"] is False
assert "not found" in result["error"]
class TestListCommits:
@patch("bitbucket_mcp.tools.commits.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": [
{
"hash": "abc123def456789",
"message": "Fix bug\nDetailed description",
"date": "2025-01-01",
"author": {"user": {"display_name": "Dev"}},
"links": {"html": {"href": "https://bb.org/commit/abc123"}}
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = list_commits("repo")
assert result["success"] is True
assert len(result["commits"]) == 1
assert result["commits"][0]["hash"] == "abc123def456789"
assert result["commits"][0]["hash_short"] == "abc123d"
assert result["commits"][0]["message_summary"] == "Fix bug"
@patch("bitbucket_mcp.tools.commits.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_commits("nonexistent")
assert result["success"] is False
assert "not found" in result["error"]
class TestGetCommit:
@patch("bitbucket_mcp.tools.commits.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, {
"hash": "abc123def456789",
"message": "Fix bug",
"date": "2025-01-01",
"author": {"user": {"display_name": "Dev"}},
"parents": [{"hash": "parent123456"}],
"links": {"html": {"href": "https://bb.org/commit/abc123"}}
})
result = get_commit("repo", "abc123def456789")
assert result["success"] is True
assert result["hash"] == "abc123def456789"
assert result["parents"] == ["parent1"]
@patch("bitbucket_mcp.tools.commits.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_commit("repo", "nonexistent")
assert result["success"] is False
assert "not found" in result["error"]
class TestGetCommitDiff:
@patch("bitbucket_mcp.tools.commits.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)
resp = make_mock_response(200)
resp.text = "--- a/file.py\n+++ b/file.py\n@@ -1 +1 @@\n-old\n+new"
client.get.return_value = resp
result = get_commit_diff("repo", "abc123")
assert result["success"] is True
assert "---" in result["diff"]
assert result["truncated"] is False
class TestGetCommitDiffstat:
@patch("bitbucket_mcp.tools.commits.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": [
{
"old": {"path": "file.py"},
"new": {"path": "file.py"},
"status": "modified",
"lines_added": 5,
"lines_removed": 2,
}
],
"next": None,
})
result = get_commit_diffstat("repo", "abc123")
assert result["success"] is True
assert result["total_files"] == 1
assert result["total_lines_added"] == 5
assert result["total_lines_removed"] == 2
class TestListCommitStatuses:
@patch("bitbucket_mcp.tools.commits.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": [
{
"state": "SUCCESSFUL",
"key": "build-123",
"name": "CI Build",
"description": "Build passed",
"url": "https://ci.example.com/123",
"created_on": "2025-01-01",
"updated_on": "2025-01-01",
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = list_commit_statuses("repo", "abc123")
assert result["success"] is True
assert len(result["statuses"]) == 1
assert result["statuses"][0]["state"] == "SUCCESSFUL"
assert result["statuses"][0]["key"] == "build-123"
class TestCreateBuildStatus:
@patch("bitbucket_mcp.tools.commits.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, {
"state": "SUCCESSFUL",
"key": "build-123",
"name": "CI Build",
"description": "Build passed",
"url": "https://ci.example.com/123",
"created_on": "2025-01-01",
})
result = create_build_status("repo", "abc123", "SUCCESSFUL", "build-123")
assert result["success"] is True
assert result["state"] == "SUCCESSFUL"
assert result["key"] == "build-123"
class TestListCommitComments:
@patch("bitbucket_mcp.tools.commits.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": [
{
"id": 1,
"content": {"raw": "Nice change!"},
"user": {"display_name": "Reviewer"},
"created_on": "2025-01-01",
"updated_on": "2025-01-01",
"inline": None,
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = list_commit_comments("repo", "abc123")
assert result["success"] is True
assert len(result["comments"]) == 1
assert result["comments"][0]["content"] == "Nice change!"
@patch("bitbucket_mcp.tools.commits.httpx.Client")
def test_with_inline_comment(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": [
{
"id": 2,
"content": {"raw": "Fix this line"},
"user": {"display_name": "Reviewer"},
"created_on": "2025-01-01",
"updated_on": "2025-01-01",
"inline": {
"path": "file.py",
"from": 10,
"to": 15,
},
}
],
"size": 1, "page": 1, "pagelen": 25,
})
result = list_commit_comments("repo", "abc123")
assert result["success"] is True
assert result["comments"][0]["inline"]["path"] == "file.py"