File size: 3,133 Bytes
23d337e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""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"