rmi-backend/tests/unit/test_insider_network.py
opencode c762564d40 style(rmi-backend): complete lint cleanup — 1175→0 ruff errors
- Fix 71 invalid-syntax files (class-body newline-broken assignments)
- Add from/None chain to 307 B904 raise-without-from sites
- Add B008 ignore to ruff.toml (already in pyproject.toml)
- Noqa F401 on __init__.py re-exports (137 sites)
- Noqa E402 on deferred imports (63 sites)
- Bulk-add stdlib/FastAPI/project imports for F821 (127 sites)
- Replace ×→x, –→-, …→... in docstrings (4093 chars)
- Manual refactor of 5 SIM103/SIM116 patterns

Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py)
Co-authored-by: opencode <opencode@rugmunch.io>
2026-07-06 15:43:20 +02:00

403 lines
13 KiB
Python

"""
Tests for insider_network.py - Insider Web Mapper.
"""
from unittest.mock import patch
import pytest
from app.insider_network import (
InsiderCluster,
InsiderLink,
InsiderNetworkAnalyzer,
InsiderNetworkReport,
_compute_cluster_risk,
_detect_co_deployer,
_detect_co_trading,
_detect_shared_funding,
_detect_value_transfers,
_truncate_address,
analyze_insider_network,
format_insider_network_report,
is_valid_address,
)
# ── Address Validation Tests ──────────────────────────────────────
def test_is_valid_address_solana():
"""Valid Solana address (base58, 32-44 chars)."""
assert is_valid_address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") is True
def test_is_valid_address_evm():
"""Valid EVM address (0x + 40 hex chars)."""
assert is_valid_address("0xdAC17F958D2ee523a2206206994597C13D831ec7") is True
def test_is_valid_address_empty():
"""Empty string is invalid."""
assert is_valid_address("") is False
def test_is_valid_address_none():
"""None is invalid."""
assert is_valid_address(None) is False
def test_is_valid_address_invalid():
"""Garbage string is invalid."""
assert is_valid_address("not-a-valid-address") is False
def test_is_valid_address_eip55_checksum():
"""Mixed-case EIP-55 compliant address passes."""
assert is_valid_address("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B") is True
def test_is_valid_address_eip55_lowercase():
"""All-lowercase EVM address is valid."""
assert is_valid_address("0xdac17f958d2ee523a2206206994597c13d831ec7") is True
def test_is_valid_address_solana_valid():
"""Valid Solana address passes."""
assert is_valid_address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") is True
# ── _truncate_address Tests ──────────────────────────────────────
def test_truncate_long_address():
"""Long address gets truncated."""
addr = "0xdAC17F958D2ee523a2206206994597C13D831ec7"
result = _truncate_address(addr)
assert result == "0xdAC1...1ec7"
assert len(result) == 13
def test_truncate_short_address():
"""Short address is not truncated."""
assert _truncate_address("0x1234") == "0x1234"
# ── InsiderLink Tests ────────────────────────────────────────────
def test_insider_link_defaults():
"""InsiderLink defaults are set correctly."""
link = InsiderLink(
source_wallet="0xaaa",
target_wallet="0xbbb",
relationship_type="shared_funding",
)
assert link.strength == 0.0
assert link.evidence == []
assert link.first_seen == ""
assert link.last_seen == ""
def test_insider_link_with_values():
"""InsiderLink with all fields set."""
link = InsiderLink(
source_wallet="0xaaa",
target_wallet="0xbbb",
relationship_type="co_trading",
strength=0.75,
evidence=["Traded same token"],
first_seen="2024-01-01",
last_seen="2024-06-01",
)
assert link.strength == 0.75
assert "Traded same token" in link.evidence
# ── InsiderCluster Tests ──────────────────────────────────────────
def test_insider_cluster_defaults():
"""InsiderCluster defaults are set correctly."""
cluster = InsiderCluster(cluster_id="INSIDER-0001")
assert cluster.wallets == []
assert cluster.projects_involved == []
assert cluster.risk_score == 0.0
assert cluster.member_count == 0
def test_insider_cluster_member_count():
"""Member count reflects wallet list."""
cluster = InsiderCluster(
cluster_id="INSIDER-0001",
wallets=["0xaaa", "0xbbb", "0xccc"],
member_count=3,
)
assert cluster.member_count == 3
# ── InsiderNetworkReport Tests ────────────────────────────────────
def test_report_defaults():
"""InsiderNetworkReport defaults are correct."""
report = InsiderNetworkReport(target_wallet="0xaaa")
assert report.target_wallet == "0xaaa"
assert report.clusters == []
assert report.total_connected_wallets == 0
assert report.total_clusters == 0
assert report.highest_risk_score == 0.0
# ── Relationship Detection Tests ──────────────────────────────────
def test_detect_shared_funding():
"""Detect wallets sharing a common funder."""
wallets = ["0xaaa", "0xbbb", "0xccc"]
tx_data = {
"0xaaa": [
{
"from": "0xfunder1",
"to": "0xaaa",
"value": "1000000000000000000",
}
],
"0xbbb": [
{
"from": "0xfunder1",
"to": "0xbbb",
"value": "500000000000000000",
}
],
"0xccc": [
{
"from": "0xfunder2",
"to": "0xccc",
"value": "300000000000000000",
}
],
}
links = _detect_shared_funding(wallets, tx_data)
assert len(links) >= 1
link_found = False
for link in links:
if (
link.source_wallet in ("0xaaa", "0xbbb")
and link.target_wallet in ("0xaaa", "0xbbb")
and link.source_wallet != link.target_wallet
):
link_found = True
break
assert link_found, "Expected link between 0xaaa and 0xbbb (shared funder)"
def test_detect_co_trading():
"""Detect wallets trading the same tokens."""
wallets = ["0xaaa", "0xbbb", "0xddd"]
tx_data = {
"0xaaa": [{"contractAddress": "0xtoken1", "from": "0xaaa", "to": "0xeee"}],
"0xbbb": [{"contractAddress": "0xtoken1", "from": "0xbbb", "to": "0xfff"}],
"0xddd": [{"contractAddress": "0xtoken2", "from": "0xddd", "to": "0xggg"}],
}
links = _detect_co_trading(wallets, tx_data)
assert len(links) >= 1
def test_detect_value_transfers():
"""Detect direct value transfers between cluster wallets."""
wallets = ["0xaaa", "0xbbb", "0xccc"]
tx_data = {
"0xaaa": [
{
"from": "0xaaa",
"to": "0xbbb",
"value": "10000000000000000000",
"hash": "0xh1",
}
],
"0xbbb": [
{
"from": "0xbbb",
"to": "0xccc",
"value": "5000000000000000000",
"hash": "0xh2",
}
],
"0xccc": [],
}
links = _detect_value_transfers(wallets, tx_data)
assert len(links) >= 1
pair_set = {(link.source_wallet, link.target_wallet) for link in links}
assert ("0xaaa", "0xbbb") in pair_set or ("0xbbb", "0xaaa") in pair_set
def test_detect_co_deployer():
"""Detect wallets created by the same deployer."""
wallets = ["0xaaa", "0xbbb", "0xccc"]
tx_data = {
"0xaaa": [
{
"from": "0xdeployer1",
"to": "0xaaa",
"value": "0",
"hash": "0xh1",
}
],
"0xbbb": [
{
"from": "0xdeployer1",
"to": "0xbbb",
"value": "0",
"hash": "0xh2",
}
],
"0xccc": [
{
"from": "0xdeployer2",
"to": "0xccc",
"value": "0",
"hash": "0xh3",
}
],
}
links = _detect_co_deployer(wallets, tx_data)
assert len(links) >= 1
link_found = False
for link in links:
if (
link.source_wallet in ("0xaaa", "0xbbb")
and link.target_wallet in ("0xaaa", "0xbbb")
and link.source_wallet != link.target_wallet
):
link_found = True
break
assert link_found, "Expected link between 0xaaa and 0xbbb (shared deployer)"
# ── Cluster Risk Computation Tests ────────────────────────────────
def test_compute_cluster_risk_no_links():
"""Empty links = zero risk."""
cluster = InsiderCluster(cluster_id="INSIDER-0001", wallets=["0xaaa", "0xbbb"])
risk = _compute_cluster_risk(cluster, [])
assert risk == 0.0
def test_compute_cluster_risk_dense():
"""Dense links produce higher risk."""
cluster = InsiderCluster(
cluster_id="INSIDER-0002",
wallets=["0xaaa", "0xbbb", "0xccc"],
)
links = [
InsiderLink("0xaaa", "0xbbb", "co_deploy", 0.6),
InsiderLink("0xaaa", "0xccc", "co_deploy", 0.6),
InsiderLink("0xbbb", "0xccc", "value_transfer", 0.8),
]
risk = _compute_cluster_risk(cluster, links)
assert risk > 30.0
def test_compute_cluster_risk_single():
"""Single link produces minimal risk."""
cluster = InsiderCluster(
cluster_id="INSIDER-0003",
wallets=["0xaaa", "0xbbb"],
)
links = [
InsiderLink("0xaaa", "0xbbb", "co_trading", 0.4),
]
risk = _compute_cluster_risk(cluster, links)
assert risk > 0.0
assert risk < 50.0
# ── Formatting Tests ──────────────────────────────────────────────
def test_format_report_no_clusters():
"""Report with no clusters shows clean message."""
report = InsiderNetworkReport(target_wallet="0xabc123...def456")
formatted = format_insider_network_report(report)
assert "No insider networks detected" in formatted
assert "INSIDER NETWORK ANALYSIS REPORT" in formatted
def test_format_report_with_clusters():
"""Report with clusters includes cluster details."""
report = InsiderNetworkReport(target_wallet="0xabc123...def456")
cluster = InsiderCluster(
cluster_id="INSIDER-0001",
wallets=["0xaaa", "0xbbb", "0xccc"],
member_count=3,
risk_score=65.0,
projects_involved=["ProjectA", "ProjectB"],
risk_factors=["High coordination density"],
)
cluster.top_relationships.append(
{
"from": "0xaaa",
"to": "0xbbb",
"type": "shared_funding",
"strength": 0.8,
}
)
report.clusters.append(cluster)
report.total_clusters = 1
report.total_connected_wallets = 3
report.highest_risk_score = 65.0
formatted = format_insider_network_report(report)
assert "INSIDER-0001" in formatted
assert "65" in formatted
assert "ProjectA" in formatted or "ProjectB" in formatted
# ── Integration Tests (mocked) ────────────────────────────────────
@pytest.mark.asyncio
async def test_analyze_insider_network_invalid_address():
"""Invalid address raises ValueError."""
with pytest.raises(ValueError, match="Invalid wallet address"):
await analyze_insider_network("not-valid")
@pytest.mark.asyncio
async def test_analyze_insider_network_empty_result():
"""Even with mocked empty responses, returns a valid report."""
with (
patch("app.insider_network._fetch_wallet_transactions", return_value=[]),
patch("app.insider_network._fetch_token_transfers", return_value=[]),
):
report = await analyze_insider_network(
"0xdAC17F958D2ee523a2206206994597C13D831ec7",
chains=["ethereum"],
)
assert isinstance(report, InsiderNetworkReport)
assert report.target_wallet == "0xdAC17F958D2ee523a2206206994597C13D831ec7"
assert report.total_connected_wallets == 0
assert report.total_clusters == 0
# ── InsiderNetworkAnalyzer Tests ──────────────────────────────────
@pytest.mark.asyncio
async def test_analyzer_class():
"""InsiderNetworkAnalyzer wrapper works."""
with patch("app.insider_network.analyze_insider_network") as mock_fn:
mock_report = InsiderNetworkReport(target_wallet="0xtest", total_connected_wallets=5)
mock_fn.return_value = mock_report
analyzer = InsiderNetworkAnalyzer()
result = await analyzer.analyze("0xtest")
assert result.total_connected_wallets == 5
mock_fn.assert_called_once()
def test_analyzer_format_report():
"""Static format method works."""
report = InsiderNetworkReport(target_wallet="0xabc")
result = InsiderNetworkAnalyzer.format_report(report)
assert "INSIDER NETWORK ANALYSIS REPORT" in result