1010from quantclass_sync_internal .models import CommandContext , EmptyDownloadLinkError , FatalRequestError , ProductPlan , ProductSyncError , RunReport , SyncStats
1111from quantclass_sync_internal .orchestrator import _execute_plans , _resolve_requested_dates_for_plan
1212from quantclass_sync_internal .reporting import _new_report
13- from quantclass_sync_internal .status_store import connect_status_db
13+ from quantclass_sync_internal .status_store import _SOURCE_API_CHECK , connect_status_db
1414
1515
1616class UpdateCatchUpTests (unittest .TestCase ):
@@ -705,21 +705,31 @@ class TestPrefetchApiDates(unittest.TestCase):
705705 def setUp (self ):
706706 self ._tmpdir = tempfile .TemporaryDirectory ()
707707 self .root = Path (self ._tmpdir .name )
708+ # log_dir 路径与 report_dir_path(data_root) 保持一致:data_root/.quantclass_sync/log
708709 self .log_dir = self .root / ".quantclass_sync" / "log"
709710 self .log_dir .mkdir (parents = True )
710711
711712 def tearDown (self ):
712713 self ._tmpdir .cleanup ()
713714
715+ def _ctx (self ) -> CommandContext :
716+ """构造测试用 CommandContext,api_base 设为 http://fake。"""
717+ return CommandContext (
718+ run_id = "test" ,
719+ data_root = self .root ,
720+ dry_run = False ,
721+ stop_on_error = False ,
722+ api_base = "http://fake" ,
723+ )
724+
714725 @patch ("quantclass_sync_internal.orchestrator.get_latest_time" )
715726 def test_fetches_uncached_products (self , mock_get ):
716727 """无缓存时并发调用 get_latest_time。"""
717728 mock_get .return_value = "2026-03-18"
718729 from quantclass_sync_internal .orchestrator import _prefetch_api_dates
719730 cache = _prefetch_api_dates (
720731 products = ["prod-a" , "prod-b" ],
721- api_base = "http://fake" , hid = "hid" , headers = {},
722- log_dir = self .log_dir ,
732+ command_ctx = self ._ctx (), hid = "hid" , headers = {},
723733 )
724734 self .assertEqual (mock_get .call_count , 2 )
725735 self .assertIn ("prod-a" , cache )
@@ -734,8 +744,7 @@ def test_skips_fresh_cache(self, mock_get):
734744 update_api_latest_dates (self .log_dir , {"prod-a" : "2026-03-18" })
735745 cache = _prefetch_api_dates (
736746 products = ["prod-a" ],
737- api_base = "http://fake" , hid = "hid" , headers = {},
738- log_dir = self .log_dir ,
747+ command_ctx = self ._ctx (), hid = "hid" , headers = {},
739748 )
740749 mock_get .assert_not_called ()
741750 self .assertIn ("prod-a" , cache )
@@ -749,8 +758,7 @@ def test_partial_cache_only_fetches_missing(self, mock_get):
749758 update_api_latest_dates (self .log_dir , {"prod-a" : "2026-03-18" })
750759 cache = _prefetch_api_dates (
751760 products = ["prod-a" , "prod-b" ],
752- api_base = "http://fake" , hid = "hid" , headers = {},
753- log_dir = self .log_dir ,
761+ command_ctx = self ._ctx (), hid = "hid" , headers = {},
754762 )
755763 # 只查了 prod-b
756764 self .assertEqual (mock_get .call_count , 1 )
@@ -763,8 +771,7 @@ def test_failure_returns_partial_cache(self, mock_get):
763771 from quantclass_sync_internal .orchestrator import _prefetch_api_dates
764772 cache = _prefetch_api_dates (
765773 products = ["prod-a" ],
766- api_base = "http://fake" , hid = "hid" , headers = {},
767- log_dir = self .log_dir ,
774+ command_ctx = self ._ctx (), hid = "hid" , headers = {},
768775 )
769776 # 失败但不抛异常,返回空缓存
770777 self .assertEqual (cache , {})
@@ -783,14 +790,13 @@ def test_expired_cache_refetches(self, mock_get):
783790 "prod-a" : {
784791 "date_time" : "2026-03-17" ,
785792 "checked_at" : expired_time .strftime ("%Y-%m-%dT%H:%M:%S" ),
786- "source" : "api_check" ,
793+ "source" : _SOURCE_API_CHECK ,
787794 }
788795 }))
789796 mock_get .return_value = "2026-03-18"
790797 cache = _prefetch_api_dates (
791798 products = ["prod-a" ],
792- api_base = "http://fake" , hid = "hid" , headers = {},
793- log_dir = self .log_dir ,
799+ command_ctx = self ._ctx (), hid = "hid" , headers = {},
794800 )
795801 mock_get .assert_called_once () # 过期缓存触发重查
796802 self .assertEqual (cache ["prod-a" ][0 ], "2026-03-18" ) # 返回新日期
0 commit comments