import pytest
from unittest import mock
from src.jixia.engines.openbb_stock_data import get_stock_data
from types import SimpleNamespace

class TestOpenBBIntegration:
    """OpenBB集成测试套件"""

    def test_stock_data_retrieval(self):
        """测试股票数据成功获取"""
        # 创建一个模拟的'openbb'模块
        mock_openbb_module = mock.MagicMock()
        # 在该模块上创建一个模拟的'obb'属性
        mock_obb_object = mock.MagicMock()
        mock_openbb_module.obb = mock_obb_object

        # 配置模拟的obb对象的返回值
        mock_data = [
            SimpleNamespace(date='2023-01-01', open=100, high=110, low=90, close=105, volume=10000),
            SimpleNamespace(date='2023-01-02', open=105, high=115, low=102, close=112, volume=12000)
        ]
        mock_obb_object.equity.price.historical.return_value = SimpleNamespace(results=mock_data)

        # 使用patch.dict来模拟openbb模块的导入
        with mock.patch.dict('sys.modules', {'openbb': mock_openbb_module}):
            data = get_stock_data('AAPL')

        # 断言
        assert data is not None
        assert len(data) == 2
        assert data[0].close == 105
        mock_obb_object.equity.price.historical.assert_called_once()

    def test_stock_data_handles_api_error(self):
        """测试当OpenBB API未返回有效数据时的情况"""
        mock_openbb_module = mock.MagicMock()
        mock_obb_object = mock.MagicMock()
        mock_openbb_module.obb = mock_obb_object
        
        # 配置模拟的obb对象以返回没有结果的情况
        mock_obb_object.equity.price.historical.return_value = SimpleNamespace(results=None)

        with mock.patch.dict('sys.modules', {'openbb': mock_openbb_module}):
            data = get_stock_data('FAIL')

        # 断言
        assert data is None
        mock_obb_object.equity.price.historical.assert_called_once_with(
            symbol='FAIL', 
            provider='yfinance',
            start_date=mock.ANY,
            end_date=mock.ANY
        )

    def test_stock_data_handles_import_error(self):
        """测试openbb库不可用时的降级行为"""
        # 模拟sys.modules中没有openbb
        with mock.patch.dict('sys.modules', {'openbb': None}):
            data = get_stock_data('NOBB')

        # 断言
        assert data is None