124 lines
4.4 KiB
Python
124 lines
4.4 KiB
Python
"""Tests for refactoring analyzer module."""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
|
|
from shellgenius.refactoring import (
|
|
RefactoringAnalyzer,
|
|
RefactoringIssue,
|
|
RefactoringResult,
|
|
SecurityRulesDB,
|
|
refactor_script,
|
|
)
|
|
|
|
|
|
class TestSecurityRulesDB:
|
|
def test_get_rules(self):
|
|
"""Test getting all security rules."""
|
|
rules = SecurityRulesDB.get_rules()
|
|
|
|
assert len(rules) > 0
|
|
assert any(r["id"] == "CWE-78" for r in rules)
|
|
|
|
def test_check_rule_shell_injection(self):
|
|
"""Test detection of shell injection patterns."""
|
|
dangerous_line = 'rm -rf $dir'
|
|
|
|
rule = SecurityRulesDB.check_rule(dangerous_line)
|
|
|
|
assert rule is not None
|
|
assert rule["severity"] == "high"
|
|
|
|
def test_check_rule_no_match(self):
|
|
"""Test that safe commands don't match rules."""
|
|
safe_line = "ls -la"
|
|
|
|
rule = SecurityRulesDB.check_rule(safe_line)
|
|
|
|
assert rule is None
|
|
|
|
|
|
class TestRefactoringAnalyzer:
|
|
def test_analyze_safe_script(self):
|
|
"""Test analyzing a safe script."""
|
|
with patch('shellgenius.refactoring.get_ollama_client') as mock_client:
|
|
mock_client.return_value.generate.return_value = {"success": False}
|
|
|
|
safe_script = "#!/bin/bash\nset -euo pipefail\necho hello"
|
|
|
|
analyzer = RefactoringAnalyzer()
|
|
result = analyzer.analyze(safe_script, include_suggestions=False)
|
|
|
|
assert result.score >= 90
|
|
assert len(result.issues) == 0
|
|
|
|
def test_analyze_unsafe_script(self):
|
|
"""Test analyzing a script with security issues."""
|
|
with patch('shellgenius.refactoring.get_ollama_client') as mock_client:
|
|
mock_client.return_value.generate.return_value = {"success": False}
|
|
|
|
unsafe_script = "#!/bin/bash\nchmod 777 /tmp/sensitive"
|
|
|
|
analyzer = RefactoringAnalyzer()
|
|
result = analyzer.analyze(unsafe_script, include_suggestions=False)
|
|
|
|
assert result.score < 100
|
|
assert len(result.issues) > 0
|
|
|
|
def test_calculate_score(self):
|
|
"""Test security score calculation."""
|
|
with patch('shellgenius.refactoring.get_ollama_client') as mock_client:
|
|
mock_client.return_value.generate.return_value = {"success": False}
|
|
|
|
analyzer = RefactoringAnalyzer()
|
|
|
|
critical_issue = RefactoringIssue(
|
|
line_number=1,
|
|
original="eval $user_input",
|
|
issue_type="Eval with User Input",
|
|
severity="critical",
|
|
description="Eval with variable input",
|
|
risk_assessment="Shell injection vulnerability",
|
|
suggestion="Avoid eval",
|
|
safer_alternative="Use direct variable",
|
|
)
|
|
|
|
score = analyzer._calculate_score([critical_issue], "script")
|
|
|
|
assert score <= 75
|
|
|
|
def test_generate_safer_script(self):
|
|
"""Test generation of safer script version."""
|
|
with patch('shellgenius.refactoring.get_ollama_client') as mock_client:
|
|
mock_client.return_value.generate.return_value = {"success": False}
|
|
|
|
analyzer = RefactoringAnalyzer()
|
|
|
|
unsafe_script = "chmod 777 /tmp/file"
|
|
|
|
critical_issue = RefactoringIssue(
|
|
line_number=1,
|
|
original=unsafe_script,
|
|
issue_type="Insecure File Permissions",
|
|
severity="high",
|
|
description="World-writable permissions",
|
|
risk_assessment="Security vulnerability",
|
|
suggestion="Use chmod 755",
|
|
safer_alternative="chmod 755 /tmp/file",
|
|
)
|
|
|
|
safer = analyzer._generate_safer_script(unsafe_script, [critical_issue])
|
|
|
|
assert "755" in safer
|
|
|
|
|
|
class TestRefactorScript:
|
|
def test_convenience_function(self):
|
|
"""Test the convenience function for refactoring."""
|
|
with patch('shellgenius.refactoring.get_ollama_client') as mock_client:
|
|
mock_client.return_value.generate.return_value = {"success": False}
|
|
|
|
result = refactor_script("echo hello", include_suggestions=False)
|
|
|
|
assert isinstance(result, RefactoringResult)
|