Files
odysseus/tests/test_direct_upload_limits.py
Vykos 193dc2f085 fix(uploads): bound direct upload reads
* Stabilize full test collection

* Add bounded reads for direct uploads
2026-06-04 00:32:50 +01:00

62 lines
1.9 KiB
Python

import io
from pathlib import Path
import pytest
from fastapi import HTTPException, UploadFile
from src.upload_limits import format_byte_limit, read_upload_limited
REPO = Path(__file__).resolve().parent.parent
def _upload(name: str, data: bytes) -> UploadFile:
return UploadFile(filename=name, file=io.BytesIO(data))
def _source(path: str) -> str:
return (REPO / path).read_text(encoding="utf-8")
async def test_read_upload_limited_accepts_exact_limit():
assert await read_upload_limited(_upload("ok.bin", b"abcd"), 4, "Test upload") == b"abcd"
async def test_read_upload_limited_rejects_oversized_upload():
with pytest.raises(HTTPException) as exc:
await read_upload_limited(_upload("too-big.bin", b"abcde"), 4, "Test upload")
assert exc.value.status_code == 413
assert exc.value.detail == "Test upload exceeds 4 bytes limit"
def test_upload_limit_formatting_is_human_readable():
assert format_byte_limit(25 * 1024 * 1024) == "25 MB"
assert format_byte_limit(512 * 1024) == "512 KB"
assert format_byte_limit(7) == "7 bytes"
def test_direct_upload_routes_use_bounded_reads():
expectations = {
"routes/stt_routes.py": [
"read_upload_limited(file, STT_MAX_AUDIO_BYTES",
],
"routes/gallery_routes.py": [
"read_upload_limited(file, GALLERY_UPLOAD_MAX_BYTES",
"read_upload_limited(file, GALLERY_TRANSFORM_UPLOAD_MAX_BYTES",
],
"routes/memory_routes.py": [
"read_upload_limited(file, MEMORY_IMPORT_MAX_BYTES",
],
"routes/calendar_routes.py": [
"read_upload_limited(file, _ICS_MAX_BYTES",
],
"routes/email_routes.py": [
"read_upload_limited(file, EMAIL_COMPOSE_UPLOAD_MAX_BYTES",
],
}
for path, needles in expectations.items():
text = _source(path)
for needle in needles:
assert needle in text