"""Tests for shared.python.input_validation."""
import pytest
from shared.python.input_validation import (
sanitize_prompt_input,
validate_email,
validate_number_input,
validate_text_input,
validate_url,
)
class TestValidateNumberInput:
def test_valid_number(self):
assert validate_number_input("5", min_val=1, max_val=20) == 5
def test_strips_whitespace(self):
assert validate_number_input(" 7 ") == 7
def test_below_minimum_raises(self):
with pytest.raises(ValueError, match="between"):
validate_number_input("0", min_val=1, max_val=20)
def test_above_maximum_raises(self):
with pytest.raises(ValueError, match="between"):
validate_number_input("21", min_val=1, max_val=20)
def test_non_numeric_raises(self):
with pytest.raises(ValueError):
validate_number_input("abc")
class TestValidateTextInput:
def test_valid_text(self):
assert validate_text_input("Hello World", max_length=100) == "Hello World"
def test_trims_result(self):
assert validate_text_input(" padded ") == "padded"
def test_empty_not_allowed_raises(self):
with pytest.raises(ValueError, match="empty"):
validate_text_input(" ")
def test_empty_allowed_returns_empty(self):
assert validate_text_input(" ", allow_empty=True) == ""
def test_too_long_raises(self):
with pytest.raises(ValueError, match="too long"):
validate_text_input("x" * 11, max_length=10)
def test_too_short_raises(self):
with pytest.raises(ValueError, match="too short"):
validate_text_input("ab", min_length=5)
class TestSanitizePromptInput:
def test_plain_text_unchanged(self):
assert sanitize_prompt_input("Hello, world!") == "Hello, world!"
def test_removes_template_injection(self):
result = sanitize_prompt_input("Hello {{system}} world")
assert "{{" not in result
assert "}}" not in result
def test_removes_variable_substitution(self):
result = sanitize_prompt_input("value ${danger} here")
assert "${" not in result
def test_removes_script_tags(self):
result = sanitize_prompt_input("hi there")
assert "