#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Test P2: collegamento progetti MCP ↔ repository Gitea.""" from __future__ import annotations import json import os import shutil import sys import tempfile ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) if ROOT not in sys.path: sys.path.insert(0, ROOT) os.environ["MCP_DB"] = "/tmp/loogle_mcp_p2_test.db" TEST_ROOT = tempfile.mkdtemp(prefix="mcp-p2-") def _load_dotenv() -> None: env_path = os.path.join(ROOT, ".env") if not os.path.isfile(env_path): return with open(env_path, encoding="utf-8") as fh: for line in fh: line = line.strip() if not line or line.startswith("#") or "=" not in line: continue key, _, value = line.partition("=") os.environ.setdefault(key.strip(), value.strip().strip("'").strip('"')) def run_unit_tests() -> None: os.environ["MCP_CONTEXT_ROOT"] = TEST_ROOT from app.db import init_db from app.context import store as context_store from app.mcp import tools init_db() claims = { "sub": "daniele", "scope": "context:read context:write gitea:read gitea:write", } meta = context_store.create_project( "daniele", "Progetto unit test", tags=["test"], ) meta_path = os.path.join(TEST_ROOT, "daniele", "projects", meta["id"], "meta.json") meta["gitea_repo"] = "daniele/rete" with open(meta_path, "w", encoding="utf-8") as f: json.dump(meta, f, ensure_ascii=False, indent=2) ctx = tools.call_tool( "get_project_context", {"project_id": meta["id"], "include_gitea": False}, claims, ) payload = json.loads(ctx["content"][0]["text"]) assert payload["meta"]["gitea_repo"] == "daniele/rete" unlinked = tools.call_tool( "link_project_repo", {"project_id": meta["id"], "gitea_repo": ""}, claims, ) payload = json.loads(unlinked["content"][0]["text"]) assert "gitea_repo" not in payload print("OK unit: meta gitea_repo + scollegamento locale") def run_live_tests() -> None: _load_dotenv() token = os.environ.get("GITEA_API_TOKEN_DANIELE", "").strip() if not token: print("SKIP live: GITEA_API_TOKEN_DANIELE assente") return live_root = os.path.join(TEST_ROOT, "live") os.makedirs(live_root, exist_ok=True) os.environ["MCP_CONTEXT_ROOT"] = live_root from app.context import store as context_store from app.mcp import tools from app.knowledge import gitea gitea._tokens_cache = None claims = { "sub": "daniele", "scope": "context:read context:write gitea:read gitea:write", } project_id = "rete-ha-p2-test" proj_dir = os.path.join(live_root, "daniele", "projects", project_id) if os.path.isdir(proj_dir): shutil.rmtree(proj_dir) created = tools.call_tool( "create_project", { "title": "Rete HA P2 test", "tags": ["infra", "test"], "gitea_repo": "daniele/rete", "seed_from_gitea": True, }, claims, ) payload = json.loads(created["content"][0]["text"]) project_id = payload["id"] assert payload.get("gitea_repo") == "daniele/rete" assert payload.get("gitea_seeded_at") ctx_path = os.path.join(live_root, "daniele", "projects", project_id, "context.md") context_md = open(ctx_path, encoding="utf-8").read() assert "seed:gitea daniele/rete" in context_md assert len(context_md) > 200 enriched = tools.call_tool( "get_project_context", {"project_id": project_id, "include_gitea": True, "session_limit": 0}, claims, ) data = json.loads(enriched["content"][0]["text"]) assert data["meta"]["gitea_repo"] == "daniele/rete" assert data["gitea"]["available"] is True assert data["gitea"]["readme"] is not None assert isinstance(data["gitea"].get("docs_files"), list) link_existing = tools.call_tool( "link_project_repo", {"project_id": project_id, "gitea_repo": "daniele/rete", "seed_from_gitea": True}, claims, ) meta2 = json.loads(link_existing["content"][0]["text"]) assert "gitea_seeded_at" in meta2 shutil.rmtree(proj_dir) print(f"OK live: create+seed+enrichment su daniele/rete (project {project_id})") def main() -> int: try: run_unit_tests() run_live_tests() return 0 finally: shutil.rmtree(TEST_ROOT, ignore_errors=True) if __name__ == "__main__": raise SystemExit(main())