diff --git a/src/main.py b/src/main.py index 3128139..6f12139 100644 --- a/src/main.py +++ b/src/main.py @@ -104,6 +104,7 @@ async def context() -> JSONResponse: Repo(id=r["id"], name=r["name"], full_name=r["full_name"], description=r.get("description") or "", url=r["html_url"], updated_at=r.get("updated_at", "")) for r in (repo_data or [])[:50] if isinstance(r, dict) + and all(field in r for field in ("id", "name", "full_name", "html_url")) ] issue_models = [ Issue(id=i["id"], number=i["number"], title=i["title"], state=i["state"], labels=[l.get("name", "") for l in (i.get("labels") or [])], assignees=[a.get("login", "") for a in (i.get("assignees") or [])], url=i["html_url"]) diff --git a/tests/test_context_timeout.py b/tests/test_context_timeout.py index ea7bff2..84976ed 100644 --- a/tests/test_context_timeout.py +++ b/tests/test_context_timeout.py @@ -188,3 +188,34 @@ async def test_context_returns_fallback_for_null_current_user_payload(monkeypatc assert response.status_code == 200 assert context["repos"] == [] assert context["error"] == "Gitea current-user response was not an object" + + +@pytest.mark.anyio +async def test_context_skips_malformed_repository_entries(monkeypatch): + async def user(): + return {"id": 1, "login": "timmy"} + + async def repository_collection(): + return [ + {"id": 79, "name": "missing-required-fields"}, + { + "id": 1, + "name": "dashboard", + "full_name": "stackchain/dashboard", + "description": "Operations dashboard", + "html_url": "https://forge.example/stackchain/dashboard", + }, + ] + + async def empty_collection(): + return [] + + monkeypatch.setattr(main, "current_user", user) + monkeypatch.setattr(main, "repos", repository_collection) + monkeypatch.setattr(main, "issues", empty_collection) + monkeypatch.setattr(main, "pull_requests", empty_collection) + + response = await main.context() + repositories = json.loads(response.body)["repos"] + + assert [repository["name"] for repository in repositories] == ["dashboard"]