import io import json from pathlib import Path import subprocess import sys import os import pytest from PIL import Image sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from app import create_app TOKEN = "t" * 48 AUTH = {"Authorization": "Bearer " + TOKEN} @pytest.fixture def service(tmp_path): app = create_app(tmp_path / "data", TOKEN) app.config["TESTING"] = True return app, app.test_client(), tmp_path / "data" def photo(color="red", format="JPEG", size=(40, 20), exif=None): output = io.BytesIO() Image.new("RGB", size, color).save(output, format, **({"exif": exif} if exif else {})) return output.getvalue() def upload(client, images=None, caption="", headers=AUTH): return client.post("/api/photos", headers=headers, data={ "caption": caption, "photos": [(io.BytesIO(raw), "../../escape.jpg") for raw in (images or [photo()])], }) def test_authentication_and_request_limits(service): app, client, data = service assert upload(client, headers={}).status_code == 401 assert upload(client, headers={"Authorization": "Bearer wrong"}).status_code == 401 assert client.get("/api/photos/" + "a" * 64).status_code == 401 assert client.get("/healthz").status_code == 200 assert upload(client, caption="a" * 4001).status_code == 400 assert client.post("/api/photos", headers=AUTH).status_code == 400 assert upload(client, [photo()] * 21).status_code == 400 app.config["MAX_CONTENT_LENGTH"] = 100 assert upload(client).status_code == 413 assert not list((data / "submissions").iterdir()) def test_validation_is_all_or_nothing(service): _, client, data = service assert upload(client, [photo(), b"not an image"]).status_code == 400 assert upload(client, [photo(format="GIF")]).status_code == 400 assert not list((data / "submissions").iterdir()) assert not list((data / "temporary").iterdir()) def test_album_caption_order_and_retry_deduplication(service): _, client, data = service caption = ' {% include secret %} {{ site.email }}\nsecond line' images = [photo("red"), photo("blue")] response = upload(client, images, caption) assert response.status_code == 202 job = response.json["id"] folder = data / "submissions" / job entry = (folder / "entry.md").read_text() assert "