"""Unit tests for src/server/image_utils.py""" import base64 import cv2 import numpy as np import pytest from src.server.image_utils import decode_image, CLASS_COLORS def _make_jpeg_bytes(width=64, height=64) -> bytes: """Create a minimal valid JPEG bytestring.""" img = np.zeros((height, width, 3), dtype=np.uint8) img[10:50, 10:50] = (128, 64, 200) # a coloured rectangle success, buf = cv2.imencode(".jpg", img) assert success return buf.tobytes() class TestDecodeImage: def test_decodes_valid_jpeg_bytes(self): raw = _make_jpeg_bytes() img = decode_image(raw) assert img is not None assert img.ndim == 3 def test_decodes_from_memoryview(self): raw = _make_jpeg_bytes() img = decode_image(memoryview(raw)) assert img is not None def test_decodes_base64_encoded_jpeg(self): raw = _make_jpeg_bytes() encoded = base64.b64encode(raw) img = decode_image(encoded) assert img is not None def test_returns_none_for_garbage_bytes(self): img = decode_image(b"\x00\x01\x02\x03garbage") assert img is None def test_returns_none_for_empty_bytes(self): img = decode_image(b"") assert img is None def test_decoded_shape_matches_source(self): raw = _make_jpeg_bytes(width=80, height=60) img = decode_image(raw) assert img is not None # JPEG encoding may have minor dimension rounding; check order assert img.shape[0] == 60 # height assert img.shape[1] == 80 # width class TestClassColors: def test_class_colors_are_bgr_tuples(self): for cls_id, color in CLASS_COLORS.items(): assert isinstance(color, tuple) assert len(color) == 3 assert all(0 <= c <= 255 for c in color) def test_known_class_ids_present(self): assert 0 in CLASS_COLORS assert 1 in CLASS_COLORS