feat(collect): support soft deletion of one task

This commit is contained in:
chengma
2026-07-20 10:27:21 +08:00
parent a92f1c86f4
commit 9852b1c9c1
8 changed files with 333 additions and 10 deletions
+109
View File
@@ -8827,6 +8827,115 @@ class GuiTests(TempDirMixin, unittest.TestCase):
self.assert_removed(temp_dir)
def test_collect_tab_soft_deletes_selected_task_from_context_menu(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)
accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
batch_id = db.create_batch(["input.xlsx"], path=cfg["db_path"])
db.insert_tasks(
batch_id,
[
{
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
"source_sheet": "商品",
"source_row": 2,
"account_name": "Excel主店",
"alias": "alias-a",
"item_id": "51100639510",
},
{
"source_file_abs": os.path.join(temp_dir, "input.xlsx"),
"source_sheet": "商品",
"source_row": 3,
"account_name": "Excel主店",
"alias": "alias-a",
"item_id": "51100639511",
},
],
path=cfg["db_path"],
)
first, second = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
db.set_collected(first.id, "旧标题", "old.jpg", path=cfg["db_path"])
db.set_generated(first.id, "新标题", "new.jpg", path=cfg["db_path"])
db.set_applied(first.id, True, path=cfg["db_path"])
db.set_collected(second.id, "旧标题2", "old2.jpg", path=cfg["db_path"])
db.set_generated(second.id, "新标题2", "new2.jpg", path=cfg["db_path"])
statuses = []
refresh_calls = []
generate_tab = GenerateTab(config=cfg)
apply_tab = ApplyTab(config=cfg)
apply_tab.status_filter.setCurrentIndex(apply_tab.status_filter.findData("all"))
def refresh_workflow():
refresh_calls.append(True)
generate_tab.refresh_tasks()
apply_tab.refresh_tasks()
collect_tab = CollectTab(
config=cfg,
status_callback=statuses.append,
refresh_workflow_callback=refresh_workflow,
)
self.addCleanup(collect_tab.close)
self.addCleanup(generate_tab.close)
self.addCleanup(apply_tab.close)
collect_tab.resize(1000, 600)
collect_tab.show()
QApplication.processEvents()
first_index = collect_tab.model.index(0, 0)
first_rect = collect_tab.table.visualRect(first_index)
self.assertTrue(first_rect.isValid())
class FakeMenu:
def __init__(self, parent=None):
self.actions = []
def addAction(self, text):
action = SimpleNamespace(
text=text,
enabled=True,
triggered=DummySignal(),
)
action.setEnabled = lambda enabled: setattr(action, "enabled", bool(enabled))
self.actions.append(action)
return action
def exec(self, position):
return None
with mock.patch("app.gui.tabs.collect.QMenu", FakeMenu):
collect_tab._show_task_context_menu(first_rect.center())
self.assertEqual(0, collect_tab.table.currentIndex().row())
with mock.patch(
"app.gui.QMessageBox.question",
return_value=gui.QMessageBox.No,
) as question:
collect_tab.delete_selected_task()
self.assertIsNotNone(db.get_task(first.id, path=cfg["db_path"]))
self.assertIn("已取消删除本条记录", statuses[-1])
self.assertIn("不会回滚蝦皮线上商品", question.call_args[0][2])
with mock.patch(
"app.gui.QMessageBox.question",
return_value=gui.QMessageBox.Yes,
), mock.patch("app.gui.QMessageBox.information") as information:
collect_tab.delete_selected_task()
self.assertIsNone(db.get_task(first.id, path=cfg["db_path"]))
self.assertEqual([second.id], [task.id for task in db.list_tasks(batch_id=batch_id, path=cfg["db_path"])])
self.assertTrue(all(task.id != first.id for task in generate_tab.model.tasks))
self.assertTrue(all(task.id != first.id for task in apply_tab.model.tasks))
self.assertEqual([True], refresh_calls)
self.assertIn("已删除本地记录:商品 51100639510", statuses[-1])
self.assertIn("已删除本地记录:商品 51100639510", information.call_args[0][2])
collect_tab.collect_thread = object()
collect_tab.delete_selected_task()
self.assertIn("采集或回写正在进行", statuses[-1])
self.assert_removed(temp_dir)
def test_collect_tab_can_filter_unmatched_tasks_from_summary_bar(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)