File size: 3,509 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
"""
Unit tests for Gemini 3.1 model support.

Required test categories coverage note:
- Happy path: Covered via Gemini 3.1 Pro normalization + capability matching.
- Null/undefined/empty: Covered in tests/test_smart_rotation_fix.py; omitted here to avoid duplicate coverage.
- Boundary values: N/A (string normalization does not have numeric boundaries).
- Invalid type/malformed: N/A (function expects str; invalid types not used in production paths).
- Error conditions: N/A (pure functions without error branches).
- Concurrency/timing: N/A (no async/concurrency logic).
- Performance: N/A (simple string operations).
- Security-focused: N/A (no auth/permission logic).
"""

import pytest

from api_utils.routers.model_capabilities import _get_model_capabilities
from browser_utils.auth_rotation import _normalize_model_id


class TestNormalizeModelIdGemini31:
    """Tests for _normalize_model_id covering Gemini 3.1 variants."""

    @pytest.mark.parametrize(
        "input_id,expected",
        [
            ("gemini-3.1-pro", "gemini-3.1-pro"),
            ("gemini-3-1-pro", "gemini-3.1-pro"),
            ("gemini-3.1-pro-preview", "gemini-3.1-pro"),
        ],
        ids=[
            "pro-dot",
            "pro-hyphen",
            "pro-preview",
        ],
    )
    def test_normalize_gemini31_variants(self, input_id, expected):
        """Happy path: Normalize supported Gemini 3.1 inputs."""
        # Arrange
        model_id = input_id

        # Act
        result = _normalize_model_id(model_id)

        # Assert
        assert result == expected

    @pytest.mark.parametrize(
        "input_id,expected",
        [
            ("gemini3.1pro", "gemini3-1pro"),
        ],
        ids=["no-separators-pro"],
    )
    def test_normalize_gemini31_edge_formats(self, input_id, expected):
        """Edge cases: Inputs without separators are normalized by dot replacement."""
        # Arrange
        model_id = input_id

        # Act
        result = _normalize_model_id(model_id)

        # Assert
        assert result == expected

    @pytest.mark.parametrize(
        "input_id,expected",
        [
            ("gemini-1.5-pro", "gemini-1.5-pro"),
            ("gemini-2.5-pro", "gemini-2.5-pro"),
            ("gemini-3-pro-preview", "gemini-3-pro-preview"),
        ],
        ids=["gemini-1-5-pro", "gemini-2-5-pro", "gemini-3-pro-preview"],
    )
    def test_normalize_existing_models_still_supported(self, input_id, expected):
        """Regression: Existing model normalizations still map correctly."""
        # Arrange
        model_id = input_id

        # Act
        result = _normalize_model_id(model_id)

        # Assert
        assert result == expected


class TestModelCapabilitiesGemini31:
    """Tests for _get_model_capabilities for Gemini 3.1 models."""

    @pytest.mark.parametrize(
        "model_id",
        [
            "gemini-3.1-pro",
            "gemini-3.1-pro-preview",
            "gemini3.1pro-exp",
        ],
        ids=["pro", "pro-preview", "pro-compact"],
    )
    def test_gemini31_pro_capabilities(self, model_id):
        """Happy path: Gemini 3.1 Pro maps to gemini3Pro category."""
        # Arrange
        expected_levels = ["low", "high"]

        # Act
        result = _get_model_capabilities(model_id)

        # Assert
        assert result["thinkingType"] == "level"
        assert result["levels"] == expected_levels
        assert result["defaultLevel"] == "high"
        assert result["supportsGoogleSearch"] is True