import logging import unittest from unittest.mock import MagicMock, patch, PropertyMock from datetime import datetime from ExchangeInterface import ExchangeInterface from Exchange import Exchange from DataCache_v3 import DataCache from typing import Dict, Any logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) class Trade: """ Mock Trade class to simulate trade objects used in the tests. """ def __init__(self, target, symbol, order_id): self.target = target self.symbol = symbol self.order = MagicMock(orderId=order_id) class TestExchangeInterface(unittest.TestCase): def setUp(self): self.cache_manager = DataCache() self.exchange_interface = ExchangeInterface(self.cache_manager) # Setup test data self.user_name = "test_user" self.exchange_name = "binance" self.api_keys = {'key': 'test_key', 'secret': 'test_secret'} # Mock trade object self.trade = Trade(target=self.exchange_name, symbol="BTC/USDT", order_id="12345") # Example order data self.order_data: Dict[str, Any] = { 'status': 'closed', 'filled': 1.0, 'average': 50000.0 } def test_get_trade_status(self): """Test getting trade status with mocked exchange.""" mock_exchange = MagicMock() mock_exchange.get_order.return_value = self.order_data # Mock get_exchange to return our mock with patch.object(self.exchange_interface, 'get_exchange', return_value=mock_exchange): status = self.exchange_interface.get_trade_info(self.trade, self.user_name, 'status') self.assertEqual(status, 'closed') def test_get_trade_executed_qty(self): """Test getting executed quantity with mocked exchange.""" mock_exchange = MagicMock() mock_exchange.get_order.return_value = self.order_data with patch.object(self.exchange_interface, 'get_exchange', return_value=mock_exchange): executed_qty = self.exchange_interface.get_trade_info(self.trade, self.user_name, 'executed_qty') self.assertEqual(executed_qty, 1.0) def test_get_trade_executed_price(self): """Test getting executed price with mocked exchange.""" mock_exchange = MagicMock() mock_exchange.get_order.return_value = self.order_data with patch.object(self.exchange_interface, 'get_exchange', return_value=mock_exchange): executed_price = self.exchange_interface.get_trade_info(self.trade, self.user_name, 'executed_price') self.assertEqual(executed_price, 50000.0) def test_invalid_info_type(self): """Test invalid info type returns None.""" mock_exchange = MagicMock() mock_exchange.get_order.return_value = self.order_data with patch.object(self.exchange_interface, 'get_exchange', return_value=mock_exchange): with self.assertLogs(level='ERROR') as log: result = self.exchange_interface.get_trade_info(self.trade, self.user_name, 'invalid_type') self.assertIsNone(result) self.assertTrue(any('Invalid info type' in message for message in log.output)) def test_order_not_found(self): """Test order not found returns None.""" mock_exchange = MagicMock() mock_exchange.get_order.return_value = None with patch.object(self.exchange_interface, 'get_exchange', return_value=mock_exchange): with self.assertLogs(level='ERROR') as log: result = self.exchange_interface.get_trade_info(self.trade, self.user_name, 'status') self.assertIsNone(result) self.assertTrue(any('not found' in message for message in log.output)) def test_get_price_default_source(self): """Test get_price with default exchange.""" mock_exchange = MagicMock() mock_exchange.get_price.return_value = 50000.0 with patch.object(self.exchange_interface, 'connect_default_exchange'): self.exchange_interface.default_exchange = mock_exchange price = self.exchange_interface.get_price("BTC/USDT") self.assertEqual(price, 50000.0) def test_get_price_with_invalid_exchange(self): """Test get_price with invalid exchange name returns 0.""" # Unknown exchange should return 0.0 price = self.exchange_interface.get_price("BTC/USDT", exchange_name="invalid_exchange_xyz") self.assertEqual(price, 0.0) if __name__ == '__main__': unittest.main()