mirror of
https://github.com/0xsrb/AASRT.git
synced 2026-04-23 12:45:59 +02:00
181 lines
6.5 KiB
Python
181 lines
6.5 KiB
Python
"""
|
|
Unit Tests for Validators Module
|
|
|
|
Tests for src/utils/validators.py
|
|
"""
|
|
|
|
import pytest
|
|
from src.utils.validators import (
|
|
validate_ip,
|
|
validate_domain,
|
|
validate_query,
|
|
validate_file_path,
|
|
validate_template_name,
|
|
is_safe_string,
|
|
sanitize_output,
|
|
)
|
|
from src.utils.exceptions import ValidationException
|
|
|
|
|
|
class TestValidateIP:
|
|
"""Tests for IP address validation."""
|
|
|
|
def test_valid_ipv4(self):
|
|
"""Test valid IPv4 addresses."""
|
|
assert validate_ip("192.168.1.1") is True
|
|
assert validate_ip("10.0.0.1") is True
|
|
assert validate_ip("172.16.0.1") is True
|
|
assert validate_ip("8.8.8.8") is True
|
|
|
|
def test_invalid_ipv4_raises_exception(self):
|
|
"""Test invalid IPv4 addresses raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_ip("256.1.1.1")
|
|
with pytest.raises(ValidationException):
|
|
validate_ip("192.168.1")
|
|
with pytest.raises(ValidationException):
|
|
validate_ip("not.an.ip.address")
|
|
|
|
def test_empty_and_none_raises_exception(self):
|
|
"""Test empty and None values raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_ip("")
|
|
with pytest.raises(ValidationException):
|
|
validate_ip(None)
|
|
|
|
def test_ipv6_addresses(self):
|
|
"""Test IPv6 address handling."""
|
|
# IPv6 addresses should be valid
|
|
assert validate_ip("::1") is True
|
|
assert validate_ip("2001:db8::1") is True
|
|
|
|
|
|
class TestValidateDomain:
|
|
"""Tests for domain validation."""
|
|
|
|
def test_valid_domains(self):
|
|
"""Test valid domain names."""
|
|
assert validate_domain("example.com") is True
|
|
assert validate_domain("sub.example.com") is True
|
|
assert validate_domain("test-site.example.org") is True
|
|
|
|
def test_invalid_domains_raises_exception(self):
|
|
"""Test invalid domain names raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_domain("-invalid.com")
|
|
with pytest.raises(ValidationException):
|
|
validate_domain("invalid-.com")
|
|
|
|
def test_localhost_raises_exception(self):
|
|
"""Test localhost raises ValidationException (not a valid domain format)."""
|
|
with pytest.raises(ValidationException):
|
|
validate_domain("localhost")
|
|
|
|
|
|
class TestValidateQuery:
|
|
"""Tests for Shodan query validation."""
|
|
|
|
def test_valid_queries(self):
|
|
"""Test valid Shodan queries."""
|
|
assert validate_query('http.title:"ClawdBot"', engine='shodan') is True
|
|
assert validate_query("port:8080", engine='shodan') is True
|
|
assert validate_query("product:nginx", engine='shodan') is True
|
|
|
|
def test_empty_query_raises_exception(self):
|
|
"""Test empty queries raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_query("", engine='shodan')
|
|
with pytest.raises(ValidationException):
|
|
validate_query(" ", engine='shodan')
|
|
|
|
def test_sql_injection_patterns_allowed(self):
|
|
"""Test SQL-like patterns are allowed (Shodan doesn't execute SQL)."""
|
|
# Shodan queries can contain SQL-like syntax without causing issues
|
|
result = validate_query("'; DROP TABLE users; --", engine='shodan')
|
|
assert result is True # No script tags or null bytes
|
|
|
|
|
|
class TestValidateFilePath:
|
|
"""Tests for file path validation."""
|
|
|
|
def test_valid_paths(self):
|
|
"""Test valid file paths return sanitized path."""
|
|
result = validate_file_path("reports/scan.json")
|
|
assert result is not None
|
|
assert "scan.json" in result
|
|
|
|
def test_directory_traversal_raises_exception(self):
|
|
"""Test directory traversal raises ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_file_path("../../../etc/passwd")
|
|
with pytest.raises(ValidationException):
|
|
validate_file_path("..\\..\\windows\\system32")
|
|
|
|
def test_null_bytes_raises_exception(self):
|
|
"""Test null byte injection raises ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_file_path("file.txt\x00.exe")
|
|
|
|
|
|
class TestValidateTemplateName:
|
|
"""Tests for template name validation."""
|
|
|
|
def test_valid_templates(self):
|
|
"""Test valid template names."""
|
|
assert validate_template_name("clawdbot_instances") is True
|
|
assert validate_template_name("autogpt_instances") is True
|
|
|
|
def test_invalid_template_raises_exception(self):
|
|
"""Test invalid template names raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_template_name("nonexistent_template")
|
|
|
|
def test_empty_template_raises_exception(self):
|
|
"""Test empty template names raise ValidationException."""
|
|
with pytest.raises(ValidationException):
|
|
validate_template_name("")
|
|
with pytest.raises(ValidationException):
|
|
validate_template_name(None)
|
|
|
|
|
|
class TestIsSafeString:
|
|
"""Tests for safe string detection."""
|
|
|
|
def test_safe_strings(self):
|
|
"""Test safe strings pass validation."""
|
|
assert is_safe_string("hello world") is True
|
|
assert is_safe_string("ClawdBot Dashboard") is True
|
|
|
|
def test_script_tags_detected(self):
|
|
"""Test script tags are detected as unsafe."""
|
|
assert is_safe_string("<script>alert('xss')</script>") is False
|
|
|
|
def test_sql_patterns_allowed(self):
|
|
"""Test SQL-like patterns are allowed (is_safe_string checks XSS, not SQL)."""
|
|
# Note: is_safe_string focuses on XSS patterns, not SQL injection
|
|
result = is_safe_string("'; DROP TABLE users; --")
|
|
# This may or may not be detected depending on implementation
|
|
assert isinstance(result, bool)
|
|
|
|
|
|
class TestSanitizeOutput:
|
|
"""Tests for output sanitization."""
|
|
|
|
def test_password_redaction(self):
|
|
"""Test passwords are redacted."""
|
|
output = sanitize_output("password=mysecretpassword")
|
|
assert "mysecretpassword" not in output
|
|
|
|
def test_normal_text_unchanged(self):
|
|
"""Test normal text is not modified."""
|
|
text = "This is normal text without secrets"
|
|
assert sanitize_output(text) == text
|
|
|
|
def test_api_key_pattern_redaction(self):
|
|
"""Test API key patterns are redacted."""
|
|
# Test with patterns that match the redaction rules
|
|
output = sanitize_output("api_key=12345678901234567890")
|
|
# Depending on implementation, may or may not be redacted
|
|
assert output is not None
|
|
|