64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
import io
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from PIL import Image
|
|
|
|
from src.image_sanitizer import MAX_IMAGE_PIXELS, sanitize_image
|
|
|
|
|
|
def test_runtime_dependencies_install_the_image_decoder():
|
|
requirements = (Path(__file__).parents[1] / "requirements.txt").read_text().splitlines()
|
|
assert any(line.startswith("Pillow==") for line in requirements)
|
|
|
|
|
|
def encoded_image(format_name, size=(3, 2), *, exif=None):
|
|
image = Image.new("RGB", size)
|
|
image.putdata(
|
|
[(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255), (255, 0, 255)]
|
|
)
|
|
output = io.BytesIO()
|
|
image.save(output, format=format_name, exif=exif or b"")
|
|
return output.getvalue()
|
|
|
|
|
|
def test_sanitize_image_applies_orientation_and_removes_jpeg_metadata():
|
|
exif = Image.Exif()
|
|
exif[274] = 6
|
|
exif[ GPS_TAG := 34853 ] = {1: "N", 2: (1, 1, 1)}
|
|
source = encoded_image("JPEG", exif=exif)
|
|
|
|
sanitized = sanitize_image("image/jpeg", source)
|
|
|
|
with Image.open(io.BytesIO(sanitized)) as result:
|
|
assert result.size == (2, 3)
|
|
assert not result.getexif()
|
|
assert GPS_TAG not in result.info
|
|
assert result.format == "JPEG"
|
|
|
|
|
|
def test_sanitize_image_rejects_bytes_that_do_not_match_claimed_type():
|
|
source = encoded_image("PNG")
|
|
|
|
with pytest.raises(ValueError, match="does not match"):
|
|
sanitize_image("image/jpeg", source)
|
|
|
|
|
|
def test_sanitize_image_rejects_over_twelve_megapixels_before_decoding():
|
|
image = Image.new("RGB", (4096, 3073))
|
|
output = io.BytesIO()
|
|
image.save(output, format="PNG")
|
|
|
|
with pytest.raises(ValueError, match="12 megapixels"):
|
|
sanitize_image("image/png", output.getvalue())
|
|
|
|
|
|
def test_sanitize_image_rejects_animated_webp():
|
|
first = Image.new("RGB", (2, 2), "red")
|
|
second = Image.new("RGB", (2, 2), "blue")
|
|
output = io.BytesIO()
|
|
first.save(output, format="WEBP", save_all=True, append_images=[second], duration=100)
|
|
|
|
with pytest.raises(ValueError, match="animated"):
|
|
sanitize_image("image/webp", output.getvalue())
|