Spaces:
Sleeping
Sleeping
| """Tests for /api/process/audio endpoint.""" | |
| from __future__ import annotations | |
| import io | |
| import json | |
| from fastapi.testclient import TestClient | |
| def _valid_options(**overrides: object) -> str: | |
| """Return a valid JSON options string with optional overrides.""" | |
| defaults = { | |
| "pitchShift": False, | |
| "speedChange": False, | |
| "bassBoost": False, | |
| "trimSilence": False, | |
| "mixAudio": False, | |
| "addNoise": False, | |
| } | |
| defaults.update(overrides) | |
| return json.dumps(defaults) | |
| def _fake_audio(content: bytes = b"\x00" * 1024) -> io.BytesIO: | |
| return io.BytesIO(content) | |
| def test_audio_valid_request_accepted(client: TestClient) -> None: | |
| """Valid audio file + valid options should not return 422.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": _valid_options()}, | |
| files={"file": ("test.wav", _fake_audio(), "audio/wav")}, | |
| ) | |
| # Should be processed (200) or a processing error (400/500) — never 422 | |
| assert response.status_code != 422 | |
| def test_audio_rejects_non_audio(client: TestClient) -> None: | |
| """Should reject non-audio content type with 400.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": _valid_options()}, | |
| files={"file": ("test.txt", _fake_audio(), "text/plain")}, | |
| ) | |
| assert response.status_code == 400 | |
| detail = response.json()["detail"] | |
| assert detail["code"] == "invalid_file_type" | |
| def test_audio_rejects_missing_content_type(client: TestClient) -> None: | |
| """Should reject file with empty content type as invalid.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": _valid_options()}, | |
| files={"file": ("test.bin", _fake_audio(), "")}, | |
| ) | |
| assert response.status_code == 400 | |
| detail = response.json()["detail"] | |
| assert detail["code"] == "invalid_file_type" | |
| def test_audio_rejects_missing_file(client: TestClient) -> None: | |
| """Should reject request without file.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": _valid_options()}, | |
| ) | |
| assert response.status_code == 422 | |
| def test_audio_rejects_invalid_options_json(client: TestClient) -> None: | |
| """Should reject malformed JSON in options with 422 + invalid_options code.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": "not-valid-json"}, | |
| files={"file": ("test.wav", _fake_audio(), "audio/wav")}, | |
| ) | |
| assert response.status_code == 422 | |
| detail = response.json()["detail"] | |
| assert detail["code"] == "invalid_options" | |
| def test_audio_accepts_camel_case_options(client: TestClient) -> None: | |
| """Frontend sends camelCase keys — should be accepted.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| data={"options": _valid_options(pitchShift=True, addNoise=True)}, | |
| files={"file": ("test.wav", _fake_audio(), "audio/wav")}, | |
| ) | |
| assert response.status_code != 422 | |
| def test_audio_defaults_when_options_missing(client: TestClient) -> None: | |
| """Missing options field should default to all-off, not 422.""" | |
| response = client.post( | |
| "/api/process/audio", | |
| files={"file": ("test.wav", _fake_audio(), "audio/wav")}, | |
| ) | |
| # Should proceed to processing (200) or processing error — never 422 | |
| assert response.status_code != 422 | |