import pytest
from unittest.mock import AsyncMock, patch, mock_open
from cve_checker.dependency_scanner import DependencyScanner
from cve_checker.cve_data_fetcher import CVEDataFetcher

@pytest.fixture
def dependency_scanner():
    mock_cve_data_fetcher = AsyncMock(spec=CVEDataFetcher)
    return DependencyScanner(mock_cve_data_fetcher)

def test_parse_requirements_txt(dependency_scanner):
    mock_file_content = "package1==1.0.0\npackage2==2.0.0\n"
    with patch("builtins.open", mock_open(read_data=mock_file_content)):
        result = dependency_scanner._parse_requirements_txt("requirements.txt")
    assert result == {"package1": "1.0.0", "package2": "2.0.0"}

def test_parse_package_json(dependency_scanner):
    mock_file_content = '{"dependencies": {"package1": "1.0.0"}, "devDependencies": {"package2": "2.0.0"}}'
    with patch("builtins.open", mock_open(read_data=mock_file_content)):
        result = dependency_scanner._parse_package_json("package.json")
    assert result == {"package1": "1.0.0", "package2": "2.0.0"}

def test_parse_yaml_file(dependency_scanner):
    mock_file_content = "dependencies:\n  package1: 1.0.0\n  package2: 2.0.0\n"
    with patch("builtins.open", mock_open(read_data=mock_file_content)):
        result = dependency_scanner._parse_yaml_file("dependencies.yaml")
    assert result == {"package1": "1.0.0", "package2": "2.0.0"}

def test_parse_toml_file(dependency_scanner):
    mock_file_content = '[dependencies]\npackage1 = "1.0.0"\npackage2 = "2.0.0"\n'
    with patch("builtins.open", mock_open(read_data=mock_file_content)):
        result = dependency_scanner._parse_toml_file("pyproject.toml")
    assert result == {"package1": "1.0.0", "package2": "2.0.0"}

@pytest.mark.asyncio
async def test_scan_dependencies(dependency_scanner):
    mock_vulnerabilities = {
        "package1": [{"cve_id": "CVE-2021-1234", "description": "Test vulnerability"}]
    }
    
    async def mock_check_vulnerabilities(package, version):
        return mock_vulnerabilities.get(package, [])

    dependency_scanner.vulnerability_checker.check_vulnerabilities = AsyncMock(side_effect=mock_check_vulnerabilities)
    
    with patch.object(dependency_scanner, '_parse_dependency_file', return_value={"package1": "1.0.0", "package2": "2.0.0"}):
        result = await dependency_scanner.scan_dependencies("requirements.txt")
    
    assert result == mock_vulnerabilities
    dependency_scanner.vulnerability_checker.check_vulnerabilities.assert_any_call("package1", "1.0.0")
    dependency_scanner.vulnerability_checker.check_vulnerabilities.assert_any_call("package2", "2.0.0")
