Python 88.3%
TypeScript 7.6%
Shell 4.1%
1"""Images API tests. Validation-error and provenance tests are free and always run; generation is gated by RUN_IMAGE_TESTS."""2from __future__ import annotations34import base645import uuid6from pathlib import Path78import pytest910ROOT = Path(__file__).resolve().parents[2]111213def test_invalid_size_error_shape(openai):14 st, body, _ = openai("POST", "/v1/images/generations", {"model": "gpt-image-1-mini", "prompt": "a plain white square", "size": "123x456"},15 note="test_images invalid size (free)")16 assert st == 400, body17 err = body["error"]18 assert err["type"] == "image_generation_user_error" and err["param"] == "size" and err["code"] == "invalid_value"192021def test_dalle_params_rejected_on_gpt_image(openai):22 st, body, _ = openai("POST", "/v1/images/generations", {"model": "gpt-image-1-mini", "prompt": "x", "style": "vivid"}, note="test style on gpt-image (free)")23 assert st == 400 and body["error"]["code"] == "unknown_parameter" and body["error"]["param"] == "style"242526def test_dalle3_retired(openai):27 st, body, _ = openai("POST", "/v1/images/generations", {"model": "dall-e-3", "prompt": "x", "n": 1}, note="test dall-e-3 retired (free)")28 assert st in (400, 404), body29 if st == 400:30 assert body["error"]["param"] == "model"313233def _multipart(fields: dict, files: dict) -> tuple[bytes, str]:34 bnd = uuid.uuid4().hex35 out = b""36 for k, v in fields.items():37 out += f'--{bnd}\r\nContent-Disposition: form-data; name="{k}"\r\n\r\n{v}\r\n'.encode()38 for k, (fn, data, ct) in files.items():39 out += f'--{bnd}\r\nContent-Disposition: form-data; name="{k}"; filename="{fn}"\r\nContent-Type: {ct}\r\n\r\n'.encode() + data + b"\r\n"40 return out + f"--{bnd}--\r\n".encode(), f"multipart/form-data; boundary={bnd}"414243def test_provenance_check_on_plain_png(openai):44 png = base64.b64decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC")45 body, ct = _multipart({}, {"file": ("px.png", png, "image/png")})46 st, resp, _ = openai("POST", "/v1/content_provenance_checks", data=body, content_type=ct, note="test provenance 1x1 png (free)")47 if st == 429:48 pytest.skip("provenance API rate-limited")49 assert st == 200, resp50 assert resp["object"] == "content_provenance_check"51 types = {r["type"]: r for r in resp["results"]}52 assert types["c2pa"]["outcome"] == "not_detected" and types["c2pa"]["validation_state"] == "not_present"53 assert types["synthid"]["outcome"] == "not_detected"545556@pytest.mark.run_image_tests57def test_generate_gpt_image_1_mini_low(openai):58 """~$0.002-0.005: one 1024x1024 low-quality jpeg with the cheapest GPT image model."""59 st, body, _ = openai("POST", "/v1/images/generations", {"model": "gpt-image-1-mini", "prompt": "a plain white square", "size": "1024x1024",60 "quality": "low", "output_format": "jpeg", "n": 1},61 est_cost_usd=0.005, note="test_images generation (RUN_IMAGE_TESTS)", timeout=180)62 assert st == 200, body63 assert body["output_format"] == "jpeg" and body["quality"] == "low" and body["size"] == "1024x1024"64 img = base64.b64decode(body["data"][0]["b64_json"])65 assert img[:3] == b"\xff\xd8\xff", "JPEG magic bytes"66 u = body["usage"]67 assert u["output_tokens"] >= 1 and u["total_tokens"] == u["input_tokens"] + u["output_tokens"]68 (ROOT / "tmp-live").mkdir(exist_ok=True)69 (ROOT / "tmp-live" / "test-gen-1mini.jpg").write_bytes(img)70