86 lines
2.5 KiB
Python
86 lines
2.5 KiB
Python
from io import BytesIO
|
|
|
|
import pytest
|
|
from PIL import Image
|
|
|
|
from pigway_frame_flow.errors import FlowError
|
|
from pigway_frame_flow.renderers.images import convert
|
|
|
|
|
|
def image_bytes(format="PNG", size=(800, 400)):
|
|
out = BytesIO()
|
|
Image.new("RGB", size, "red").save(out, format)
|
|
return out.getvalue()
|
|
|
|
|
|
@pytest.mark.parametrize("format", ["JPEG", "PNG", "WEBP"])
|
|
@pytest.mark.parametrize("fit", ["contain", "cover", "smart"])
|
|
@pytest.mark.parametrize("profile", ["color", "grayscale"])
|
|
def test_conversion(format, fit, profile):
|
|
img = Image.open(BytesIO(convert(image_bytes(format), fit, profile)))
|
|
assert img.size == (1200, 1600)
|
|
assert img.format == "JPEG"
|
|
if profile == "grayscale":
|
|
assert len(set(img.getpixel((600, 800)))) == 1
|
|
|
|
|
|
def test_contain_preserves_shape():
|
|
img = Image.open(BytesIO(convert(image_bytes(), "contain")))
|
|
assert img.getpixel((600, 100)) == (255, 255, 255)
|
|
assert img.getpixel((600, 800))[0] > 240
|
|
|
|
|
|
def test_invalid_image():
|
|
with pytest.raises(FlowError):
|
|
convert(b"bad")
|
|
|
|
|
|
def test_transparency_white():
|
|
out = BytesIO()
|
|
Image.new("RGBA", (100, 100), (255, 0, 0, 0)).save(out, "PNG")
|
|
img = Image.open(BytesIO(convert(out.getvalue(), "cover")))
|
|
assert img.getpixel((600, 800)) == (255, 255, 255)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"template",
|
|
["daily-dashboard", "weather", "calendar", "quote", "photo-text", "system-alert"],
|
|
)
|
|
def test_templates(service, template):
|
|
result = service.renderer.render(template, {}, "color")
|
|
assert Image.open(BytesIO(result)).size == (1200, 1600)
|
|
|
|
|
|
def test_url_default_disabled(service):
|
|
with pytest.raises(FlowError):
|
|
service.assets.fetch_url("https://example.com/x.jpg")
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"url",
|
|
[
|
|
"http://localhost/x",
|
|
"file:///etc/passwd",
|
|
"https://127.0.0.1/x",
|
|
"https://user:pass@example.com/x",
|
|
],
|
|
)
|
|
def test_url_ssrf(service, url):
|
|
with pytest.raises(FlowError):
|
|
service.assets.fetch_url(url)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"template",
|
|
["daily-dashboard", "weather", "calendar", "quote", "photo-text", "system-alert"],
|
|
)
|
|
def test_template_grayscale(service, template):
|
|
img = Image.open(BytesIO(service.renderer.render(template, {}, "grayscale")))
|
|
assert img.size == (1200, 1600)
|
|
assert len(set(img.getpixel((600, 800)))) == 1
|
|
|
|
|
|
def test_calendar_rejects_invalid_date(service):
|
|
with pytest.raises(FlowError):
|
|
service.renderer.render("calendar", {"date": "not-a-date"})
|