@@ -275,6 +275,34 @@ async def test_export_attachments_exports_existing_and_skips_missing(
275275 assert "files/attachments/att_ok.txt" in namelist
276276 assert "files/attachments/att_missing.txt" not in namelist
277277
278+ @pytest .mark .asyncio
279+ async def test_export_attachments_skips_empty_attachment_id (
280+ self , mock_main_db , tmp_path
281+ ):
282+ """测试附件导出:attachment_id 为空时跳过,避免覆盖冲突。"""
283+ exporter = AstrBotExporter (main_db = mock_main_db , kb_manager = None )
284+
285+ file_a = tmp_path / "a.txt"
286+ file_b = tmp_path / "b.txt"
287+ file_a .write_text ("a" , encoding = "utf-8" )
288+ file_b .write_text ("b" , encoding = "utf-8" )
289+ zip_path = tmp_path / "attachments_empty_id.zip"
290+
291+ attachments = [
292+ {"attachment_id" : "" , "path" : str (file_a )},
293+ {"path" : str (file_b )},
294+ {"attachment_id" : "att_ok" , "path" : str (file_a )},
295+ ]
296+
297+ with zipfile .ZipFile (zip_path , "w" , zipfile .ZIP_DEFLATED ) as zf :
298+ await exporter ._export_attachments (zf , attachments )
299+
300+ with zipfile .ZipFile (zip_path , "r" ) as zf :
301+ namelist = zf .namelist ()
302+
303+ assert "files/attachments/att_ok.txt" in namelist
304+ assert "files/attachments/.txt" not in namelist
305+
278306
279307class TestAstrBotImporter :
280308 """AstrBotImporter 类测试"""
0 commit comments