crowncode-backend / tests /test_data_processing.py
Rthur2003's picture
fix: update audio processing endpoint to default options to all-off when missing
8ea6326
"""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