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
120 lines
4.7 KiB
Python
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."
|
|
)
|