Files
learningcircuit--local-deep…/tests/chat/test_chat_settings_integration.py
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

120 lines
4.7 KiB
Python

"""Integration tests for chat-mode settings extraction.
Replaces three earlier tests that only asserted on locally-constructed
dict literals (no production-code import) with checks that actually
exercise the chat route's settings helper and reproduce the snapshot
field-extraction the research pipeline performs.
These do NOT spin up a full DB — ``_load_settings`` is patched to
return a controlled snapshot and the extraction is asserted against
the same field names the production research path reads.
"""
from unittest.mock import MagicMock, patch
class TestLoadSettingsHelper:
"""Tests for the ``chat/routes.py::_load_settings`` helper."""
def test_load_settings_bypasses_cache(self):
"""``_load_settings`` must call ``get_all_settings(bypass_cache=True)``
so a UI setting change just before the chat send takes effect on
the very next research run (matches the behaviour of
``research_routes.start_research``)."""
from src.local_deep_research.chat import routes as chat_routes
with (
patch.object(chat_routes, "get_user_db_session") as mock_get_db,
patch.object(chat_routes, "SettingsManager") as mock_manager_cls,
):
mock_db = MagicMock()
mock_get_db.return_value.__enter__.return_value = mock_db
mock_manager = MagicMock()
mock_manager.get_all_settings.return_value = {
"llm.provider": {"value": "ollama"}
}
mock_manager_cls.return_value = mock_manager
snapshot = chat_routes._load_settings("alice")
mock_manager_cls.assert_called_once_with(db_session=mock_db)
mock_manager.get_all_settings.assert_called_once_with(bypass_cache=True)
assert snapshot == {"llm.provider": {"value": "ollama"}}
def test_load_settings_returns_independent_snapshot_per_call(self):
"""Each ``_load_settings`` call returns the dict from the
manager — independent calls don't share state by reference. This
backs the snapshot semantics relied on by the research pipeline,
where the snapshot is supposed to survive global setting changes
that happen during the research run."""
from src.local_deep_research.chat import routes as chat_routes
snapshots: list[dict] = [
{"llm.model": {"value": "first"}},
{"llm.model": {"value": "second"}},
]
results = []
def _make_manager(*args, **kwargs):
m = MagicMock()
m.get_all_settings.return_value = snapshots[len(results)]
return m
with (
patch.object(chat_routes, "get_user_db_session") as mock_get_db,
patch.object(
chat_routes,
"SettingsManager",
side_effect=_make_manager,
),
):
mock_get_db.return_value.__enter__.return_value = MagicMock()
results.append(chat_routes._load_settings("alice"))
results.append(chat_routes._load_settings("alice"))
# Two distinct dicts — modifying one doesn't bleed into the other.
results[0]["llm.model"]["value"] = "mutated"
assert results[1]["llm.model"]["value"] == "second"
class TestSettingsExtractionMatchesProduction:
"""The extraction pattern used by ``send_message`` to pull settings
out of the snapshot before invoking the research pipeline. If the
schema for one of these keys changes, this test fails before the
routes silently fall back to a default the user didn't ask for."""
EXTRACTION_KEYS = (
"llm.provider",
"llm.model",
"search.tool",
"search.iterations",
"search.questions_per_iteration",
"search.search_strategy",
)
def test_full_snapshot_round_trip(self):
"""Every key the chat route reads from the snapshot is present in
the default settings shipped with the project
(``defaults/default_settings.json`` loaded at import time by
the SettingsManager). If any key is renamed or removed without
updating the route, this fails."""
import json
from pathlib import Path
import local_deep_research
defaults_path = (
Path(local_deep_research.__file__).parent
/ "defaults"
/ "default_settings.json"
)
with defaults_path.open() as fh:
defaults = json.load(fh)
for key in self.EXTRACTION_KEYS:
assert key in defaults, (
f"chat route reads {key!r} from settings_snapshot, but it "
"is missing from default_settings.json — a rename will "
"silently fall back to None at runtime."
)