82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
"""Tests for the main mt5bridge exchange class."""
|
|
|
|
import responses
|
|
import pytest
|
|
|
|
import mt5bridge_ccxt
|
|
from mt5bridge_ccxt.exceptions import (
|
|
Mt5BridgeAuthError,
|
|
Mt5BridgeConnectionError,
|
|
Mt5BridgeNotConnectedError,
|
|
Mt5BridgeInvalidRequestError,
|
|
)
|
|
|
|
|
|
class TestMt5bridgeInit:
|
|
def test_id_and_name(self, exchange_config):
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
assert ex.id == "mt5bridge"
|
|
assert ex.name == "MT5 Bridge"
|
|
assert ex.apiKey == exchange_config["apiKey"]
|
|
assert ex.host == "http://mock-mt5bridge:8080"
|
|
|
|
def test_default_host(self):
|
|
ex = mt5bridge_ccxt.mt5bridge({"apiKey": "x"})
|
|
assert ex.host == "http://localhost:8080"
|
|
|
|
def test_timeframes(self, exchange_config):
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
assert "1m" in ex.timeframes
|
|
assert "1h" in ex.timeframes
|
|
assert "1d" in ex.timeframes
|
|
assert ex.timeframes["1h"] == "TIMEFRAME_H1"
|
|
|
|
def test_mql5_bridge_attached(self, exchange_config):
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
assert ex.mql5 is not None
|
|
assert hasattr(ex.mql5, "alpha_trend_signal")
|
|
|
|
def test_strip_slash_fallback(self):
|
|
ex = mt5bridge_ccxt.mt5bridge({
|
|
"apiKey": "x",
|
|
"host": "http://h:8080",
|
|
})
|
|
# Without symbol_map, falls back to stripping slash
|
|
assert ex._resolve_mt5_symbol("XAU/USD") == "XAUUSD"
|
|
assert ex._resolve_mt5_symbol("BTC/USDT") == "BTCUSDT"
|
|
|
|
def test_symbol_map_used(self, exchange_config):
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
assert ex._resolve_mt5_symbol("XAU/USD") == "XAUUSDc"
|
|
assert ex._resolve_mt5_symbol("EUR/USD") == "EURUSDc"
|
|
|
|
def test_reverse_symbol_map(self, exchange_config):
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
assert ex._resolve_ccxt_symbol("XAUUSDc") == "XAU/USD"
|
|
|
|
|
|
class TestErrorHandling:
|
|
@responses.activate
|
|
def test_401_raises_auth_error(self, exchange_config):
|
|
responses.add(responses.GET, "http://mock-mt5bridge:8080/account",
|
|
json={"detail": "Unauthorized"}, status=401)
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
with pytest.raises(Mt5BridgeAuthError):
|
|
ex.fetch_balance()
|
|
|
|
@responses.activate
|
|
def test_503_raises_not_connected(self, exchange_config):
|
|
responses.add(responses.GET, "http://mock-mt5bridge:8080/account",
|
|
json={"detail": "MT5 not connected"}, status=503)
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
with pytest.raises(Mt5BridgeNotConnectedError):
|
|
ex.fetch_balance()
|
|
|
|
@responses.activate
|
|
def test_400_raises_invalid_request(self, exchange_config):
|
|
responses.add(responses.GET, "http://mock-mt5bridge:8080/account",
|
|
json={"detail": "Bad symbol"}, status=400)
|
|
ex = mt5bridge_ccxt.mt5bridge(exchange_config)
|
|
with pytest.raises(Mt5BridgeInvalidRequestError):
|
|
ex.fetch_balance()
|