Skip to content

Commit c74384d

Browse files
Add unit tests to improve coverage for new features
- Add tests for CloudflareKVStorage with mocked httpx - Add async tests for LocalFileStorage and TelemetryCollector - Add tests for TelemetryCollector.create_event class method - Add tests for error handling in storage backends - Add unit tests for OpenRouter LLM with user_id parameter - Add tests for TelemetryConfig and mark_first_run error handling
1 parent c9c3adb commit c74384d

File tree

3 files changed

+427
-1
lines changed

3 files changed

+427
-1
lines changed

tests/test_cli_config.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,3 +337,43 @@ def test_mark_first_run_complete_idempotent(self, temp_config_dir):
337337

338338
# Should not be first run
339339
assert is_first_run() is False
340+
341+
def test_mark_first_run_complete_handles_write_error(self, temp_config_dir):
342+
"""Test that mark_first_run_complete handles OSError gracefully."""
343+
from unittest.mock import patch
344+
345+
# Mock Path.touch to raise OSError
346+
with patch("src.cli.config.FIRST_RUN_FILE") as mock_file:
347+
mock_file.touch.side_effect = OSError("Permission denied")
348+
349+
# Should not raise, just silently fail
350+
mark_first_run_complete()
351+
352+
353+
class TestTelemetryConfig:
354+
"""Tests for telemetry configuration."""
355+
356+
def test_default_telemetry_config(self):
357+
"""Test default telemetry configuration."""
358+
from src.cli.config import TelemetryConfig
359+
360+
config = TelemetryConfig()
361+
362+
assert config.enabled is True
363+
assert "openai/gpt-oss-120b" in config.model_blacklist
364+
365+
def test_telemetry_config_disabled(self):
366+
"""Test telemetry can be disabled."""
367+
from src.cli.config import TelemetryConfig
368+
369+
config = TelemetryConfig(enabled=False)
370+
371+
assert config.enabled is False
372+
373+
def test_telemetry_config_custom_blacklist(self):
374+
"""Test telemetry with custom model blacklist."""
375+
from src.cli.config import TelemetryConfig
376+
377+
config = TelemetryConfig(model_blacklist=["custom/model"])
378+
379+
assert config.model_blacklist == ["custom/model"]

tests/test_openrouter_llm.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
"""Unit tests for OpenRouter LLM utility."""
2+
3+
4+
class TestCreateOpenRouterLLM:
5+
"""Tests for create_openrouter_llm function."""
6+
7+
def test_creates_llm_with_default_params(self):
8+
"""Test creating LLM with default parameters."""
9+
from src.utils.openrouter_llm import create_openrouter_llm
10+
11+
llm = create_openrouter_llm(api_key="test-key")
12+
13+
assert llm is not None
14+
assert llm.model_name == "openai/gpt-oss-120b"
15+
assert llm.temperature == 0.1
16+
17+
def test_creates_llm_with_custom_model(self):
18+
"""Test creating LLM with custom model."""
19+
from src.utils.openrouter_llm import create_openrouter_llm
20+
21+
llm = create_openrouter_llm(model="anthropic/claude-3-haiku", api_key="test-key")
22+
23+
assert llm.model_name == "anthropic/claude-3-haiku"
24+
25+
def test_creates_llm_with_provider(self):
26+
"""Test creating LLM with provider preference."""
27+
from src.utils.openrouter_llm import create_openrouter_llm
28+
29+
llm = create_openrouter_llm(
30+
api_key="test-key",
31+
provider="Cerebras",
32+
)
33+
34+
assert llm is not None
35+
# Provider is passed in extra_body
36+
assert llm.extra_body is not None
37+
assert llm.extra_body.get("provider") == {"only": ["Cerebras"]}
38+
39+
def test_creates_llm_with_user_id(self):
40+
"""Test creating LLM with user_id for cache optimization."""
41+
from src.utils.openrouter_llm import create_openrouter_llm
42+
43+
llm = create_openrouter_llm(
44+
api_key="test-key",
45+
user_id="test-user-123",
46+
)
47+
48+
assert llm is not None
49+
# User ID is passed in extra_body for sticky cache routing
50+
assert llm.extra_body is not None
51+
assert llm.extra_body.get("user") == "test-user-123"
52+
53+
def test_creates_llm_with_provider_and_user_id(self):
54+
"""Test creating LLM with both provider and user_id."""
55+
from src.utils.openrouter_llm import create_openrouter_llm
56+
57+
llm = create_openrouter_llm(
58+
api_key="test-key",
59+
provider="Cerebras",
60+
user_id="test-user-456",
61+
)
62+
63+
assert llm is not None
64+
assert llm.extra_body is not None
65+
assert llm.extra_body.get("provider") == {"only": ["Cerebras"]}
66+
assert llm.extra_body.get("user") == "test-user-456"
67+
68+
def test_creates_llm_without_extra_body(self):
69+
"""Test creating LLM without provider or user_id."""
70+
from src.utils.openrouter_llm import create_openrouter_llm
71+
72+
llm = create_openrouter_llm(api_key="test-key")
73+
74+
# extra_body should be None when no provider or user_id
75+
assert llm.extra_body is None
76+
77+
def test_creates_llm_with_max_tokens(self):
78+
"""Test creating LLM with max_tokens."""
79+
from src.utils.openrouter_llm import create_openrouter_llm
80+
81+
llm = create_openrouter_llm(
82+
api_key="test-key",
83+
max_tokens=1000,
84+
)
85+
86+
assert llm.max_tokens == 1000
87+
88+
89+
class TestGetModelName:
90+
"""Tests for get_model_name function."""
91+
92+
def test_get_known_model_alias(self):
93+
"""Test getting model name for known alias."""
94+
from src.utils.openrouter_llm import get_model_name
95+
96+
result = get_model_name("gpt-oss-120b")
97+
98+
assert result == "openai/gpt-oss-120b"
99+
100+
def test_get_unknown_model_returns_input(self):
101+
"""Test getting model name for unknown alias returns input."""
102+
from src.utils.openrouter_llm import get_model_name
103+
104+
result = get_model_name("some-unknown-model")
105+
106+
assert result == "some-unknown-model"

0 commit comments

Comments
 (0)