# -*- coding: utf-8 -*- from pathlib import Path from backend import cli def test_live_runs_incremental_market_store_update_before_start(monkeypatch, tmp_path): project_root = tmp_path (project_root / ".env").write_text("FINNHUB_API_KEY=test\n", encoding="utf-8") calls = [] monkeypatch.setattr(cli, "get_project_root", lambda: project_root) monkeypatch.setattr(cli, "handle_history_cleanup", lambda config_name, auto_clean=False: None) monkeypatch.setattr(cli, "run_data_updater", lambda project_root: calls.append(("run_data_updater", project_root))) monkeypatch.setattr( cli, "auto_update_market_store", lambda config_name, end_date=None: calls.append(("auto_update_market_store", config_name, end_date)), ) monkeypatch.setattr( cli, "auto_enrich_market_store", lambda config_name, end_date=None, lookback_days=120, force=False: calls.append( ("auto_enrich_market_store", config_name, end_date, lookback_days, force) ), ) monkeypatch.setattr(cli.os, "chdir", lambda path: calls.append(("chdir", Path(path)))) def fake_run(cmd, check=True, **kwargs): calls.append(("subprocess.run", cmd, check)) return 0 monkeypatch.setattr(cli.subprocess, "run", fake_run) cli.live( config_name="smoke_fullstack", host="0.0.0.0", port=8765, trigger_time="now", poll_interval=10, clean=False, enable_memory=False, ) assert any(item[0] == "run_data_updater" for item in calls) assert any( item[0] == "auto_update_market_store" and item[1] == "smoke_fullstack" for item in calls ) assert any( item[0] == "auto_enrich_market_store" and item[1] == "smoke_fullstack" for item in calls ) run_call = next(item for item in calls if item[0] == "subprocess.run") assert run_call[1][:6] == [ cli.sys.executable, "-u", "-m", "backend.main", "--mode", "live", ] def test_backtest_runs_full_market_store_prepare_before_start(monkeypatch, tmp_path): project_root = tmp_path calls = [] monkeypatch.setattr(cli, "get_project_root", lambda: project_root) monkeypatch.setattr(cli, "handle_history_cleanup", lambda config_name, auto_clean=False: None) monkeypatch.setattr(cli, "run_data_updater", lambda project_root: calls.append(("run_data_updater", project_root))) monkeypatch.setattr( cli, "auto_prepare_backtest_market_store", lambda config_name, start_date, end_date: calls.append( ("auto_prepare_backtest_market_store", config_name, start_date, end_date) ), ) monkeypatch.setattr( cli, "auto_enrich_market_store", lambda config_name, end_date=None, lookback_days=120, force=False: calls.append( ("auto_enrich_market_store", config_name, end_date, lookback_days, force) ), ) monkeypatch.setattr(cli.os, "chdir", lambda path: calls.append(("chdir", Path(path)))) def fake_run(cmd, check=True, **kwargs): calls.append(("subprocess.run", cmd, check)) return 0 monkeypatch.setattr(cli.subprocess, "run", fake_run) cli.backtest( start="2026-03-01", end="2026-03-10", config_name="smoke_fullstack", host="0.0.0.0", port=8765, poll_interval=10, clean=False, enable_memory=False, ) assert any(item[0] == "run_data_updater" for item in calls) assert any( item[0] == "auto_prepare_backtest_market_store" and item[1:] == ("smoke_fullstack", "2026-03-01", "2026-03-10") for item in calls ) assert any( item[0] == "auto_enrich_market_store" and item[1] == "smoke_fullstack" and item[2] == "2026-03-10" for item in calls ) run_call = next(item for item in calls if item[0] == "subprocess.run") assert run_call[1][:6] == [ cli.sys.executable, "-u", "-m", "backend.main", "--mode", "backtest", ] def test_ingest_enrich_runs_batch_enrichment(monkeypatch): calls = [] monkeypatch.setattr(cli, "_resolve_symbols", lambda raw_tickers, config_name=None: ["AAPL", "MSFT"]) class DummyStore: pass monkeypatch.setattr(cli, "MarketStore", lambda: DummyStore()) monkeypatch.setattr( cli, "enrich_symbols", lambda store, symbols, start_date=None, end_date=None, limit=200, analysis_source="local", skip_existing=True: calls.append( ("enrich_symbols", symbols, start_date, end_date, limit, analysis_source, skip_existing) ) or [ { "symbol": symbol, "news_count": 3, "queued_count": 3, "analyzed": 3, "skipped_existing_count": 0, "deduped_count": 0, "llm_count": 0, "local_count": 3, } for symbol in symbols ], ) cli.ingest_enrich( tickers=None, start="2026-03-01", end="2026-03-10", limit=150, force=False, config_name="smoke_fullstack", ) assert calls == [ ("enrich_symbols", ["AAPL", "MSFT"], "2026-03-01", "2026-03-10", 150, "local", True) ] def test_ingest_report_reads_market_store_report(monkeypatch): calls = [] printed = [] monkeypatch.setattr(cli, "_resolve_symbols", lambda raw_tickers, config_name=None: ["AAPL"]) class DummyStore: def get_enrich_report(self, symbols=None, start_date=None, end_date=None): calls.append(("get_enrich_report", symbols, start_date, end_date)) return [ { "symbol": "AAPL", "raw_news_count": 10, "analyzed_news_count": 8, "coverage_pct": 80.0, "llm_count": 5, "local_count": 3, "latest_trade_date": "2026-03-16", "latest_analysis_at": "2026-03-16T09:00:00", } ] monkeypatch.setattr(cli, "MarketStore", lambda: DummyStore()) monkeypatch.setattr(cli, "get_explain_model_info", lambda: {"provider": "DASHSCOPE", "model_name": "qwen-max", "label": "DASHSCOPE:qwen-max"}) monkeypatch.setattr(cli, "llm_enrichment_enabled", lambda: True) monkeypatch.setattr(cli.console, "print", lambda value: printed.append(value)) cli.ingest_report( tickers=None, start="2026-03-01", end="2026-03-16", config_name="smoke_fullstack", only_problematic=False, ) assert calls == [ ("get_enrich_report", ["AAPL"], "2026-03-01", "2026-03-16") ] assert printed assert getattr(printed[0], "caption", "") == "Explain LLM: DASHSCOPE:qwen-max" def test_filter_problematic_report_rows_keeps_low_coverage_and_no_llm(): rows = [ { "symbol": "AAPL", "coverage_pct": 100.0, "llm_count": 2, }, { "symbol": "MSFT", "coverage_pct": 80.0, "llm_count": 1, }, { "symbol": "NVDA", "coverage_pct": 100.0, "llm_count": 0, }, ] filtered = cli._filter_problematic_report_rows(rows) assert [row["symbol"] for row in filtered] == ["MSFT", "NVDA"]