From 67bd09af072dcf4d5bce98d446208299e8a52e98 Mon Sep 17 00:00:00 2001 From: leo <260626284+cameledev@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:47:46 +0200 Subject: [PATCH] wiip --- CHANGELOG.md | 2 +- src/backend/core/models.py | 3 +- src/backend/core/tests/test_models_files.py | 46 +++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/backend/core/tests/test_models_files.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 0790eda5..8fbbd031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,6 @@ and this project adheres to ### Changed -- ♻️(backend) centralize file hard deletion in the model - 📈(frontend) include LiveKit SIDs in the connection analytics event - 🔇(backend) silence expected 401 warnings on /me - 🔇(backend) silence noisy request summary info logs @@ -23,6 +22,7 @@ and this project adheres to - ⬆️(frontend) upgrade posthog-js from 1.414.0 to 1.418.10 - ⬆️(addons) upgrade i18next from 26.3.6 to 26.4.0 - ⬆️(frontend) upgrade humanize-duration from 3.33.2 to 3.34.1 +- ♻️(backend) delete files synchronously ### Fixed diff --git a/src/backend/core/models.py b/src/backend/core/models.py index 3924cf63..bd9b3101 100644 --- a/src/backend/core/models.py +++ b/src/backend/core/models.py @@ -1040,5 +1040,6 @@ class File(BaseModel): def delete(self, using=None, keep_parents=False): """Remove the file from the database, then from storage once committed.""" key = self.file_key - super().delete(using, keep_parents) + result = super().delete(using, keep_parents) transaction.on_commit(lambda: default_storage.delete(key)) + return result diff --git a/src/backend/core/tests/test_models_files.py b/src/backend/core/tests/test_models_files.py new file mode 100644 index 00000000..4bd613b3 --- /dev/null +++ b/src/backend/core/tests/test_models_files.py @@ -0,0 +1,46 @@ +""" +Unit tests for the File model deletion flow +""" + +from django.core.files.storage import default_storage +from django.utils import timezone + +import pytest + +from core.factories import FileFactory +from core.models import File + +pytestmark = pytest.mark.django_db + + +def test_models_files_soft_delete(): + """Soft deleting should only set the deletion timestamp.""" + file = FileFactory() + assert file.is_deleted is False + + file.soft_delete() + + file.refresh_from_db() + assert file.is_deleted is True + assert FileFactory(deleted_at=timezone.now()).is_deleted is True + + +def test_models_files_soft_delete_twice(): + """Soft deleting an already soft deleted file should fail.""" + file = FileFactory() + file.soft_delete() + + with pytest.raises(RuntimeError, match="already deleted"): + file.soft_delete() + + +@pytest.mark.django_db(transaction=True) +def test_models_files_delete(): + """Deleting should remove the row and the content from storage.""" + file = FileFactory(upload_bytes=b"hello") + key = file.file_key + + file.delete() + + assert not File.objects.filter(pk=file.pk).exists() + assert not default_storage.exists(key)