"""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"