generated from coulomb/repo-seed
guarded repository delete flow
This commit is contained in:
@@ -3,10 +3,11 @@ from __future__ import annotations
|
|||||||
from dataclasses import asdict
|
from dataclasses import asdict
|
||||||
from html import escape
|
from html import escape
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Form
|
from fastapi import APIRouter, Depends, Form, HTTPException
|
||||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
|
|
||||||
from repo_registry.core.service import RegistryService
|
from repo_registry.core.service import RegistryService
|
||||||
|
from repo_registry.storage.sqlite import NotFoundError
|
||||||
from repo_registry.web_api.app import get_service
|
from repo_registry.web_api.app import get_service
|
||||||
|
|
||||||
|
|
||||||
@@ -264,7 +265,10 @@ def repository_detail(
|
|||||||
repository_id: int,
|
repository_id: int,
|
||||||
service: RegistryService = Depends(get_service),
|
service: RegistryService = Depends(get_service),
|
||||||
) -> HTMLResponse:
|
) -> 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)
|
runs = service.list_analysis_runs(repository_id)
|
||||||
ability_map = service.ability_map(repository_id)
|
ability_map = service.ability_map(repository_id)
|
||||||
decisions = service.list_review_decisions(repository_id)
|
decisions = service.list_review_decisions(repository_id)
|
||||||
@@ -358,6 +362,13 @@ def repository_detail(
|
|||||||
<h2>Review Decisions</h2>
|
<h2>Review Decisions</h2>
|
||||||
{render_review_decisions(decisions)}
|
{render_review_decisions(decisions)}
|
||||||
</section>
|
</section>
|
||||||
|
<section class="panel" style="margin-top:18px">
|
||||||
|
<h2>Delete Repository</h2>
|
||||||
|
<form class="stack" method="post" action="/ui/repos/{repository_id}/delete">
|
||||||
|
<label>Confirm repository name <input name="confirm_name" placeholder="{escape(repository.name)}" required></label>
|
||||||
|
<button class="secondary" type="submit">Delete Repository</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
"""
|
"""
|
||||||
return page(repository.name, body)
|
return page(repository.name, body)
|
||||||
|
|
||||||
@@ -379,6 +390,19 @@ def edit_repository_from_form(
|
|||||||
return RedirectResponse(f"/ui/repos/{repository_id}", status_code=303)
|
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")
|
@router.post("/ui/repos/{repository_id}/abilities")
|
||||||
def create_ability_from_form(
|
def create_ability_from_form(
|
||||||
repository_id: int,
|
repository_id: int,
|
||||||
|
|||||||
@@ -594,6 +594,23 @@ def test_ui_manual_registry_entry_loop(tmp_path):
|
|||||||
detail_response = client.get(repository_path)
|
detail_response = client.get(repository_path)
|
||||||
assert "Edited Manual API" not in detail_response.text
|
assert "Edited Manual API" not in detail_response.text
|
||||||
assert "tests/test_manual.py" 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:
|
finally:
|
||||||
app.dependency_overrides.clear()
|
app.dependency_overrides.clear()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user