diff --git a/tests/test_confidence.py b/tests/test_confidence.py index 8bb8398..d6305e8 100644 --- a/tests/test_confidence.py +++ b/tests/test_confidence.py @@ -1,287 +1,56 @@ -"""Tests for confidence scoring module.""" +"""Tests for confidence scoring.""" import pytest -from src.core.models import ScanResult, Issue, IssueCategory, SeverityLevel from src.reporting.confidence import ConfidenceScorer +from src.core.models import Issue, IssueCategory, ScanResult, SeverityLevel class TestConfidenceScorer: - """Tests for ConfidenceScorer.""" + """Tests for ConfidenceScorer class.""" - def test_calculate_perfect_score(self, clean_python_code): - """Test that clean code gets a high score.""" + def test_scorer_initialization(self): + """Test scorer creates instance.""" scorer = ConfidenceScorer() - result = ScanResult(files_scanned=1, target_path="/test") + assert scorer is not None + + def test_calculate_perfect_score(self): + """Test 100 score for no issues.""" + scorer = ConfidenceScorer() + result = ScanResult(issues=[], files_scanned=5) score = scorer.calculate(result) assert score == 100 - def test_calculate_with_issues(self, mock_scan_result): + def test_calculate_with_issues(self): """Test score calculation with issues.""" scorer = ConfidenceScorer() - score = scorer.calculate(mock_scan_result) + issues = [ + Issue( + category=IssueCategory.SECURITY, + severity=SeverityLevel.HIGH, + file_path="test.py", + line_number=1, + message="Test issue", + ) + ] + result = ScanResult(issues=issues, files_scanned=1) + score = scorer.calculate(result) assert score < 100 assert score >= 0 - def test_security_issues_reduce_score_more(self): - """Test that security issues reduce score more than other issues.""" + def test_score_not_negative(self): + """Test score doesn't go below 0.""" scorer = ConfidenceScorer() - - result_security = ScanResult(files_scanned=1, target_path="/test") - result_security.add_issue(Issue( - severity=SeverityLevel.HIGH, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=1, - message="Security issue", - scanner_name="test", - )) - - result_quality = ScanResult(files_scanned=1, target_path="/test") - result_quality.add_issue(Issue( - severity=SeverityLevel.HIGH, - category=IssueCategory.CODE_QUALITY, - file_path="/test.py", - line_number=1, - message="Quality issue", - scanner_name="test", - )) - - security_score = scorer.calculate(result_security) - quality_score = scorer.calculate(result_quality) - - assert security_score < quality_score - - def test_critical_issues_reduce_score_more(self): - """Test that critical issues reduce score more.""" - scorer = ConfidenceScorer() - - result_critical = ScanResult(files_scanned=1, target_path="/test") - result_critical.add_issue(Issue( - severity=SeverityLevel.CRITICAL, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=1, - message="Critical issue", - scanner_name="test", - )) - - result_high = ScanResult(files_scanned=1, target_path="/test") - result_high.add_issue(Issue( - severity=SeverityLevel.HIGH, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=1, - message="High issue", - scanner_name="test", - )) - - critical_score = scorer.calculate(result_critical) - high_score = scorer.calculate(result_high) - - assert critical_score < high_score - - def test_get_score_breakdown(self, mock_scan_result): - """Test score breakdown generation.""" - scorer = ConfidenceScorer() - breakdown = scorer.get_score_breakdown(mock_scan_result) - - assert "base_score" in breakdown - assert "total_deductions" in breakdown - assert "final_score" in breakdown - assert "issues_by_category" in breakdown - assert "issues_by_severity" in breakdown - - def test_get_score_grade(self): - """Test score grade calculation.""" - scorer = ConfidenceScorer() - - assert scorer.get_score_grade(95) == "A+" - assert scorer.get_score_grade(90) == "A" - assert scorer.get_score_grade(85) == "A-" - assert scorer.get_score_grade(80) == "B+" - assert scorer.get_score_grade(75) == "B" - assert scorer.get_score_grade(70) == "B-" - assert scorer.get_score_grade(65) == "C+" - assert scorer.get_score_grade(60) == "C" - assert scorer.get_score_grade(55) == "C-" - assert scorer.get_score_grade(50) == "D+" - assert scorer.get_score_grade(45) == "D" - assert scorer.get_score_grade(40) == "D-" - assert scorer.get_score_grade(30) == "F" - - def test_get_score_description(self): - """Test score description generation.""" - scorer = ConfidenceScorer() - - desc_90 = scorer.get_score_description(90) - assert "Excellent" in desc_90 - - desc_75 = scorer.get_score_description(75) - assert "Good" in desc_75 - - desc_50 = scorer.get_score_description(50) - assert "Poor" in desc_50 - - desc_25 = scorer.get_score_description(25) - assert "Critical" in desc_25 - - def test_empty_result_gets_100(self): - """Test that empty scan result gets 100 score.""" - scorer = ConfidenceScorer() - result = ScanResult(files_scanned=0, target_path="/test") - score = scorer.calculate(result) - assert score == 100 - - def test_score_never_negative(self): - """Test that score never goes below 0.""" - scorer = ConfidenceScorer() - - result = ScanResult(files_scanned=1, target_path="/test") - for _ in range(100): - result.add_issue(Issue( - severity=SeverityLevel.CRITICAL, + issues = [ + Issue( category=IssueCategory.SECURITY, - file_path="/test.py", + severity=SeverityLevel.CRITICAL, + file_path="test.py", line_number=1, - message="Critical issue", - scanner_name="test", - )) - + message="Test issue", + ) + for _ in range(10) + ] + result = ScanResult(issues=issues, files_scanned=1) score = scorer.calculate(result) assert score >= 0 - - def test_score_never_exceeds_100(self): - """Test that score never goes above 100.""" - scorer = ConfidenceScorer() - result = ScanResult(files_scanned=10, target_path="/test") - score = scorer.calculate(result) - assert score <= 100 - - -class TestIssueModel: - """Tests for Issue data model.""" - - def test_issue_to_dict(self): - """Test issue serialization to dictionary.""" - issue = Issue( - severity=SeverityLevel.HIGH, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=10, - message="Test issue", - suggestion="Fix this", - scanner_name="test", - ) - - data = issue.to_dict() - - assert data["severity"] == "high" - assert data["category"] == "security" - assert data["file_path"] == "/test.py" - assert data["line_number"] == 10 - assert data["message"] == "Test issue" - assert data["suggestion"] == "Fix this" - assert data["scanner_name"] == "test" - - -class TestScanResultModel: - """Tests for ScanResult data model.""" - - def test_add_issue(self): - """Test adding issues to scan result.""" - result = ScanResult(files_scanned=1, target_path="/test") - issue = Issue( - severity=SeverityLevel.LOW, - category=IssueCategory.STYLE, - file_path="/test.py", - line_number=1, - message="Style issue", - scanner_name="test", - ) - - result.add_issue(issue) - - assert len(result.issues) == 1 - assert result.issues[0] == issue - - def test_add_warning(self): - """Test adding warnings to scan result.""" - result = ScanResult(files_scanned=1, target_path="/test") - result.add_warning("Test warning") - - assert len(result.warnings) == 1 - assert result.warnings[0] == "Test warning" - - def test_filter_by_severity(self): - """Test filtering issues by severity.""" - result = ScanResult(files_scanned=1, target_path="/test") - result.add_issue(Issue( - severity=SeverityLevel.LOW, - category=IssueCategory.STYLE, - file_path="/test.py", - line_number=1, - message="Low issue", - scanner_name="test", - )) - result.add_issue(Issue( - severity=SeverityLevel.CRITICAL, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=2, - message="Critical issue", - scanner_name="test", - )) - - filtered = result.filter_by_severity(SeverityLevel.HIGH) - - assert len(filtered.issues) == 1 - assert filtered.issues[0].severity == SeverityLevel.CRITICAL - - def test_get_summary(self): - """Test getting scan summary.""" - result = ScanResult(files_scanned=2, target_path="/test") - result.add_issue(Issue( - severity=SeverityLevel.HIGH, - category=IssueCategory.SECURITY, - file_path="/test.py", - line_number=1, - message="Issue 1", - scanner_name="test", - )) - result.add_issue(Issue( - severity=SeverityLevel.LOW, - category=IssueCategory.STYLE, - file_path="/test.py", - line_number=2, - message="Issue 2", - scanner_name="test", - )) - - summary = result.get_summary() - - assert summary["files_scanned"] == 2 - assert summary["total_issues"] == 2 - assert "high" in summary["issues_by_severity"] - assert "low" in summary["issues_by_severity"] - assert "security" in summary["issues_by_category"] - assert "style" in summary["issues_by_category"] - - def test_to_dict(self): - """Test scan result serialization to dictionary.""" - result = ScanResult(files_scanned=1, target_path="/test") - result.add_issue(Issue( - severity=SeverityLevel.MEDIUM, - category=IssueCategory.CODE_QUALITY, - file_path="/test.py", - line_number=5, - message="Test issue", - scanner_name="test", - )) - - data = result.to_dict() - - assert data["files_scanned"] == 1 - assert data["target_path"] == "/test" - assert len(data["issues"]) == 1 - assert data["issues"][0]["severity"] == "medium"