test: add 106 unit + smoke tests, 93% coverage
- pytest + respx + pytest-cov added as dev dependencies - tests/smoke/test_registration.py: verify all 66 tools registered and unique - tests/unit/: 12 files covering every tool — HTTP method, URL, params/body, errors - tests/config.test.json + conftest.py: zero-network test setup via GITEA_CONFIG - CLAUDE.md: developer guide with testing philosophy, pyramid, and commands - server/gitea_mcp.py: get_commit, list_pr_files tools added - README.md: tool count corrected to 66
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import pytest
|
||||
import httpx
|
||||
import respx
|
||||
from server.gitea_mcp import list_commits, get_commit, compare_branches, list_repo_contributors
|
||||
|
||||
BASE = "https://gitea.test/api/v1"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_list_commits_defaults():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/commits").mock(
|
||||
return_value=httpx.Response(200, json=[{"sha": "abc123"}])
|
||||
)
|
||||
result = list_commits("owner", "repo")
|
||||
assert route.called
|
||||
params = dict(route.calls[0].request.url.params)
|
||||
assert params["limit"] == "20"
|
||||
assert params["page"] == "1"
|
||||
assert "sha" not in params
|
||||
assert "path" not in params
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_list_commits_on_branch_and_path():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/commits").mock(
|
||||
return_value=httpx.Response(200, json=[])
|
||||
)
|
||||
list_commits("owner", "repo", sha="develop", path="server/gitea_mcp.py")
|
||||
params = dict(route.calls[0].request.url.params)
|
||||
assert params["sha"] == "develop"
|
||||
assert params["path"] == "server/gitea_mcp.py"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_get_commit():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/git/commits/abc123").mock(
|
||||
return_value=httpx.Response(200, json={"sha": "abc123", "commit": {"message": "fix bug"}})
|
||||
)
|
||||
result = get_commit("owner", "repo", "abc123")
|
||||
assert route.called
|
||||
assert result["sha"] == "abc123"
|
||||
params = dict(route.calls[0].request.url.params)
|
||||
assert params["stat"] == "true"
|
||||
assert params["files"] == "true"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_get_commit_without_stat():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/git/commits/deadbeef").mock(
|
||||
return_value=httpx.Response(200, json={"sha": "deadbeef"})
|
||||
)
|
||||
get_commit("owner", "repo", "deadbeef", stat=False, files=False)
|
||||
params = dict(route.calls[0].request.url.params)
|
||||
assert params["stat"] == "false"
|
||||
assert params["files"] == "false"
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_get_commit_not_found():
|
||||
respx.get(f"{BASE}/repos/owner/repo/git/commits/notacommit").mock(
|
||||
return_value=httpx.Response(404, json={"message": "not found"})
|
||||
)
|
||||
with pytest.raises(RuntimeError, match="404"):
|
||||
get_commit("owner", "repo", "notacommit")
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_compare_branches():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/compare/main...develop").mock(
|
||||
return_value=httpx.Response(200, json={"total_commits": 3, "commits": []})
|
||||
)
|
||||
result = compare_branches("owner", "repo", "main", "develop")
|
||||
assert route.called
|
||||
assert result["total_commits"] == 3
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_compare_branches_with_slashes():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/compare/release%2F1.0...feature%2Fnew").mock(
|
||||
return_value=httpx.Response(200, json={"total_commits": 1})
|
||||
)
|
||||
result = compare_branches("owner", "repo", "release/1.0", "feature/new")
|
||||
assert route.called
|
||||
|
||||
|
||||
@respx.mock
|
||||
def test_list_repo_contributors():
|
||||
route = respx.get(f"{BASE}/repos/owner/repo/contributors").mock(
|
||||
return_value=httpx.Response(200, json=[{"login": "alice", "contributions": 42}])
|
||||
)
|
||||
result = list_repo_contributors("owner", "repo")
|
||||
assert route.called
|
||||
assert result[0]["login"] == "alice"
|
||||
assert dict(route.calls[0].request.url.params)["limit"] == "20"
|
||||
Reference in New Issue
Block a user