"""Unit tests for pipeline/validation.py.""" from __future__ import annotations import base64 import pytest from pipeline.validation import InputValidator, ValidationResult class TestInputValidator: def test_no_input_rejected(self): v = InputValidator() r = v.validate() assert not r.valid assert "No image input" in r.error def test_url_valid(self): v = InputValidator() r = v.validate(image_url="https://example.com/image.jpg") assert r.valid assert r.source == "url" def test_url_invalid_scheme(self): v = InputValidator() r = v.validate(image_url="ftp://example.com/image.jpg") assert not r.valid assert "scheme" in r.error def test_url_missing_host(self): v = InputValidator() r = v.validate(image_url="https:///image.jpg") assert not r.valid assert "host" in r.error def test_url_localhost_rejected(self): v = InputValidator() r = v.validate(image_url="http://localhost/image.jpg") assert not r.valid assert "Localhost" in r.error def test_url_127_rejected(self): v = InputValidator() r = v.validate(image_url="http://127.0.0.1/image.jpg") assert not r.valid def test_base64_valid(self, sample_image_b64): v = InputValidator() r = v.validate(image_base64=sample_image_b64) assert r.valid assert r.source == "base64" assert r.image_bytes is not None assert r.format == "jpeg" def test_base64_with_data_uri_prefix(self, sample_image_b64): v = InputValidator() r = v.validate(image_base64="data:image/jpeg;base64," + sample_image_b64) assert r.valid def test_base64_invalid(self): v = InputValidator() r = v.validate(image_base64="!!!not-base64!!!") assert not r.valid def test_base64_too_large(self): v = InputValidator(max_bytes=100) # Create a large fake "image" (just bytes) big = b"\xff\xd8\xff" + b"x" * 200 b64 = base64.b64encode(big).decode() r = v.validate(image_base64=b64) assert not r.valid assert "exceeds" in r.error def test_bytes_valid(self, sample_image_bytes): v = InputValidator() r = v.validate(image_bytes=sample_image_bytes) assert r.valid assert r.source == "bytes" assert r.format == "jpeg" def test_bytes_invalid_magic(self): v = InputValidator() r = v.validate(image_bytes=b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b") assert not r.valid assert "format" in r.error.lower() def test_bytes_too_small(self): v = InputValidator() r = v.validate(image_bytes=b"\xff\xd8\xff") # 3 bytes is too small for the magic-byte check assert not r.valid def test_png_format_detected(self): # Minimal PNG magic bytes png = b"\x89PNG\r\n\x1a\n" + b"\x00" * 50 v = InputValidator() r = v.validate(image_bytes=png) assert r.valid assert r.format == "png"