mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 11:56:01 +02:00
89 lines
3.9 KiB
Python
89 lines
3.9 KiB
Python
"""Logo persistence, image validation, and overlay authentication."""
|
|
|
|
import io
|
|
|
|
import pytest
|
|
from PIL import Image
|
|
|
|
from backend.tests.overlay_helpers import mint_token, setup_admin
|
|
|
|
pytestmark = [pytest.mark.asyncio, pytest.mark.integration]
|
|
|
|
|
|
def logo_bytes(fmt="PNG"):
|
|
output = io.BytesIO()
|
|
Image.new("RGBA", (80, 40), (255, 0, 0, 128)).save(output, format=fmt)
|
|
return output.getvalue()
|
|
|
|
|
|
async def test_logo_upload_read_remove(async_client, tmp_path, monkeypatch):
|
|
from backend.app.core.config import settings
|
|
|
|
monkeypatch.setattr(settings, "base_dir", tmp_path)
|
|
response = await async_client.post(
|
|
"/api/v1/settings/overlay-logo", files={"file": ("logo.webp", logo_bytes("WEBP"), "image/webp")}
|
|
)
|
|
assert response.status_code == 200
|
|
image = await async_client.get("/api/v1/overlay-branding/logo")
|
|
assert image.status_code == 200
|
|
assert image.headers["content-type"] == "image/png"
|
|
with Image.open(io.BytesIO(image.content)) as decoded:
|
|
assert decoded.size == (80, 40)
|
|
assert decoded.mode == "RGBA"
|
|
assert (await async_client.delete("/api/v1/settings/overlay-logo")).status_code == 200
|
|
assert (await async_client.get("/api/v1/overlay-branding/logo")).status_code == 404
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("content", "status"),
|
|
[(b"<svg></svg>", 400), (b"invalid", 400), (b"x" * (2 * 1024 * 1024 + 1), 413)],
|
|
ids=["svg", "invalid", "oversized"],
|
|
)
|
|
async def test_rejects_invalid_uploads(async_client, tmp_path, monkeypatch, content, status):
|
|
from backend.app.core.config import settings
|
|
|
|
monkeypatch.setattr(settings, "base_dir", tmp_path)
|
|
response = await async_client.post(
|
|
"/api/v1/settings/overlay-logo", files={"file": ("logo.png", content, "image/png")}
|
|
)
|
|
assert response.status_code == status
|
|
assert not (tmp_path / "overlay-branding" / "logo.png").exists()
|
|
|
|
|
|
async def test_logo_auth_and_token_scope(async_client, tmp_path, monkeypatch):
|
|
from backend.app.core.config import settings
|
|
|
|
monkeypatch.setattr(settings, "base_dir", tmp_path)
|
|
jwt = await setup_admin(async_client, suffix="_branding")
|
|
headers = {"Authorization": f"Bearer {jwt}"}
|
|
response = await async_client.post(
|
|
"/api/v1/settings/overlay-logo",
|
|
headers=headers,
|
|
files={"file": ("logo.png", logo_bytes(), "image/png")},
|
|
)
|
|
assert response.status_code == 200
|
|
assert (await async_client.get("/api/v1/settings/overlay-logo", headers=headers)).status_code == 200
|
|
assert (await async_client.get("/api/v1/settings/overlay-logo")).status_code == 401
|
|
assert (await async_client.get("/api/v1/overlay-branding/logo")).status_code == 401
|
|
for scope in ("camera_stream", "camwall", "overlay"):
|
|
token = await mint_token(async_client, jwt, scope=scope, name=scope)
|
|
response = await async_client.get("/api/v1/overlay-branding/logo", params={"token": token})
|
|
assert response.status_code == (200 if scope == "overlay" else 401)
|
|
assert (await async_client.delete("/api/v1/settings/overlay-logo", params={"token": token})).status_code == 401
|
|
assert (await async_client.get("/api/v1/overlay-branding/logo?token=invalid")).status_code == 401
|
|
|
|
|
|
async def test_invalid_replacement_preserves_logo(async_client, tmp_path, monkeypatch):
|
|
from backend.app.core.config import settings
|
|
|
|
monkeypatch.setattr(settings, "base_dir", tmp_path)
|
|
await async_client.post("/api/v1/settings/overlay-logo", files={"file": ("logo.png", logo_bytes(), "image/png")})
|
|
before = (await async_client.get("/api/v1/overlay-branding/logo")).content
|
|
output = io.BytesIO()
|
|
Image.new("RGB", (2100, 2100)).save(output, "PNG")
|
|
response = await async_client.post(
|
|
"/api/v1/settings/overlay-logo", files={"file": ("huge.png", output.getvalue(), "image/png")}
|
|
)
|
|
assert response.status_code == 400
|
|
assert (await async_client.get("/api/v1/overlay-branding/logo")).content == before
|