GooDrive/backend/drive/test_empty_trash.py
Louis Mazin 17afb70810 super
2026-10-14 18:51:52 +02:00

84 lines
4.2 KiB
Python

"""USE_SQLITE=true python manage.py test drive.test_empty_trash"""
import tempfile
from pathlib import Path
from uuid import uuid4
from django.contrib.auth import get_user_model
from django.test import TestCase, override_settings
from django.utils import timezone
from rest_framework.test import APIClient
from .models import DriveItem, SpaceGrant
from .spaces import ensure_private_space, ensure_space
from .storage_layout import disk_path
class EmptyTrashTests(TestCase):
def setUp(self):
temp = tempfile.TemporaryDirectory()
self.addCleanup(temp.cleanup)
root = Path(temp.name)
config = override_settings(DRIVE_STORAGE_ROOT=root, FILE_UPLOAD_TEMP_DIR=str(root / '.tmp'))
config.enable()
self.addCleanup(config.disable)
self.admin = get_user_model().objects.create_superuser('admin-trash', 'admin@example.org', 'pass')
self.other = get_user_model().objects.create_user('private-owner', password='pass')
self.shared = ensure_space(self.admin)
SpaceGrant.objects.create(user=self.other, space=self.shared, permissions=['view', 'download'])
self.private = ensure_private_space(self.other)
self.client = APIClient()
self.client.force_authenticate(self.admin)
def file(self, space, owner, filename, relative_location):
location = '/'.join(p for p in (space.relative_path, relative_location) if p)
path = disk_path(location)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(filename.encode())
record = DriveItem.objects.create(
space=space, owner=owner, name=filename, mime_type='text/plain',
storage_key=str(uuid4()), storage_location=location,
size=len(filename), trashed_at=timezone.now(),
)
return record, path
def test_empty_trash_removes_accessible_files_but_not_other_private_files(self):
item1, path1 = self.file(self.shared, self.admin, 'duplicata.txt', '.gooddrive-trash/id1/duplicata.txt')
item2, path2 = self.file(self.shared, self.admin, 'duplicata.txt', '.gooddrive-trash/id2/duplicata.txt')
secret, secret_path = self.file(self.private, self.other, 'prive.txt', '.gooddrive-trash/private/prive.txt')
with self.captureOnCommitCallbacks(execute=True):
response = self.client.delete('/api/drive/trash/')
self.assertEqual(response.status_code, 200, response.data)
self.assertEqual(response.data['deleted'], 2)
self.assertFalse(DriveItem.objects.filter(pk=item1.pk).exists())
self.assertFalse(DriveItem.objects.filter(pk=item2.pk).exists())
self.assertTrue(DriveItem.objects.filter(pk=secret.pk).exists())
self.assertFalse(path1.exists())
self.assertFalse(path2.exists())
self.assertTrue(secret_path.exists())
def test_empty_trash_requires_authentication(self):
self.client.force_authenticate(user=None)
response = self.client.delete('/api/drive/trash/')
self.assertEqual(response.status_code, 401)
def test_empty_trash_never_deletes_active_files(self):
active, path = self.file(self.shared, self.admin, 'actif.txt', 'actif.txt')
DriveItem.objects.filter(pk=active.pk).update(trashed_at=None)
response = self.client.delete('/api/drive/trash/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['deleted'], 0)
self.assertTrue(path.exists())
self.assertTrue(DriveItem.objects.filter(pk=active.pk).exists())
def test_reader_cannot_empty_trash(self):
reader = get_user_model().objects.create_user('reader', password='pass')
SpaceGrant.objects.create(user=reader, space=self.shared, permissions=['view', 'download'])
item, path = self.file(self.shared, self.admin, 'lecture.txt', '.gooddrive-trash/reader/lecture.txt')
self.client.force_authenticate(reader)
response = self.client.delete('/api/drive/trash/')
self.assertEqual(response.status_code, 200, response.data)
self.assertEqual(response.data['deleted'], 0)
self.assertEqual(response.data['skipped'], 1)
self.assertTrue(path.exists())
self.assertTrue(DriveItem.objects.filter(pk=item.pk).exists())