170
tests/unit/test_analyzers.py
Normal file
170
tests/unit/test_analyzers.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""Tests for CVE and version analyzers."""
|
||||
|
||||
import pytest
|
||||
|
||||
from depcheck.analyzers.cve import CVEAnalyzer, load_cve_database
|
||||
from depcheck.analyzers.version import VersionAnalyzer
|
||||
from depcheck.models import Dependency, PackageManager, Severity, Vulnerability
|
||||
|
||||
|
||||
class TestCVEAnalyzer:
|
||||
"""Tests for CVE analyzer."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.db = {
|
||||
"cves": [
|
||||
{
|
||||
"package": "lodash",
|
||||
"cve_id": "CVE-2021-23337",
|
||||
"severity": "high",
|
||||
"description": "Command Injection",
|
||||
"affected_versions": "<4.17.21",
|
||||
"fixed_version": "4.17.21",
|
||||
},
|
||||
{
|
||||
"package": "requests",
|
||||
"cve_id": "CVE-2024-35195",
|
||||
"severity": "medium",
|
||||
"description": "Auth bypass",
|
||||
"affected_versions": "<2.32.0",
|
||||
"fixed_version": "2.32.0",
|
||||
},
|
||||
],
|
||||
"version_warnings": [
|
||||
{
|
||||
"package": "moment",
|
||||
"message": "Consider migrating",
|
||||
"min_safe": "2.29.4",
|
||||
}
|
||||
],
|
||||
}
|
||||
self.analyzer = CVEAnalyzer(self.db)
|
||||
|
||||
def test_detects_vulnerable_version(self):
|
||||
"""Test that vulnerable versions are detected."""
|
||||
dep = Dependency(
|
||||
name="lodash",
|
||||
current_version="4.17.20",
|
||||
package_manager=PackageManager.NPM,
|
||||
)
|
||||
|
||||
vulns = self.analyzer.analyze(dep)
|
||||
|
||||
assert len(vulns) == 1
|
||||
assert vulns[0].cve_id == "CVE-2021-23337"
|
||||
assert vulns[0].severity == Severity.HIGH
|
||||
|
||||
def test_detects_safe_version(self):
|
||||
"""Test that safe versions are not flagged."""
|
||||
dep = Dependency(
|
||||
name="lodash",
|
||||
current_version="4.17.21",
|
||||
package_manager=PackageManager.NPM,
|
||||
)
|
||||
|
||||
vulns = self.analyzer.analyze(dep)
|
||||
|
||||
assert len(vulns) == 0
|
||||
|
||||
def test_unknown_package_returns_empty(self):
|
||||
"""Test that unknown packages return no vulnerabilities."""
|
||||
dep = Dependency(
|
||||
name="unknown-package",
|
||||
current_version="1.0.0",
|
||||
package_manager=PackageManager.NPM,
|
||||
)
|
||||
|
||||
vulns = self.analyzer.analyze(dep)
|
||||
|
||||
assert len(vulns) == 0
|
||||
|
||||
def test_load_bundled_database(self):
|
||||
"""Test loading bundled CVE database."""
|
||||
db = load_cve_database()
|
||||
assert "cves" in db
|
||||
assert "version_warnings" in db
|
||||
|
||||
def test_version_warning(self):
|
||||
"""Test version warning check."""
|
||||
dep = Dependency(
|
||||
name="moment",
|
||||
current_version="2.29.3",
|
||||
package_manager=PackageManager.NPM,
|
||||
)
|
||||
|
||||
warning = self.analyzer.check_version_warning(dep)
|
||||
|
||||
assert warning is not None
|
||||
assert "migrating" in warning.lower()
|
||||
|
||||
def test_safe_version_no_warning(self):
|
||||
"""Test that safe versions don't trigger warnings."""
|
||||
dep = Dependency(
|
||||
name="moment",
|
||||
current_version="2.29.4",
|
||||
package_manager=PackageManager.NPM,
|
||||
)
|
||||
|
||||
warning = self.analyzer.check_version_warning(dep)
|
||||
|
||||
assert warning is None
|
||||
|
||||
|
||||
class TestVersionAnalyzer:
|
||||
"""Tests for version analyzer."""
|
||||
|
||||
def setup_method(self):
|
||||
"""Set up test fixtures."""
|
||||
self.analyzer = VersionAnalyzer()
|
||||
|
||||
def test_update_type_major(self):
|
||||
"""Test major version bump detection."""
|
||||
result = self.analyzer.get_update_type("1.0.0", "2.0.0")
|
||||
assert result == "major"
|
||||
|
||||
def test_update_type_minor(self):
|
||||
"""Test minor version bump detection."""
|
||||
result = self.analyzer.get_update_type("1.0.0", "1.1.0")
|
||||
assert result == "minor"
|
||||
|
||||
def test_update_type_patch(self):
|
||||
"""Test patch version bump detection."""
|
||||
result = self.analyzer.get_update_type("1.0.0", "1.0.1")
|
||||
assert result == "patch"
|
||||
|
||||
def test_compare_versions_greater(self):
|
||||
"""Test version comparison - v1 > v2."""
|
||||
result = self.analyzer.compare_versions("2.0.0", "1.0.0")
|
||||
assert result == 1
|
||||
|
||||
def test_compare_versions_less(self):
|
||||
"""Test version comparison - v1 < v2."""
|
||||
result = self.analyzer.compare_versions("1.0.0", "2.0.0")
|
||||
assert result == -1
|
||||
|
||||
def test_compare_versions_equal(self):
|
||||
"""Test version comparison - equal."""
|
||||
result = self.analyzer.compare_versions("1.0.0", "1.0.0")
|
||||
assert result == 0
|
||||
|
||||
def test_suggest_safe_upgrade_major(self):
|
||||
"""Test major upgrade suggestion."""
|
||||
result = self.analyzer.suggest_safe_upgrade("1.0.0", "major")
|
||||
assert result == "2.0.0"
|
||||
|
||||
def test_suggest_safe_upgrade_minor(self):
|
||||
"""Test minor upgrade suggestion."""
|
||||
result = self.analyzer.suggest_safe_upgrade("1.0.0", "minor")
|
||||
assert result == "1.1.0"
|
||||
|
||||
def test_suggest_safe_upgrade_patch(self):
|
||||
"""Test patch upgrade suggestion."""
|
||||
result = self.analyzer.suggest_safe_upgrade("1.0.0", "patch")
|
||||
assert result == "1.0.1"
|
||||
|
||||
def test_severity_for_update(self):
|
||||
"""Test mapping update type to severity."""
|
||||
assert self.analyzer.get_severity_for_update("major") == Severity.HIGH
|
||||
assert self.analyzer.get_severity_for_update("minor") == Severity.MEDIUM
|
||||
assert self.analyzer.get_severity_for_update("patch") == Severity.LOW
|
||||
Reference in New Issue
Block a user