from fastapi.testclient import TestClient import os import sys import pytest import base64 # Add app to path sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from app.main import app from app.config import API_KEY client = TestClient(app) # Minimal valid MP3 for testing VALID_MP3_B64 = "SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU4Ljc2LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAEAAABIADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDB/wAAAP7AAAAAAAAAAABMYW1lMzkuOTUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAEAAABIADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDB/wAAAP7AAAAAAAAAAABMYW1lMzkuOTUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" def test_health_check(): response = client.get("/health") assert response.status_code == 200 assert response.json() == {"status": "healthy", "service": "voice-detection-api"} def test_auth_failure(): response = client.post("/api/voice-detection", json={}) assert response.status_code == 403 assert response.json()["status"] == "error" def test_invalid_input_structure(): headers = {"x-api-key": API_KEY} response = client.post("/api/voice-detection", json={"wrong": "field"}, headers=headers) assert response.status_code == 400 assert response.json()["status"] == "error" def test_valid_prediction_flow(): # This uses a mocked/random model since weights might be missing # But verifies the pipeline runs end-to-end headers = {"x-api-key": API_KEY} payload = { "language": "English", "audioFormat": "mp3", "audioBase64": VALID_MP3_B64 } # We expect either success or a specific decoding error, but NOT 500 response = client.post("/api/voice-detection", json=payload, headers=headers) # If 500, test fails. If 400 (decoding), it verifies error handling. # Ideally 200. if response.status_code == 200: data = response.json() assert data["status"] == "success" assert "confidenceScore" in data assert "explanation" in data assert data["classification"] in ["AI_GENERATED", "HUMAN"] elif response.status_code == 400: # Acceptable if the minimal MP3 is too short for Librosa but handled gracefully assert response.json()["status"] == "error" else: pytest.fail(f"Unexpected status code: {response.status_code}") def test_invalid_language(): headers = {"x-api-key": API_KEY} payload = { "language": "French", # Not supported "audioFormat": "mp3", "audioBase64": VALID_MP3_B64 } response = client.post("/api/voice-detection", json=payload, headers=headers) assert response.status_code == 400 assert "Invalid language" in response.json()["message"]