Cyril Dupland
feat transcription: implement meeting transcription quotas with project ID and duration limits, enhancing validation and quota management. Update settings and documentation to reflect new features and usage examples.
833089d | """Basic tests for the /transcription/meeting endpoint.""" | |
| from pathlib import Path | |
| from fastapi.testclient import TestClient | |
| from app import app | |
| _DIR = Path(__file__).resolve().parent | |
| def get_auth_headers() -> dict: | |
| """Helper to obtain an auth header for tests. | |
| For now we call the real /auth/token endpoint, which in this project does not | |
| require credentials and returns a short-lived JWT suitable for local tests. | |
| """ | |
| client = TestClient(app) | |
| response = client.post("/auth/token") | |
| response.raise_for_status() | |
| token = response.json()["access_token"] | |
| return {"Authorization": f"Bearer {token}"} | |
| def test_transcription_meeting_rejects_unsupported_format(tmp_path): | |
| """/transcription/meeting should reject unsupported file formats before calling OpenAI.""" | |
| client = TestClient(app) | |
| headers = get_auth_headers() | |
| # Create a small dummy text file (unsupported extension) | |
| dummy_file = tmp_path / "dummy.txt" | |
| dummy_file.write_text("not an audio file", encoding="utf-8") | |
| with dummy_file.open("rb") as f: | |
| files = {"file": ("dummy.txt", f, "text/plain")} | |
| data = {"project_id": "test-proj", "max_duration_seconds": 3600} | |
| response = client.post( | |
| "/transcription/meeting", | |
| headers=headers, | |
| files=files, | |
| data=data, | |
| ) | |
| assert response.status_code == 400 | |
| body = response.json() | |
| assert "Unsupported file format" in body["detail"] | |
| def test_transcription_meeting_includes_metadata_on_success(monkeypatch, tmp_path): | |
| """Successful /transcription/meeting call should include usage/metadata fields.""" | |
| client = TestClient(app) | |
| headers = get_auth_headers() | |
| # Create a tiny dummy wav file (extension supported, content irrelevant here) | |
| dummy_file = tmp_path / "meeting.wav" | |
| dummy_file.write_bytes(b"RIFF....WAVEfmt ") | |
| # We don't mock OpenAI here; the goal is just to assert response shape | |
| with dummy_file.open("rb") as f: | |
| files = {"file": ("meeting.wav", f, "audio/wav")} | |
| data = {"project_id": "test-proj", "max_duration_seconds": 3600} | |
| response = client.post( | |
| "/transcription/meeting", | |
| headers=headers, | |
| files=files, | |
| data=data, | |
| ) | |
| # Depending on environment/OpenAI, this may fail; in that case, skip shape assertion | |
| if response.status_code == 200: | |
| body = response.json() | |
| assert "text" in body | |
| # New optional fields added by the carbon/tokens pipeline | |
| assert "usage" in body | |
| assert "metadata" in body | |