Skip to content

Commit db27548

Browse files
Create test_preflight.py
1 parent 4179234 commit db27548

1 file changed

Lines changed: 115 additions & 0 deletions

File tree

tests/tests/test_preflight.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
def _wallet_stub(chain, address):
2+
return {
3+
'chain': chain,
4+
'address_type': 'personal_wallet',
5+
'rpc_used': False,
6+
'details': 'stubbed for regression tests',
7+
}
8+
9+
10+
def test_preflight_requires_api_key(client):
11+
response = client.post('/api/preflight-check', json={})
12+
13+
assert response.status_code == 401
14+
assert response.get_json()['error'] == 'API key required for direct API access.'
15+
16+
17+
def test_preflight_network_mismatch_returns_block(client, api_headers, app_module, monkeypatch):
18+
monkeypatch.setattr(app_module, 'classify_address', _wallet_stub)
19+
20+
payload = {
21+
'expected': {
22+
'network': 'ethereum',
23+
'asset': 'USDT',
24+
'address': '0x1111111111111111111111111111111111111111',
25+
},
26+
'provided': {
27+
'network': 'arbitrum',
28+
'asset': 'USDT',
29+
'address': '0x1111111111111111111111111111111111111111',
30+
},
31+
}
32+
response = client.post('/api/preflight-check', json=payload, headers=api_headers)
33+
body = response.get_json()
34+
35+
assert response.status_code == 200
36+
assert body['reason_code'] == 'NETWORK_MISMATCH'
37+
assert body['verdict'] == 'BLOCK'
38+
assert body['next_action'] == 'BLOCK_AND_REVERIFY'
39+
assert 'NETWORK_MISMATCH' in body['risk_flags']
40+
41+
42+
def test_preflight_zero_address_returns_do_not_send(client, api_headers, app_module, monkeypatch):
43+
monkeypatch.setattr(app_module, 'classify_address', _wallet_stub)
44+
45+
payload = {
46+
'expected': {
47+
'network': 'ethereum',
48+
'asset': 'USDT',
49+
'address': '0x1111111111111111111111111111111111111111',
50+
},
51+
'provided': {
52+
'network': 'ethereum',
53+
'asset': 'USDT',
54+
'address': '0x0000000000000000000000000000000000000000',
55+
},
56+
}
57+
response = client.post('/api/preflight-check', json=payload, headers=api_headers)
58+
body = response.get_json()
59+
60+
assert response.status_code == 200
61+
assert body['reason_code'] == 'ZERO_ADDRESS'
62+
assert body['verdict'] == 'BLOCK'
63+
assert body['next_action'] == 'DO_NOT_SEND'
64+
assert 'ZERO_ADDRESS' in body['risk_flags']
65+
66+
67+
def test_preflight_unsupported_network_is_blocked(client, api_headers, app_module, monkeypatch):
68+
monkeypatch.setattr(app_module, 'classify_address', _wallet_stub)
69+
70+
payload = {
71+
'expected': {
72+
'network': 'tron',
73+
'asset': 'USDT',
74+
'address': 'TXYZ',
75+
},
76+
'provided': {
77+
'network': 'tron',
78+
'asset': 'USDT',
79+
'address': 'TXYZ',
80+
},
81+
}
82+
response = client.post('/api/preflight-check', json=payload, headers=api_headers)
83+
body = response.get_json()
84+
85+
assert response.status_code == 200
86+
assert body['reason_code'] == 'UNSUPPORTED_NETWORK'
87+
assert body['verdict'] == 'BLOCK'
88+
assert body['next_action'] == 'BLOCK_AND_REVERIFY'
89+
assert body['supported_scope']['provided_network_supported'] is False
90+
91+
92+
def test_preflight_missing_memo_stays_blocked(client, api_headers, app_module, monkeypatch):
93+
monkeypatch.setattr(app_module, 'classify_address', _wallet_stub)
94+
95+
payload = {
96+
'expected': {
97+
'network': 'solana',
98+
'asset': 'USDT',
99+
'address': '4Nd1m8H2Y9F4iRciMghvYDn8ApX2HFqRSbVSSMzdg3vT',
100+
'memo': '12345',
101+
},
102+
'provided': {
103+
'network': 'solana',
104+
'asset': 'USDT',
105+
'address': '4Nd1m8H2Y9F4iRciMghvYDn8ApX2HFqRSbVSSMzdg3vT',
106+
},
107+
}
108+
response = client.post('/api/preflight-check', json=payload, headers=api_headers)
109+
body = response.get_json()
110+
111+
assert response.status_code == 200
112+
assert body['reason_code'] == 'MEMO_MISMATCH'
113+
assert body['verdict'] == 'BLOCK'
114+
assert body['checks']['memo_match'] is False
115+
assert 'MEMO_MISMATCH' in body['risk_flags']

0 commit comments

Comments
 (0)