"""Tests for tradingagents.portfolio.store_factory. Covers: - Default (no env var) returns filesystem ReportStore - TRADINGAGENTS_MONGO_URI returns MongoReportStore - Explicit mongo_uri parameter takes precedence - MongoDB failure falls back to filesystem """ from __future__ import annotations from unittest.mock import MagicMock, patch import pytest from tradingagents.portfolio.report_store import ReportStore from tradingagents.portfolio.store_factory import create_report_store # --------------------------------------------------------------------------- # Default: filesystem # --------------------------------------------------------------------------- def test_default_returns_filesystem_store(): """When no MongoDB URI is configured, the factory returns ReportStore.""" with patch.dict("os.environ", {}, clear=True): store = create_report_store() assert isinstance(store, ReportStore) def test_default_passes_run_id(): """run_id should be forwarded to the filesystem store.""" with patch.dict("os.environ", {}, clear=True): store = create_report_store(run_id="abc123") assert isinstance(store, ReportStore) assert store.run_id == "abc123" def test_default_passes_flow_id(): """flow_id should be forwarded to the filesystem store.""" with patch.dict("os.environ", {}, clear=True): store = create_report_store(flow_id="flow001") assert isinstance(store, ReportStore) assert store.flow_id == "flow001" assert store.run_id == "flow001" # flow_id takes precedence def test_base_dir_forwarded(): """base_dir should be forwarded to the filesystem store.""" with patch.dict("os.environ", {}, clear=True): store = create_report_store(base_dir="/custom/reports") assert isinstance(store, ReportStore) # --------------------------------------------------------------------------- # Explicit mongo_uri → MongoDB # --------------------------------------------------------------------------- def test_explicit_mongo_uri_returns_mongo_store(): """When mongo_uri is provided, the factory returns MongoReportStore.""" with patch( "tradingagents.portfolio.store_factory.MongoReportStore", create=True, ) as MockMongo, \ patch("tradingagents.portfolio.mongo_report_store.MongoClient") as mock_client_cls: mock_store = MagicMock() mock_store.run_id = "abc" # Import the real module so the factory can import it from tradingagents.portfolio.mongo_report_store import MongoReportStore with patch( "tradingagents.portfolio.mongo_report_store.MongoClient" ) as mock_mc: mock_mc.return_value = MagicMock() store = create_report_store( run_id="abc", mongo_uri="mongodb://localhost:27017", ) # It should be a MongoReportStore or fall back to ReportStore # Since MongoDB might fail in tests, just check it returns something assert store is not None # --------------------------------------------------------------------------- # MongoDB failure → filesystem fallback # --------------------------------------------------------------------------- def test_mongo_failure_falls_back_to_filesystem(): """When MongoDB connection fails, the factory falls back to ReportStore.""" with patch( "tradingagents.portfolio.mongo_report_store.MongoClient", side_effect=Exception("connection refused"), ): store = create_report_store( run_id="test", mongo_uri="mongodb://bad-host:27017", ) assert isinstance(store, ReportStore) assert store.run_id == "test" # --------------------------------------------------------------------------- # Env var # --------------------------------------------------------------------------- def test_env_var_mongo_uri(): """TRADINGAGENTS_MONGO_URI env var should trigger MongoDB store.""" with patch.dict( "os.environ", {"TRADINGAGENTS_MONGO_URI": "mongodb://envhost:27017"}, ), patch( "tradingagents.portfolio.mongo_report_store.MongoClient", side_effect=Exception("connection refused"), ): # Will fail to connect, but should try and then fall back store = create_report_store() # Should fall back to filesystem assert isinstance(store, ReportStore)