import pytest from django.core.files.uploadedfile import SimpleUploadedFile from infrasynth.features.models import FeatureFlag from infrasynth.files.models import FileCategory, ProcessingPipeline, StoredFile from infrasynth.files.services import FileService pytestmark = pytest.mark.django_db FILES_URL = "/api/v1/files/files/" CATEGORIES_URL = "/api/v1/files/categories/" PIPELINES_URL = "/api/v1/files/pipelines/" @pytest.fixture def stored_file(user, media_root): return FileService().upload( SimpleUploadedFile("doc.pdf", b"%PDF-1.4", content_type="application/pdf"), filename="doc.pdf", user=user, ) class TestStoredFileViewSet: def test_list_files(self, authenticated_client, stored_file): response = authenticated_client.get(FILES_URL) assert response.status_code == 200 assert response.data["count"] == 1 assert response.data["results"][0]["original_filename"] == "doc.pdf" def test_list_requires_auth(self, api_client, stored_file): assert api_client.get(FILES_URL).status_code == 401 def test_retrieve_file(self, authenticated_client, stored_file): response = authenticated_client.get(f"{FILES_URL}{stored_file.id}/") assert response.status_code == 200 assert response.data["id"] == stored_file.id assert response.data["mime_type"] == "application/pdf" def test_download_action(self, authenticated_client, stored_file): response = authenticated_client.get(f"{FILES_URL}{stored_file.id}/download/") assert response.status_code == 200 assert "attachment" in response["Content-Disposition"] assert b"".join(response.streaming_content) == b"%PDF-1.4" def test_download_requires_auth(self, api_client, stored_file): assert api_client.get(f"{FILES_URL}{stored_file.id}/download/").status_code == 401 def test_delete_file(self, authenticated_client, stored_file): response = authenticated_client.delete(f"{FILES_URL}{stored_file.id}/") assert response.status_code == 204 assert not StoredFile.objects.filter(pk=stored_file.pk).exists() def test_disabled_feature_returns_404(self, authenticated_client): FeatureFlag.objects.create(slug="files", name="Files", is_active=False) assert authenticated_client.get(FILES_URL).status_code == 404 class TestFileCategoryViewSet: def test_list_categories(self, authenticated_client): FileCategory.objects.create(slug="docs", name="Docs", storage_path="docs") response = authenticated_client.get(f"{CATEGORIES_URL}") assert response.status_code == 200 assert response.data["count"] == 1 assert response.data["results"][0]["slug"] == "docs" def test_create_category(self, authenticated_client): response = authenticated_client.post( f"{CATEGORIES_URL}", {"slug": "img", "name": "Images", "storage_path": "img"}, format="json", ) assert response.status_code == 201 assert FileCategory.objects.count() == 1 def test_requires_auth(self, api_client): assert api_client.get(f"{CATEGORIES_URL}").status_code == 401 class TestProcessingPipelineViewSet: def test_list_pipelines(self, authenticated_client): ProcessingPipeline.objects.create(name="Resize", slug="resize", steps=[]) response = authenticated_client.get(f"{PIPELINES_URL}") assert response.status_code == 200 assert response.data["count"] == 1 def test_create_pipeline(self, authenticated_client): response = authenticated_client.post( f"{PIPELINES_URL}", { "name": "Optimize", "slug": "optimize", "steps": [{"type": "optimize"}], }, format="json", ) assert response.status_code == 201 assert ProcessingPipeline.objects.filter(slug="optimize").exists() def test_requires_auth(self, api_client): assert api_client.get(f"{PIPELINES_URL}").status_code == 401