"""API tests for the exports endpoint. These tests verify: - The /api/exports endpoint returns exports for the current user - Export records are properly created when exporting """ from typing import Optional from galaxy_test.base.api import UsesCeleryTasks from galaxy_test.base.populators import ( DatasetPopulator, WorkflowPopulator, ) from galaxy_test.base.workflow_fixtures import WORKFLOW_SIMPLE_CAT_TWICE from ._framework import ApiTestCase class TestExportsEndpoint(ApiTestCase, UsesCeleryTasks): """Tests for the /api/exports endpoint.""" dataset_populator: DatasetPopulator workflow_populator: WorkflowPopulator def setUp(self): super().setUp() self.dataset_populator = DatasetPopulator(self.galaxy_interactor) self.workflow_populator = WorkflowPopulator(self.galaxy_interactor) def _find_export_by_object_id(self, exports: list, object_id: str) -> Optional[dict]: """Find an export record by its object_id in the metadata.""" for export in exports: metadata = export.get("export_metadata", {}) request_data = metadata.get("request_data", {}) if request_data.get("object_id") == object_id: return export return None def _create_history_export(self, history_id: str) -> str: """Create a history export and wait for it to complete. Returns storage_request_id.""" export_response = self._post( f"histories/{history_id}/prepare_store_download", data={ "model_store_format": "tar.gz", "include_files": True, }, json=True, ) assert export_response.status_code == 200, export_response.text result = export_response.json() storage_request_id = result.get("storage_request_id") assert storage_request_id, "Expected storage_request_id in response" self.dataset_populator.wait_for_download_ready(storage_request_id) return storage_request_id def test_exports_endpoint_with_history_export(self): """Test that exports endpoint returns history exports via prepare_download.""" with self.dataset_populator.test_history() as history_id: self.dataset_populator.new_dataset(history_id, content="test content", wait=True) self._create_history_export(history_id) response = self._get("exports") assert response.status_code == 200 exports = response.json() # Find the specific export for our history export_record = self._find_export_by_object_id(exports, history_id) assert export_record is not None, f"Export for history {history_id} not found in {exports}" # Verify export record structure assert "id" in export_record assert "task_uuid" in export_record assert "create_time" in export_record assert "export_metadata" in export_record # Verify metadata metadata = export_record["export_metadata"] assert metadata["request_data"]["object_type"] == "history" assert metadata["request_data"]["object_id"] == history_id def test_exports_endpoint_with_invocation_export(self): """Test that exports endpoint returns invocation exports via prepare_store_download.""" with self.dataset_populator.test_history() as history_id: summary = self.workflow_populator.run_workflow( WORKFLOW_SIMPLE_CAT_TWICE, test_data={"input1": "hello world"}, history_id=history_id, wait=True, assert_ok=True, ) invocation_id = summary.invocation_id export_response = self._post( f"invocations/{invocation_id}/prepare_store_download", data={ "model_store_format": "tar.gz", "include_files": False, }, json=True, ) assert export_response.status_code == 200, export_response.text result = export_response.json() storage_request_id = result.get("storage_request_id") assert storage_request_id, "Expected storage_request_id in response" self.dataset_populator.wait_for_download_ready(storage_request_id) response = self._get("exports") assert response.status_code == 200 exports = response.json() # Find the specific export for our invocation export_record = self._find_export_by_object_id(exports, invocation_id) assert export_record is not None, f"Export for invocation {invocation_id} not found in {exports}" # Verify export record structure assert "id" in export_record assert "task_uuid" in export_record assert "export_metadata" in export_record # Verify metadata metadata = export_record["export_metadata"] assert metadata["request_data"]["object_type"] == "invocation" assert metadata["request_data"]["object_id"] == invocation_id def test_exports_endpoint_respects_limit(self): """Test that exports endpoint respects the limit parameter.""" with self.dataset_populator.test_history() as history_id: self.dataset_populator.new_dataset(history_id, content="test content", wait=True) # Create two exports self._create_history_export(history_id) self._create_history_export(history_id) # Verify we have at least 2 exports all_response = self._get("exports") assert all_response.status_code == 200 all_exports = all_response.json() assert len(all_exports) >= 2, f"Expected at least 2 exports, got {len(all_exports)}" # Verify limit=1 returns only 1 limited_response = self._get("exports", data={"limit": 1}) assert limited_response.status_code == 200 limited_exports = limited_response.json() assert len(limited_exports) == 1, f"Expected exactly 1 export with limit=1, got {len(limited_exports)}"