"""Integration tests for generation API endpoints. Tests key generation endpoints with mocked services. """ from datetime import datetime from unittest.mock import AsyncMock, patch from uuid import uuid4 import pytest from fastapi.testclient import TestClient from notebooklm_agent.api.main import app from notebooklm_agent.api.models.responses import Artifact, GenerationResponse @pytest.mark.unit class TestGenerateAudioEndpoint: """Test suite for POST /generate/audio endpoint.""" def test_generate_audio_returns_202(self): """Should return 202 Accepted for audio generation.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) artifact_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_response = GenerationResponse( artifact_id=artifact_id, status="processing", message="Audio generation started", estimated_time_seconds=600, ) mock_service.generate_audio.return_value = mock_response mock_service_class.return_value = mock_service # Act response = client.post( f"/api/v1/notebooks/{notebook_id}/generate/audio", json={ "instructions": "Make it engaging", "format": "deep-dive", "length": "long", "language": "en", }, ) # Assert assert response.status_code == 202 data = response.json() assert data["success"] is True assert data["data"]["status"] == "processing" assert data["data"]["estimated_time_seconds"] == 600 def test_generate_audio_invalid_notebook_returns_400(self): """Should return 400 for invalid notebook ID.""" # Arrange client = TestClient(app) # Act response = client.post( "/api/v1/notebooks/invalid-id/generate/audio", json={"format": "deep-dive"}, ) # Assert assert response.status_code in [400, 422] @pytest.mark.unit class TestGenerateQuizEndpoint: """Test suite for POST /generate/quiz endpoint.""" def test_generate_quiz_returns_202(self): """Should return 202 Accepted for quiz generation.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) artifact_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_response = GenerationResponse( artifact_id=artifact_id, status="processing", message="Quiz generation started", estimated_time_seconds=600, ) mock_service.generate_quiz.return_value = mock_response mock_service_class.return_value = mock_service # Act response = client.post( f"/api/v1/notebooks/{notebook_id}/generate/quiz", json={"difficulty": "medium", "quantity": "standard"}, ) # Assert assert response.status_code == 202 data = response.json() assert data["success"] is True @pytest.mark.unit class TestGenerateMindMapEndpoint: """Test suite for POST /generate/mind-map endpoint.""" def test_generate_mind_map_returns_202(self): """Should return 202 Accepted for mind map generation.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) artifact_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_response = GenerationResponse( artifact_id=artifact_id, status="completed", message="Mind map generated", estimated_time_seconds=10, ) mock_service.generate_mind_map.return_value = mock_response mock_service_class.return_value = mock_service # Act response = client.post(f"/api/v1/notebooks/{notebook_id}/generate/mind-map") # Assert assert response.status_code == 202 data = response.json() assert data["data"]["status"] == "completed" @pytest.mark.unit class TestListArtifactsEndpoint: """Test suite for GET /artifacts endpoint.""" def test_list_artifacts_returns_200(self): """Should return 200 with list of artifacts.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_artifact = Artifact( id=uuid4(), notebook_id=notebook_id, type="audio", title="Podcast", status="completed", created_at=datetime.utcnow(), completed_at=datetime.utcnow(), download_url="https://example.com/download", ) mock_service.list_artifacts.return_value = [mock_artifact] mock_service_class.return_value = mock_service # Act response = client.get(f"/api/v1/notebooks/{notebook_id}/artifacts") # Assert assert response.status_code == 200 data = response.json() assert data["success"] is True assert len(data["data"]["items"]) == 1 assert data["data"]["items"][0]["type"] == "audio" def test_list_artifacts_empty_returns_empty_list(self): """Should return empty list if no artifacts.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_service.list_artifacts.return_value = [] mock_service_class.return_value = mock_service # Act response = client.get(f"/api/v1/notebooks/{notebook_id}/artifacts") # Assert assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["data"]["items"] == [] @pytest.mark.unit class TestGetArtifactStatusEndpoint: """Test suite for GET /artifacts/{id}/status endpoint.""" def test_get_artifact_status_returns_200(self): """Should return 200 with artifact status.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) artifact_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() mock_artifact = Artifact( id=artifact_id, notebook_id=notebook_id, type="video", title="Video", status="processing", created_at=datetime.utcnow(), completed_at=None, download_url=None, ) mock_service.get_status.return_value = mock_artifact mock_service_class.return_value = mock_service # Act response = client.get(f"/api/v1/notebooks/{notebook_id}/artifacts/{artifact_id}/status") # Assert assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["data"]["status"] == "processing" def test_get_artifact_status_not_found_returns_404(self): """Should return 404 when artifact not found.""" # Arrange client = TestClient(app) notebook_id = str(uuid4()) artifact_id = str(uuid4()) with patch("notebooklm_agent.api.routes.generation.ArtifactService") as mock_service_class: mock_service = AsyncMock() from notebooklm_agent.core.exceptions import NotFoundError mock_service.get_status.side_effect = NotFoundError("Artifact", artifact_id) mock_service_class.return_value = mock_service # Act response = client.get(f"/api/v1/notebooks/{notebook_id}/artifacts/{artifact_id}/status") # Assert assert response.status_code == 404