File size: 6,810 Bytes
a5784e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""
Tests for api_utils/routers/model_capabilities.py

Tests for model capability determination and API endpoints.
"""

import pytest
from fastapi.testclient import TestClient

from api_utils.routers.model_capabilities import (
    _get_model_capabilities,
    router,
)

# ==================== _get_model_capabilities TESTS ====================


class TestGetModelCapabilities:
    """Tests for _get_model_capabilities helper function."""

    def test_gemini3_flash(self):
        """Test Gemini 3 Flash model capabilities."""
        result = _get_model_capabilities("gemini-3-flash")
        assert result["thinkingType"] == "level"
        assert result["levels"] == ["minimal", "low", "medium", "high"]
        assert result["defaultLevel"] == "high"
        assert result["supportsGoogleSearch"] is True

    def test_gemini3_flash_variant(self):
        """Test Gemini 3 Flash variant (gemini3flash)."""
        result = _get_model_capabilities("gemini3flash-exp")
        assert result["thinkingType"] == "level"
        assert "minimal" in result["levels"]

    def test_gemini3_pro(self):
        """Test Gemini 3 Pro model capabilities."""
        result = _get_model_capabilities("gemini-3-pro")
        assert result["thinkingType"] == "level"
        assert result["levels"] == ["low", "high"]
        assert result["defaultLevel"] == "high"
        assert result["supportsGoogleSearch"] is True

    def test_gemini3_pro_variant(self):
        """Test Gemini 3 Pro variant (gemini3pro)."""
        result = _get_model_capabilities("gemini3pro-latest")
        assert result["thinkingType"] == "level"
        assert result["levels"] == ["low", "high"]

    def test_gemini25_pro(self):
        """Test Gemini 2.5 Pro model capabilities."""
        result = _get_model_capabilities("gemini-2.5-pro-preview")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is True
        assert result["budgetRange"] == [1024, 32768]
        assert result["defaultBudget"] == 32768
        assert result["supportsGoogleSearch"] is True

    def test_gemini25_pro_variant(self):
        """Test Gemini 2.5 Pro variant (gemini-2.5pro)."""
        result = _get_model_capabilities("gemini-2.5pro-exp")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is True

    def test_gemini25_flash(self):
        """Test Gemini 2.5 Flash model capabilities."""
        result = _get_model_capabilities("gemini-2.5-flash-preview")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is False
        assert result["budgetRange"] == [512, 24576]
        assert result["defaultBudget"] == 24576
        assert result["supportsGoogleSearch"] is True

    def test_gemini25_flash_variant(self):
        """Test Gemini 2.5 Flash variant (gemini-2.5flash)."""
        result = _get_model_capabilities("gemini-2.5flash-exp")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is False

    def test_gemini_flash_latest(self):
        """Test gemini-flash-latest maps to 2.5 Flash."""
        result = _get_model_capabilities("gemini-flash-latest")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is False

    def test_gemini_flash_lite_latest(self):
        """Test gemini-flash-lite-latest maps to 2.5 Flash."""
        result = _get_model_capabilities("gemini-flash-lite-latest")
        assert result["thinkingType"] == "budget"
        assert result["alwaysOn"] is False

    def test_gemini20(self):
        """Test Gemini 2.0 model capabilities (no thinking)."""
        result = _get_model_capabilities("gemini-2.0-flash-exp")
        assert result["thinkingType"] == "none"
        assert result["supportsGoogleSearch"] is False

    def test_gemini20_variant(self):
        """Test Gemini 2.0 variant (gemini2.0)."""
        result = _get_model_capabilities("gemini2.0-flash")
        assert result["thinkingType"] == "none"
        assert result["supportsGoogleSearch"] is False

    def test_gemini_robotics(self):
        """Test Gemini robotics model (special case - has Google Search)."""
        result = _get_model_capabilities("gemini-robotics-er-1.5-preview")
        assert result["thinkingType"] == "none"
        assert result["supportsGoogleSearch"] is True

    def test_other_model(self):
        """Test unknown/other model falls back to defaults."""
        result = _get_model_capabilities("some-other-model")
        assert result["thinkingType"] == "none"
        assert result["supportsGoogleSearch"] is True

    def test_case_insensitive(self):
        """Test model matching is case insensitive."""
        result = _get_model_capabilities("GEMINI-3-FLASH")
        assert result["thinkingType"] == "level"


# ==================== API Endpoint TESTS ====================


@pytest.fixture
def client():
    """Create test client for the router."""
    from fastapi import FastAPI

    app = FastAPI()
    app.include_router(router)
    return TestClient(app)


class TestModelCapabilitiesEndpoints:
    """Tests for model capabilities API endpoints."""

    @pytest.mark.asyncio
    async def test_get_model_capabilities_endpoint(self, client):
        """Test GET /api/model-capabilities returns full structure."""
        response = client.get("/api/model-capabilities")
        assert response.status_code == 200

        data = response.json()
        assert "categories" in data
        assert "matchers" in data

        # Verify categories
        categories = data["categories"]
        assert "gemini3Flash" in categories
        assert "gemini3Pro" in categories
        assert "gemini25Pro" in categories
        assert "gemini25Flash" in categories
        assert "gemini2" in categories
        assert "other" in categories

        # Verify matchers
        matchers = data["matchers"]
        assert len(matchers) >= 5
        assert all("pattern" in m and "category" in m for m in matchers)

    @pytest.mark.asyncio
    async def test_get_single_model_capabilities_endpoint(self, client):
        """Test GET /api/model-capabilities/{model_id} returns model capabilities."""
        response = client.get("/api/model-capabilities/gemini-3-flash")
        assert response.status_code == 200

        data = response.json()
        assert data["thinkingType"] == "level"
        assert "levels" in data

    @pytest.mark.asyncio
    async def test_get_single_model_unknown(self, client):
        """Test GET /api/model-capabilities/{model_id} for unknown model."""
        response = client.get("/api/model-capabilities/unknown-model")
        assert response.status_code == 200

        data = response.json()
        assert data["thinkingType"] == "none"
        assert data["supportsGoogleSearch"] is True