From 3428aed4903e514459a757ff8dfdfe0440ce42c7 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 24 Sep 2026 14:48:41 +0800 Subject: [PATCH] fix(transfer): keep automatic music selection per file --- app/api/endpoints/transfer.py | 4 +- tests/test_transfer_history_retransfer.py | 68 +++++++++++++++++++++-- 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/app/api/endpoints/transfer.py b/app/api/endpoints/transfer.py index afe96a07d..46e9bcc4d 100644 --- a/app/api/endpoints/transfer.py +++ b/app/api/endpoints/transfer.py @@ -208,8 +208,8 @@ def _selected_music_fileitems( explicitly_selected: bool, media_type: Optional[MediaType], ) -> Optional[List[FileItem]]: - """返回需要共享专辑上下文的显式多选音轨。""" - if not explicitly_selected or media_type not in (None, MediaType.MUSIC): + """仅在用户明确选择音乐类型时,将显式多选音轨作为专辑批次处理。""" + if not explicitly_selected or media_type != MediaType.MUSIC: return None if not _is_music_file_batch(fileitems): return None diff --git a/tests/test_transfer_history_retransfer.py b/tests/test_transfer_history_retransfer.py index 5e00fafd8..4ffd0c4d3 100644 --- a/tests/test_transfer_history_retransfer.py +++ b/tests/test_transfer_history_retransfer.py @@ -465,7 +465,7 @@ def test_manual_transfer_preview_multi_select_collects_failures(monkeypatch): def test_manual_transfer_music_files_share_one_album_batch(monkeypatch): - """多选音轨应一次进入整理链,避免按单曲丢失专辑分类上下文。""" + """明确选择音乐类型时,多选音轨应共享专辑批次上下文。""" selected_fileitems = [ { "storage": "local", @@ -508,7 +508,7 @@ def test_manual_transfer_music_files_share_one_album_batch(monkeypatch): transer_item=ManualTransferItem( fileitems=selected_fileitems, preview=True, - type_name="自动", + type_name="音乐", ), background=False, history_query=SimpleNamespace(get=lambda _history_id: None), @@ -525,6 +525,66 @@ def test_manual_transfer_music_files_share_one_album_batch(monkeypatch): ] +def test_manual_transfer_auto_audio_selection_uses_single_file_flow(monkeypatch): + """自动类型下多选音频仍逐文件识别,避免数量改变音乐分类结果。""" + selected_fileitems = [ + FileItem( + storage="local", + path=f"/downloads/爱像太平洋/{index:02d}.flac", + name=f"{index:02d}.flac", + extension="flac", + type="file", + ) + for index in (2, 3) + ] + captured = [] + + class FakeTransferChain: + """记录自动多选请求是否保留逐文件识别语义。""" + + def manual_transfer(self, **kwargs): + """返回当前文件的一条成功预览。""" + captured.append(kwargs) + fileitem = kwargs["fileitem"] + return True, { + "summary": {"total": 1, "success": 1, "failed": 0}, + "items": [{ + "source": fileitem.path, + "target": f"/library/合辑/{fileitem.name}", + "target_dir": "/library/合辑", + "success": True, + }], + "message": "", + } + + monkeypatch.setattr("app.api.endpoints.transfer.TransferChain", FakeTransferChain) + monkeypatch.setattr( + "app.api.endpoints.transfer.get_api_runtime_config_snapshot", + lambda: SimpleNamespace(audio_extensions=(".flac",)), + ) + + response = manual_transfer( + transer_item=ManualTransferItem( + fileitems=selected_fileitems, + preview=True, + type_name="自动", + ), + background=False, + history_query=SimpleNamespace(get=lambda _history_id: None), + _="token", + ) + + assert response.success is True + assert response.data["summary"] == {"total": 2, "success": 2, "failed": 0} + assert len(captured) == 2 + assert [call["fileitem"].path for call in captured] == [ + item.path for item in selected_fileitems + ] + assert all(call["mtype"] is None for call in captured) + assert all(call["music_type"] is None for call in captured) + assert all("selected_fileitems" not in call for call in captured) + + def test_manual_transfer_music_batch_ignores_non_disc_alternate_directory(monkeypatch): """根目录已有完整专辑时,不得把“附加原版”等任意子目录当成第二张碟。""" selected_fileitems = [ @@ -563,7 +623,7 @@ def test_manual_transfer_music_batch_ignores_non_disc_alternate_directory(monkey transer_item=ManualTransferItem( fileitems=selected_fileitems, preview=True, - type_name="自动", + type_name="音乐", ), background=False, history_query=SimpleNamespace(get=lambda _history_id: None), @@ -624,7 +684,7 @@ def test_manual_transfer_history_ids_share_one_music_album_batch(monkeypatch): logids=list(histories), preview=True, reorganize=True, - type_name="自动", + type_name="音乐", ), background=False, history_query=SimpleNamespace(get=histories.get),