File size: 5,168 Bytes
fb03795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import sys
import os
import unittest
from unittest.mock import MagicMock, patch
import json

# Mock Gradio before importing app
sys.modules['gradio'] = MagicMock()
sys.modules['gradio'].__version__ = "4.0.0"

# Mock other dependencies that might cause issues in this environment
sys.modules['plotly.graph_objects'] = MagicMock()

# Import app
import app

class TestUIFix(unittest.TestCase):
    def setUp(self):
        # Mock the trading AI and its components
        app.trading_ai = MagicMock()
        app.trading_ai.analyze_and_trade.return_value = {
            'market_data': {'price': 150.0, 'change_24h': 5.0, 'rsi': 60},
            'ai_decision': {'action': 'LONG', 'confidence': 0.8, 'reason': 'Test reason'},
            'execution_result': {'status': 'Executed'},
            'portfolio_status': {'paper_balance': 10000},
            'learning_stats': {},
            'active_positions': []
        }
        app.trading_ai.get_market_data.return_value = {'price': 150.0, 'change_24h': 5.0}
        app.trading_ai.learner.thinking_log = [{'decision': {'action': 'LONG', 'confidence': 0.8, 'reason': 'Test reason'}}]
        app.trading_ai.learner.last_api_input = "Test Input"
        app.trading_ai.learner.last_api_output = "Test Output"
        
        # Mock portfolio manager
        app.trading_ai.portfolio.position_manager.active_positions = {
            'pos1': {
                'symbol': 'SOL/USD',
                'action': 'LONG',
                'entry_price': 140.0,
                'current_price': 150.0,
                'unrealized_pnl_percent': 7.14,
                'unrealized_pnl': 50.0,
                'size_percent': 10
            }
        }
        app.trading_ai.portfolio.position_manager.closed_positions = []
        app.trading_ai.portfolio.real_wallet.get_balance_info.return_value = {
            'wallet_balance_sol': 10.0,
            'trading_balance_sol': 5.0,
            'estimated_usd_value': 1500.0
        }
        app.trading_ai.portfolio.update_all_positions.return_value = {'paper_balance': 10000}
        app.trading_ai.portfolio.get_portfolio_status.return_value = {'paper_balance': 10000}
        
        # Mock create_closed_positions_table
        app.create_closed_positions_table = MagicMock(return_value=[])

    def test_autonomous_trade_cycle_return_types(self):
        # Create interface to trigger the definition of the function
        demo = app.create_interface()
        
        # Get the function passed to demo.load
        # demo.load is a mock, so we can check call_args
        # The call is demo.load(fn=autonomous_trade_cycle, ...)
        # We need to find the call to load
        
        # Since demo is the return value of create_interface, and create_interface returns 'demo' which is a MagicMock (from gr.Blocks context manager)
        # We need to see how gr.Blocks works in the mock.
        # with gr.Blocks() as demo: -> demo is the context manager's enter return value.
        
        # Let's assume app.create_interface returns the mock object that .load was called on.
        # We need to inspect the calls to that mock.
        
        # In app.py:
        # with gr.Blocks(...) as demo:
        #    ...
        #    demo.load(...)
        # return demo
        
        # So 'demo' returned by create_interface IS the mock that .load was called on.
        
        # Find the call to load
        load_call = None
        for call in demo.load.call_args_list:
            if 'fn' in call.kwargs:
                load_call = call
                break
            # If passed as positional arg, fn is the first one
            if len(call.args) > 0:
                load_call = call
                break
        
        if not load_call:
            self.fail("Could not find call to demo.load")
            
        # Get the function
        autonomous_trade_cycle = load_call.kwargs.get('fn') or load_call.args[0]
        
        # Run the cycle
        outputs = autonomous_trade_cycle('SOL/USD', 'PAPER')
        
        # Unpack outputs (there should be 11)
        (
            thinking_text,
            market_price,
            ai_confidence,
            ai_action,
            ai_reason,
            last_execution,
            portfolio_status,
            active_positions_table,
            closed_positions_table,
            wallet_info,
            system_logs
        ) = outputs
        
        print("Verifying outputs...")
        
        # Check types
        self.assertIsInstance(last_execution, dict, "last_execution should be a dict, not a string")
        self.assertIsInstance(portfolio_status, dict, "portfolio_status should be a dict, not a string")
        self.assertIsInstance(wallet_info, str, "wallet_info should be a string (Markdown)")
        
        # Check for HF Logo in active positions
        print(f"Active Positions Table: {active_positions_table}")
        self.assertTrue(len(active_positions_table) > 0, "Should have active positions")
        self.assertIn("huggingface_logo", active_positions_table[0][0], "First column should contain HF logo URL")

if __name__ == '__main__':
    unittest.main()