Research-Stack/4-Infrastructure/NoDupeLabs/tests/database/test_security_coverage.py

189 lines
6.9 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# Copyright (c) 2025 Allaun
"""Tests for DatabaseSecurity to achieve 100% coverage."""
from unittest.mock import MagicMock
import pytest
from nodupe.tools.databases.security import DatabaseSecurity, InputValidationError, SecurityError
class TestDatabaseSecurityCoverage:
"""Test cases to achieve full coverage of DatabaseSecurity."""
def test_validate_input_none(self):
"""Test validate_input raises error for None."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_input(None)
def test_validate_input_with_type_str(self):
"""Test validate_input with string type."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
result = security.validate_input("test", "str")
assert result is True
def test_validate_input_with_type_int(self):
"""Test validate_input with int type."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
result = security.validate_input(123, "int")
assert result is True
def test_validate_input_with_type_mismatch(self):
"""Test validate_input raises error for type mismatch."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_input("123", "int")
def test_validate_input_unknown_type(self):
"""Test validate_input raises error for unknown type."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_input("test", "unknown_type")
def test_validate_input_dangerous_string(self):
"""Test validate_input raises error for dangerous string."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_input("test'; DROP TABLE users;--")
def test_is_safe_string_empty(self):
"""Test _is_safe_string returns True for empty string."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security._is_safe_string("") is True
def test_is_safe_string_dangerous(self):
"""Test _is_safe_string detects dangerous patterns."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
# These patterns should be detected as dangerous
assert security._is_safe_string("test; DROP TABLE") is False
def test_is_safe_string_safe(self):
"""Test _is_safe_string returns True for safe strings."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security._is_safe_string("test_value_123") is True
def test_validate_path_empty(self):
"""Test validate_path raises error for empty path."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_path("")
def test_validate_path_traversal(self):
"""Test validate_path detects directory traversal."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_path("../etc/passwd")
def test_validate_path_absolute_outside_base(self):
"""Test validate_path detects absolute path outside base."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_path("/etc/passwd", base_dir="/home/user")
def test_validate_path_valid(self):
"""Test validate_path accepts valid paths."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security.validate_path("/home/user/file.txt") is True
assert security.validate_path("relative/path/file.txt") is True
def test_validate_path_with_base_dir_valid(self):
"""Test validate_path accepts paths within base_dir."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security.validate_path("/home/user/data/file.txt", base_dir="/home/user/data") is True
def test_sanitize_error_message(self):
"""Test sanitize_error_message removes sensitive info."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
# Test with password pattern
error = Exception("Error: password=secret123")
result = security.sanitize_error_message(error)
assert "password" in result.lower() or "secret123" not in result
def test_validate_identifier_empty(self):
"""Test validate_identifier raises error for empty identifier."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_identifier("")
def test_validate_identifier_invalid_start(self):
"""Test validate_identifier raises error for invalid start."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_identifier("123invalid")
def test_validate_identifier_invalid_chars(self):
"""Test validate_identifier raises error for invalid chars."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_identifier("table-name")
def test_validate_identifier_valid(self):
"""Test validate_identifier accepts valid identifiers."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security.validate_identifier("valid_table") is True
assert security.validate_identifier("Table123") is True
def test_validate_schema_empty(self):
"""Test validate_schema raises error for empty schema."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_schema("")
def test_validate_schema_invalid_chars(self):
"""Test validate_schema raises error for invalid chars."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
with pytest.raises(InputValidationError):
security.validate_schema("col TEXT; DROP TABLE")
def test_validate_schema_valid(self):
"""Test validate_schema accepts valid schemas."""
mock_db = MagicMock()
security = DatabaseSecurity(mock_db)
assert security.validate_schema("id INTEGER PRIMARY KEY, name TEXT") is True
assert security.validate_schema("col1 INT, col2 TEXT, col3 REAL") is True