File size: 3,801 Bytes
26b9faa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79df050
26b9faa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79df050
26b9faa
 
 
79df050
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
測試 core/ai_client.py OpenAI 客戶端管理
"""

import pytest
from unittest.mock import patch, MagicMock


class TestAIClient:
    """測試 AI 客戶端模組"""

    def test_get_openai_client_no_api_key(self):
        """測試無 API Key 時返回 None"""
        from core import ai_client
        ai_client.reset_client()

        with patch.object(ai_client, 'settings') as mock_settings:
            mock_settings.OPENAI_API_KEY = ""
            mock_settings.OPENAI_BASE_URL = ""
            mock_settings.OPENAI_TIMEOUT = 30

            client = ai_client.get_openai_client()
            # 無 API Key 應返回 None
            assert client is None

    def test_reset_client(self):
        """測試重置客戶端"""
        from core import ai_client

        ai_client.reset_client()
        assert ai_client._initialized is False
        assert ai_client._openai_client is None

    def test_is_available_false(self):
        """測試服務不可用"""
        from core import ai_client
        ai_client.reset_client()

        with patch.object(ai_client, 'settings') as mock_settings:
            mock_settings.OPENAI_API_KEY = ""
            mock_settings.OPENAI_BASE_URL = ""
            mock_settings.OPENAI_TIMEOUT = 30

            assert ai_client.is_available() is False

    def test_get_openai_client_passes_base_url(self):
        """測試有設定 base_url 時會傳入 OpenAI client"""
        from core import ai_client
        ai_client.reset_client()

        fake_client = MagicMock()

        with patch.object(ai_client, 'settings') as mock_settings:
            mock_settings.OPENAI_API_KEY = "sk-test"
            mock_settings.OPENAI_BASE_URL = "https://sub2api.flowatelier.com/v1"
            mock_settings.OPENAI_TIMEOUT = 30

            with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
                client = ai_client.get_openai_client()

        assert client is fake_client
        mock_openai.assert_called_once_with(
            api_key="sk-test",
            base_url="https://sub2api.flowatelier.com/v1",
            timeout=30.0,
            max_retries=3,
        )

    def test_get_openai_client_normalizes_base_url_without_v1(self):
        """測試 base_url 可用裸網域設定,client factory 會補 /v1"""
        from core import ai_client
        ai_client.reset_client()

        fake_client = MagicMock()

        with patch.object(ai_client, 'settings') as mock_settings:
            mock_settings.OPENAI_API_KEY = "sk-test"
            mock_settings.OPENAI_BASE_URL = "https://sub2api.flowatelier.com"
            mock_settings.OPENAI_TIMEOUT = 30

            with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
                client = ai_client.get_openai_client()

        assert client is fake_client
        mock_openai.assert_called_once_with(
            api_key="sk-test",
            base_url="https://sub2api.flowatelier.com/v1",
            timeout=30.0,
            max_retries=3,
        )

    def test_get_openai_client_omits_base_url_when_unset(self):
        """測試未設定 base_url 時沿用 SDK 預設 OpenAI endpoint"""
        from core import ai_client
        ai_client.reset_client()

        fake_client = MagicMock()

        with patch.object(ai_client, 'settings') as mock_settings:
            mock_settings.OPENAI_API_KEY = "sk-test"
            mock_settings.OPENAI_BASE_URL = ""
            mock_settings.OPENAI_TIMEOUT = 30

            with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
                client = ai_client.get_openai_client()

        assert client is fake_client
        mock_openai.assert_called_once_with(
            api_key="sk-test",
            timeout=30.0,
            max_retries=3,
        )