From cfd1fd00dac221cd6c714c9475716e7f8239d5d6 Mon Sep 17 00:00:00 2001 From: Mohamed El Amine BOUKERFA Date: Tue, 28 Apr 2026 15:53:30 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(backend)=20Forbid=20restoring=20a?= =?UTF-8?q?=20non-deleted=20document?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Catch RuntimeError raised by Document.restore() and translate it into a DRF ValidationError so callers get a 400 instead of a 500, when trying to restore a non-deleted document. Signed-off-by: Mohamed El Amine BOUKERFA --- CHANGELOG.md | 1 + src/backend/core/api/viewsets.py | 5 ++++- .../documents/test_api_documents_restore.py | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a881c139..415bf128f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to - 🛂(frontend) fix cannot manage member on small screen #2226 - 🐛(backend) load jwks url when OIDC_RS_PRIVATE_KEY_STR is set - 🐛(backend) Prevent moving document to its own descendant or self #2208 +- 🐛(backend) return 400 when restoring a non-deleted document #2225 ### Removed diff --git a/src/backend/core/api/viewsets.py b/src/backend/core/api/viewsets.py index e9406cd40..8298f211f 100644 --- a/src/backend/core/api/viewsets.py +++ b/src/backend/core/api/viewsets.py @@ -996,7 +996,10 @@ class DocumentViewSet( Restore a soft-deleted document if it was deleted less than x days ago. """ document = self.get_object() - document.restore() + try: + document.restore() + except RuntimeError as err: + raise drf.exceptions.ValidationError({"detail": str(err)}) from err return drf_response.Response( {"detail": "Document has been successfully restored."}, diff --git a/src/backend/core/tests/documents/test_api_documents_restore.py b/src/backend/core/tests/documents/test_api_documents_restore.py index 5ae64aec1..93a088864 100644 --- a/src/backend/core/tests/documents/test_api_documents_restore.py +++ b/src/backend/core/tests/documents/test_api_documents_restore.py @@ -124,3 +124,22 @@ def test_api_documents_restore_authenticated_owner_expired(): assert response.status_code == 404 assert response.json() == {"detail": "Not found."} + + +def test_api_documents_restore_authenticated_owner_not_deleted(): + """Restoring a document that is not deleted should return a 400 error.""" + user = factories.UserFactory() + client = APIClient() + client.force_login(user) + + document = factories.DocumentFactory() + factories.UserDocumentAccessFactory(document=document, user=user, role="owner") + + response = client.post(f"/api/v1.0/documents/{document.id!s}/restore/") + + assert response.status_code == 400 + assert response.json() == {"detail": "This document is not deleted."} + + document.refresh_from_db() + assert document.deleted_at is None + assert document.ancestors_deleted_at is None