Files
odysseus/tests/test_model_defaults.py
T
Jakub Grula 060dbf0681 feat: Allow admins to choose if they want to share defaults (#4752)
* First bare fix

* Adding the option toggle

* toggle function fix

* Final fix, added missing /auth/

* Extended toggle text & added tests

* Comments change

* Description toggle change

* br tag fix

* description change based on suggestion
2026-06-23 23:06:45 +02:00

173 lines
6.1 KiB
Python

"""Tests for share_defaults_with_users setting"""
import pytest
from types import SimpleNamespace
from unittest.mock import MagicMock
from tests.helpers.import_state import preserve_import_state
from tests.helpers.db_stubs import make_core_db_stub
with preserve_import_state("core.database", "src.database", "routes.model_routes", "routes.prefs_routes"):
import routes.model_routes as model_routes
import routes.prefs_routes as prefs_routes
import src.auth_helpers as auth_helpers
### Helper Classes
class _FakeEndpoint:
"""Minimal fake endpoint for testing"""
def __init__(self, id, base_url, is_enabled=True, owner=None):
self.id = id
self.base_url = base_url
self.is_enabled = is_enabled
self.owner = owner
self.cached_models = None
self.hidden_models = None
self.pinned_models = None
class _FakeQuery:
"""Fake query object for testing"""
def __init__(self, endpoints, user=None, include_shared=True):
self._endpoints = endpoints
self._user = user
self._include_shared = include_shared
def filter(self, *conditions):
for cond in conditions:
cond_str = str(cond)
print(f"Filter condition: {cond_str}")
if 'owner' in cond_str and 'IS NULL' not in cond_str:
self._include_shared = False
return self
def first(self):
"""Return first endpoint respecting owner filter"""
if not self._endpoints:
return None
if self._user:
for ep in self._endpoints:
ep_owner = getattr(ep, 'owner', None)
if ep_owner == self._user:
return ep
if self._include_shared and ep_owner is None:
return ep
return None
return self._endpoints[0]
def _make_db_session(endpoints, user=None):
"""Create a fake DB session that returns our fake query"""
fake_session = MagicMock()
fake_query = _FakeQuery(endpoints, user)
fake_session.query.return_value = fake_query
return fake_session
def _get_default_chat_route(router):
"""Extract the /api/default-chat GET route from the router"""
for route in router.routes:
if getattr(route, "path", "") == "/api/default-chat" and "GET" in getattr(route, "methods", set()):
return route.endpoint
raise AssertionError("GET /api/default-chat route not found")
def _make_request(user=None, auth_manager=None):
"""Create a fake request for testing"""
return SimpleNamespace(
state=SimpleNamespace(current_user=user),
app=SimpleNamespace(state=SimpleNamespace(auth_manager=auth_manager)),
client=SimpleNamespace(host="127.0.0.1"),
)
### Shared test logic
def _run_get_default_chat_test(monkeypatch, share_defaults_enabled, second_endpoint_only=False):
"""Helper function that runs get_default_chat with the given share_defaults_with_users setting."""
global_settings = {
"default_endpoint_id": "global-ep-123",
"default_model": "qwen-3.6",
"default_model_fallbacks": [
{"endpoint_id": "fallback-ep", "model": "fallback-model"}
],
"share_defaults_with_users": share_defaults_enabled
}
monkeypatch.setattr(model_routes, "_load_settings", lambda: global_settings)
monkeypatch.setattr(prefs_routes, "_load_for_user", lambda user: {})
fake_auth_manager = MagicMock()
fake_auth_manager.is_admin = lambda user: False
endpoints = [
_FakeEndpoint(
id="global-ep-123",
base_url="http://global-endpoint:8000/v1",
is_enabled=True
),
_FakeEndpoint(
id="fallback-ep",
base_url="http://fallback-endpoint:8000/v1",
is_enabled=True
)
]
# When testing fallback scenario, removes the primary endpoint
if second_endpoint_only:
endpoints = [endpoints[1]]
fake_db = _make_db_session(endpoints, user="regular_user")
monkeypatch.setattr(model_routes, "SessionLocal", lambda: fake_db)
monkeypatch.setattr(model_routes, "_normalize_base", lambda url: url)
monkeypatch.setattr(model_routes, "build_chat_url", lambda base: f"{base}/chat")
router = model_routes.setup_model_routes(model_discovery=None)
get_default_chat = _get_default_chat_route(router)
fake_request = _make_request(user="regular_user", auth_manager=fake_auth_manager)
result = get_default_chat(fake_request)
return result
### Test Functions
def test_get_default_chat_user_no_prefs_share_disabled_resolves_nothing(monkeypatch):
"""
Non-admin user without personal preferences should resolve to empty
ep_id, model, and fallbacks when share_defaults_with_users is disabled.
"""
test_data = _run_get_default_chat_test(monkeypatch, share_defaults_enabled=False)
assert test_data["endpoint_id"] == "", "Should get empty endpoint_id"
assert test_data["model"] == "", "Should get empty model"
def test_get_default_chat_user_no_prefs_share_enabled_resolves_global_defaults_fallbacks(monkeypatch):
"""
Non-admin user without personal preferences should resolve to global
defaults for ep_id, model, and fallbacks when share_defaults_with_users is enabled.
"""
test_data = _run_get_default_chat_test(monkeypatch, share_defaults_enabled=True)
assert test_data["model"] == "qwen-3.6", \
"model should be resolved from global default_model"
assert test_data["endpoint_id"] == "global-ep-123", \
"Should get global endpoint_id"
def test_get_default_chat_user_no_prefs_share_enabled_resolves_global_defaults(monkeypatch):
"""
Non-admin user without personal preferences should resolve to global
defaults for ep_id, model, and fallbacks when share_defaults_with_users is enabled.
"""
test_data = _run_get_default_chat_test(monkeypatch, share_defaults_enabled=True, second_endpoint_only=True)
assert test_data["model"] == "qwen-3.6", \
"model should be resolved from global default_model"
assert test_data["endpoint_id"] == "fallback-ep", \
"Should get global endpoint_id"