Files
odysseus/tests/test_direct_upload_limits.py
T
Léo 4b4ae592da refactor(routes): move the email modules into routes/email/
routes/email_routes.py (7,194 lines), routes/email_helpers.py (2,025) and
routes/email_pollers.py (1,764) were the largest flat email area left in
routes/. They now live in routes/email/, following the pattern fifteen route
areas already use: the canonical module under the package, a shim at the old
path that replaces itself in sys.modules with the canonical object.

The shim matters more here than the move. Dozens of email tests monkeypatch
module attributes, and several pop the module from sys.modules and re-import
it. Without identity between routes.email_routes and routes.email.email_routes
those patches would apply to a different object than the app uses.

Intra-package imports keep the flat path, matching routes/document/ and
routes/gallery/: the shim resolves them and the diff stays a move.

Eight path references in five test modules read these files as source rather
than importing them, so they now read the canonical location. That is the same
adjustment every previous conversion made, and it is why the note/document
shims mention source-introspection tests explicitly.

No behaviour change. Verified with the full suite and under several explicit
collection orders, since a byte-identical routes move has broken tests under
one ordering before.
2026-09-29 18:21:18 +02: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/gallery_routes.py": [
"read_upload_limited(file, GALLERY_UPLOAD_MAX_BYTES",
"read_upload_limited(file, GALLERY_TRANSFORM_UPLOAD_MAX_BYTES",
],
"routes/memory/memory_routes.py": [
"read_upload_limited(file, MEMORY_IMPORT_MAX_BYTES",
],
"routes/calendar_routes.py": [
"read_upload_limited(file, ICS_MAX_BYTES",
],
"routes/email/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