@@ -126,6 +126,12 @@ def _write_report(self, filename: str, products: list):
126126 json .dumps (existing , ensure_ascii = False ), encoding = "utf-8"
127127 )
128128
129+ def _write_product_last_status (self , payload : dict ) -> None :
130+ """直接写入 product_last_status.json,用于覆盖 source/checked_at 等字段。"""
131+ (self .log_dir / "product_last_status.json" ).write_text (
132+ json .dumps (payload , ensure_ascii = False ), encoding = "utf-8"
133+ )
134+
129135 def test_basic_overview (self ):
130136 """有 timestamp + 有报告的基本场景。"""
131137 self ._write_timestamp ("stock-trading-data" , "2026-03-13" )
@@ -313,6 +319,63 @@ def test_overview_api_latest_dates_equal_local(self):
313319 self .assertEqual (overview [0 ]["days_behind" ], 0 )
314320 self .assertEqual (overview [0 ]["status_color" ], "green" )
315321
322+ def test_overview_sync_source_date_is_not_used_as_api_cache (self ):
323+ """sync 写入的 date_time 不能当作 API 缓存日期使用。"""
324+ self ._write_timestamp ("coin-cap" , "2026-03-10" )
325+ self ._write_product_last_status ({
326+ "coin-cap" : {
327+ "status" : "skipped" ,
328+ "reason_code" : "no_valid_output" ,
329+ "error" : "同步未产生可用输出,已跳过状态推进。" ,
330+ "date_time" : "2026-03-11" ,
331+ "checked_at" : "2026-03-13T09:00:00" ,
332+ "source" : "sync" ,
333+ }
334+ })
335+
336+ import unittest .mock
337+ with unittest .mock .patch (
338+ "quantclass_sync_internal.data_query.report_dir_path" ,
339+ return_value = self .log_dir ,
340+ ):
341+ overview = get_products_overview (
342+ self .data_root ,
343+ ["coin-cap" ],
344+ today = date (2026 , 3 , 13 ),
345+ )
346+
347+ self .assertEqual (overview [0 ]["days_behind" ], 3 )
348+ self .assertEqual (overview [0 ]["status_color" ], "yellow" )
349+
350+ def test_overview_same_api_date_after_no_valid_output_is_not_pending (self ):
351+ """同一 API 日期已确认 no_valid_output 时,不再标记为待更新。"""
352+ self ._write_timestamp ("coin-cap" , "2026-03-10" )
353+ self ._write_product_last_status ({
354+ "coin-cap" : {
355+ "status" : "skipped" ,
356+ "reason_code" : "no_valid_output" ,
357+ "error" : "同步未产生可用输出,已跳过状态推进。" ,
358+ "date_time" : "2026-03-11" ,
359+ "checked_at" : "2026-03-13T09:00:00" ,
360+ "source" : "sync" ,
361+ }
362+ })
363+
364+ import unittest .mock
365+ with unittest .mock .patch (
366+ "quantclass_sync_internal.data_query.report_dir_path" ,
367+ return_value = self .log_dir ,
368+ ):
369+ overview = get_products_overview (
370+ self .data_root ,
371+ ["coin-cap" ],
372+ today = date (2026 , 3 , 13 ),
373+ api_latest_dates = {"coin-cap" : "2026-03-11" },
374+ )
375+
376+ self .assertEqual (overview [0 ]["days_behind" ], 0 )
377+ self .assertEqual (overview [0 ]["status_color" ], "green" )
378+
316379 def test_overview_api_latest_dates_earlier_than_local (self ):
317380 """API 日期早于本地日期时 behind=0(max(0, diff) 截断)。"""
318381 self ._write_timestamp ("stock-trading-data" , "2026-03-14" )
0 commit comments