diff --git a/backend/app/api_deployment.py b/backend/app/api_deployment.py index a501ce6..d53dc4e 100644 --- a/backend/app/api_deployment.py +++ b/backend/app/api_deployment.py @@ -54,7 +54,10 @@ def make_router() -> APIRouter: ).fetchone() if row is None: raise HTTPException(status_code=404, detail="Not found") - cfg = json.loads(row["config_json"] or "{}") + try: + cfg = json.loads(row["config_json"] or "{}") + except (ValueError, TypeError): + cfg = {} dep = db.conn().execute("SELECT tagline FROM deployment WHERE id = 1").fetchone() return { "id": row["id"], diff --git a/backend/tests/test_api_deployment.py b/backend/tests/test_api_deployment.py index ce9d3a1..ea72f94 100644 --- a/backend/tests/test_api_deployment.py +++ b/backend/tests/test_api_deployment.py @@ -76,3 +76,22 @@ def test_projects_id_unknown_returns_404_for_anon(app_with_fake_gitea): app, _ = app_with_fake_gitea with TestClient(app) as client: assert client.get("/api/projects/nope").status_code == 404 + + +def test_gated_project_visible_and_readable_to_member(app_with_fake_gitea): + from app import db + app, _ = app_with_fake_gitea + with TestClient(app) as client: + _add_project("teamx", "Team X", "gated") + provision_user_row(user_id=5, login="mia", role="contributor") + db.conn().execute( + "INSERT INTO project_members (project_id, user_id, role) VALUES ('teamx', 5, 'project_viewer')" + ) + sign_in_as(client, user_id=5, gitea_login="mia", display_name="Mia", role="contributor") + # member sees the gated project in the deployment directory + ids = {p["id"] for p in client.get("/api/deployment").json()["projects"]} + assert "teamx" in ids + # member can read it directly + r = client.get("/api/projects/teamx") + assert r.status_code == 200 + assert r.json()["id"] == "teamx"