| """ |
| Tests for Contract Scanner |
| ========================== |
| """ |
|
|
| import asyncio |
| import pytest |
| from app.contract_scan import ContractScanner, RiskLevel, FindingType |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_scanner_init(): |
| """Test scanner initialization.""" |
| scanner = ContractScanner() |
| assert scanner is not None |
| await scanner.close() |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_scan_invalid_address(): |
| """Test that invalid addresses raise errors.""" |
| scanner = ContractScanner() |
| try: |
| with pytest.raises(ValueError): |
| await scanner.scan("invalid", "ethereum") |
| finally: |
| await scanner.close() |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_scan_unsupported_chain(): |
| """Test that unsupported chains raise errors.""" |
| scanner = ContractScanner() |
| try: |
| with pytest.raises(ValueError): |
| await scanner.scan("0x1234567890123456789012345678901234567890", "invalid_chain") |
| finally: |
| await scanner.close() |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_scan_valid_contract(): |
| """Test scanning a valid contract address.""" |
| |
| scanner = ContractScanner() |
| try: |
| result = await scanner.scan( |
| "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", |
| "ethereum" |
| ) |
| assert result.contract_address == "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48" |
| assert result.chain == "ethereum" |
| assert result.score >= 0 |
| assert result.risk_level in RiskLevel |
| assert isinstance(result.findings, list) |
| finally: |
| await scanner.close() |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_findings_format(): |
| """Test that findings have correct format.""" |
| scanner = ContractScanner() |
| try: |
| result = await scanner.scan( |
| "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606EB48", |
| "ethereum" |
| ) |
| for finding in result.findings: |
| assert hasattr(finding, 'finding_type') |
| assert hasattr(finding, 'severity') |
| assert hasattr(finding, 'description') |
| assert isinstance(finding.to_dict(), dict) |
| finally: |
| await scanner.close() |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_scanner_multiple_chains(): |
| """Test scanner works on multiple chains.""" |
| scanner = ContractScanner() |
| try: |
| |
| for chain in ["base", "arbitrum", "bsc"]: |
| result = await scanner.scan( |
| "0x1234567890123456789012345678901234567890", |
| chain |
| ) |
| assert result.chain == chain |
| finally: |
| await scanner.close() |
|
|
|
|
| if __name__ == "__main__": |
| asyncio.run(test_scan_valid_contract()) |
| print("All tests passed!") |