diff --git a/src/repo_registry/web_ui/views.py b/src/repo_registry/web_ui/views.py
index 8ed4a01..4d6dbaa 100644
--- a/src/repo_registry/web_ui/views.py
+++ b/src/repo_registry/web_ui/views.py
@@ -3,10 +3,11 @@ from __future__ import annotations
from dataclasses import asdict
from html import escape
-from fastapi import APIRouter, Depends, Form
+from fastapi import APIRouter, Depends, Form, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from repo_registry.core.service import RegistryService
+from repo_registry.storage.sqlite import NotFoundError
from repo_registry.web_api.app import get_service
@@ -264,7 +265,10 @@ def repository_detail(
repository_id: int,
service: RegistryService = Depends(get_service),
) -> HTMLResponse:
- repository = service.get_repository(repository_id)
+ try:
+ repository = service.get_repository(repository_id)
+ except NotFoundError as exc:
+ raise HTTPException(status_code=404, detail=str(exc)) from exc
runs = service.list_analysis_runs(repository_id)
ability_map = service.ability_map(repository_id)
decisions = service.list_review_decisions(repository_id)
@@ -358,6 +362,13 @@ def repository_detail(
Review Decisions
{render_review_decisions(decisions)}
+
"""
return page(repository.name, body)
@@ -379,6 +390,19 @@ def edit_repository_from_form(
return RedirectResponse(f"/ui/repos/{repository_id}", status_code=303)
+@router.post("/ui/repos/{repository_id}/delete")
+def delete_repository_from_form(
+ repository_id: int,
+ confirm_name: str = Form(...),
+ service: RegistryService = Depends(get_service),
+) -> RedirectResponse:
+ repository = service.get_repository(repository_id)
+ if confirm_name != repository.name:
+ return RedirectResponse(f"/ui/repos/{repository_id}", status_code=303)
+ service.delete_repository(repository_id)
+ return RedirectResponse("/ui", status_code=303)
+
+
@router.post("/ui/repos/{repository_id}/abilities")
def create_ability_from_form(
repository_id: int,
diff --git a/tests/test_web_api.py b/tests/test_web_api.py
index 3bd6bd5..8a67465 100644
--- a/tests/test_web_api.py
+++ b/tests/test_web_api.py
@@ -594,6 +594,23 @@ def test_ui_manual_registry_entry_loop(tmp_path):
detail_response = client.get(repository_path)
assert "Edited Manual API" not in detail_response.text
assert "tests/test_manual.py" not in detail_response.text
+
+ failed_delete_response = client.post(
+ f"{repository_path}/delete",
+ data={"confirm_name": "wrong name"},
+ follow_redirects=False,
+ )
+ assert failed_delete_response.status_code == 303
+ assert client.get(repository_path).status_code == 200
+
+ delete_repository_response = client.post(
+ f"{repository_path}/delete",
+ data={"confirm_name": "Manual Repo"},
+ follow_redirects=False,
+ )
+ assert delete_repository_response.status_code == 303
+ assert delete_repository_response.headers["location"] == "/ui"
+ assert client.get(repository_path).status_code == 404
finally:
app.dependency_overrides.clear()