mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-16 09:26:07 +00:00
test: tighten phase 1 coverage contracts
This commit is contained in:
@@ -11,6 +11,8 @@ from unittest.mock import AsyncMock, MagicMock
|
||||
import pytest
|
||||
import openai # Import real openai package
|
||||
|
||||
from langbot.pkg.provider.modelmgr.errors import RequesterError
|
||||
|
||||
|
||||
class TestInvokeLLMErrorHandling:
|
||||
"""Tests for invoke_llm error handling branches."""
|
||||
@@ -66,7 +68,7 @@ class TestInvokeLLMErrorHandling:
|
||||
side_effect=asyncio.TimeoutError()
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_llm(
|
||||
query=None,
|
||||
model=mock_model,
|
||||
@@ -87,7 +89,7 @@ class TestInvokeLLMErrorHandling:
|
||||
side_effect=error
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_llm(
|
||||
query=None,
|
||||
model=mock_model,
|
||||
@@ -108,7 +110,7 @@ class TestInvokeLLMErrorHandling:
|
||||
side_effect=error
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_llm(
|
||||
query=None,
|
||||
model=mock_model,
|
||||
@@ -129,7 +131,7 @@ class TestInvokeLLMErrorHandling:
|
||||
side_effect=error
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_llm(
|
||||
query=None,
|
||||
model=mock_model,
|
||||
@@ -175,7 +177,7 @@ class TestInvokeEmbeddingErrorHandling:
|
||||
side_effect=asyncio.TimeoutError()
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_embedding(
|
||||
model=mock_embedding_model,
|
||||
input_text=['test'],
|
||||
@@ -195,7 +197,7 @@ class TestInvokeEmbeddingErrorHandling:
|
||||
side_effect=error
|
||||
)
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_embedding(
|
||||
model=mock_embedding_model,
|
||||
input_text=['test'],
|
||||
@@ -242,4 +244,4 @@ class TestDefaultConfig:
|
||||
})
|
||||
|
||||
assert req.requester_cfg['base_url'] == 'https://custom.com/v1'
|
||||
assert req.requester_cfg['timeout'] == 60
|
||||
assert req.requester_cfg['timeout'] == 60
|
||||
|
||||
@@ -141,25 +141,21 @@ class TestNormalizeModalities:
|
||||
requester = self._create_requester_with_mocks()
|
||||
|
||||
result = requester._normalize_modalities('text,image')
|
||||
assert 'text' in result
|
||||
assert 'image' in result
|
||||
assert result == ['text', 'image']
|
||||
|
||||
def test_normalize_list_modalities(self):
|
||||
"""Normalize list of modalities."""
|
||||
requester = self._create_requester_with_mocks()
|
||||
|
||||
result = requester._normalize_modalities(['text', 'image', 'audio'])
|
||||
assert 'text' in result
|
||||
assert 'image' in result
|
||||
assert 'audio' in result
|
||||
assert result == ['text', 'image', 'audio']
|
||||
|
||||
def test_normalize_dict_modalities(self):
|
||||
"""Normalize dict with nested modalities."""
|
||||
requester = self._create_requester_with_mocks()
|
||||
|
||||
result = requester._normalize_modalities({'input': ['text'], 'output': ['text', 'image']})
|
||||
assert 'text' in result
|
||||
assert 'image' in result
|
||||
assert result == ['text', 'image']
|
||||
|
||||
def test_normalize_none(self):
|
||||
"""Handle None input."""
|
||||
@@ -173,8 +169,7 @@ class TestNormalizeModalities:
|
||||
requester = self._create_requester_with_mocks()
|
||||
|
||||
result = requester._normalize_modalities('text->image')
|
||||
assert 'text' in result
|
||||
assert 'image' in result
|
||||
assert result == ['text', 'image']
|
||||
|
||||
|
||||
class TestParseRerankResponse:
|
||||
@@ -192,9 +187,10 @@ class TestParseRerankResponse:
|
||||
}
|
||||
|
||||
result = OpenAIChatCompletions._parse_rerank_response(data)
|
||||
assert len(result) == 2
|
||||
assert result[0]['index'] == 0
|
||||
assert result[0]['relevance_score'] == 0.95
|
||||
assert result == [
|
||||
{'index': 0, 'relevance_score': 0.95},
|
||||
{'index': 1, 'relevance_score': 0.80},
|
||||
]
|
||||
|
||||
def test_parse_voyage_format(self):
|
||||
"""Parse Voyage AI format."""
|
||||
@@ -208,8 +204,10 @@ class TestParseRerankResponse:
|
||||
}
|
||||
|
||||
result = OpenAIChatCompletions._parse_rerank_response(data)
|
||||
assert len(result) == 2
|
||||
assert result[0]['index'] == 0
|
||||
assert result == [
|
||||
{'index': 0, 'relevance_score': 0.90},
|
||||
{'index': 2, 'relevance_score': 0.75},
|
||||
]
|
||||
|
||||
def test_parse_dashscope_format(self):
|
||||
"""Parse DashScope format."""
|
||||
@@ -224,8 +222,7 @@ class TestParseRerankResponse:
|
||||
}
|
||||
|
||||
result = OpenAIChatCompletions._parse_rerank_response(data)
|
||||
assert len(result) == 1
|
||||
assert result[0]['index'] == 0
|
||||
assert result == [{'index': 0, 'relevance_score': 0.85}]
|
||||
|
||||
def test_parse_unknown_format(self):
|
||||
"""Handle unknown format returns empty list."""
|
||||
@@ -340,4 +337,4 @@ class TestExtractScanMetadata:
|
||||
|
||||
result = requester._extract_scan_metadata(item, 'gpt-4')
|
||||
|
||||
assert result['display_name'] is None
|
||||
assert result['display_name'] is None
|
||||
|
||||
@@ -9,6 +9,8 @@ import asyncio
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
import pytest
|
||||
|
||||
from langbot.pkg.provider.modelmgr.errors import RequesterError
|
||||
|
||||
|
||||
class TestOllamaRequesterConfig:
|
||||
"""Tests for default config."""
|
||||
@@ -228,7 +230,7 @@ class TestOllamaErrorHandling:
|
||||
"""TimeoutError is converted to RequesterError."""
|
||||
requester_with_mocked_client.client.chat = AsyncMock(side_effect=asyncio.TimeoutError())
|
||||
|
||||
with pytest.raises(Exception) as exc:
|
||||
with pytest.raises(RequesterError) as exc:
|
||||
await requester_with_mocked_client.invoke_llm(
|
||||
query=None,
|
||||
model=mock_model,
|
||||
@@ -259,4 +261,4 @@ class TestOllamaScanModels:
|
||||
"""REQUESTER_NAME constant exists."""
|
||||
from langbot.pkg.provider.modelmgr.requesters.ollamachat import REQUESTER_NAME
|
||||
|
||||
assert REQUESTER_NAME == 'ollama-chat'
|
||||
assert REQUESTER_NAME == 'ollama-chat'
|
||||
|
||||
@@ -13,7 +13,6 @@ from unittest.mock import Mock
|
||||
from importlib import import_module
|
||||
|
||||
import langbot_plugin.api.entities.builtin.provider.session as provider_session
|
||||
import langbot_plugin.api.entities.builtin.provider.message as provider_message
|
||||
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user