Files
a-limasov-ii db5a43b19a refactor: make gitea a self-contained Cline skill
Relocate the script into the skill (skills/gitea/scripts/gitea_mcp.py) and add a
PEP 723 dependency block, so `uv run scripts/gitea_mcp.py` provisions deps with no
install step and the skill folder is portable (drop into ~/.cline/skills/). Drop
the non-standard `metadata` frontmatter — Cline only recognizes name + description.

- .mcp.json points at the relocated script and runs with --no-project (PEP 723)
- SKILL.md uses relative scripts/ paths; metadata block removed
- find_config walks up the tree to locate config.json (skill root or plugin root)
- tests import gitea_mcp via pytest pythonpath; README/CLAUDE paths updated

Tests: 119 passed, 92% coverage. Standalone list-tools verified via uv --no-project.
2026-06-24 14:35:28 +03:00

91 lines
2.4 KiB
Python

import pytest
import httpx
import respx
from gitea_mcp import (
get_user, search_users, list_my_orgs, get_org,
list_org_repos, list_org_members, list_org_teams,
)
BASE = "https://gitea.test/api/v1"
@respx.mock
def test_get_user():
route = respx.get(f"{BASE}/users/alice").mock(
return_value=httpx.Response(200, json={"login": "alice", "id": 42})
)
result = get_user("alice")
assert route.called
assert result["login"] == "alice"
@respx.mock
def test_get_user_not_found():
respx.get(f"{BASE}/users/nobody").mock(
return_value=httpx.Response(404, json={"message": "not found"})
)
with pytest.raises(RuntimeError, match="404"):
get_user("nobody")
@respx.mock
def test_search_users():
route = respx.get(f"{BASE}/users/search").mock(
return_value=httpx.Response(200, json={"data": [{"login": "alice"}]})
)
result = search_users("ali")
assert route.called
params = dict(route.calls[0].request.url.params)
assert params["q"] == "ali"
assert params["limit"] == "10"
@respx.mock
def test_list_my_orgs():
route = respx.get(f"{BASE}/user/orgs").mock(
return_value=httpx.Response(200, json=[{"name": "myorg"}])
)
result = list_my_orgs()
assert route.called
assert result[0]["name"] == "myorg"
@respx.mock
def test_get_org():
route = respx.get(f"{BASE}/orgs/myorg").mock(
return_value=httpx.Response(200, json={"name": "myorg", "full_name": "My Org"})
)
result = get_org("myorg")
assert route.called
assert result["name"] == "myorg"
@respx.mock
def test_list_org_repos():
route = respx.get(f"{BASE}/orgs/myorg/repos").mock(
return_value=httpx.Response(200, json=[{"name": "repo1"}])
)
result = list_org_repos("myorg")
assert route.called
assert dict(route.calls[0].request.url.params)["limit"] == "50"
@respx.mock
def test_list_org_members():
route = respx.get(f"{BASE}/orgs/myorg/members").mock(
return_value=httpx.Response(200, json=[{"login": "bob"}])
)
result = list_org_members("myorg")
assert route.called
assert result[0]["login"] == "bob"
@respx.mock
def test_list_org_teams():
route = respx.get(f"{BASE}/orgs/myorg/teams").mock(
return_value=httpx.Response(200, json=[{"id": 1, "name": "developers"}])
)
result = list_org_teams("myorg")
assert route.called
assert result[0]["name"] == "developers"