fix: 优化重新采集取消交互 (#82)

This commit is contained in:
chengma
2026-08-10 09:08:54 +08:00
parent 8cc8574e8a
commit 39f4a8ee4f
6 changed files with 307 additions and 16 deletions
+34
View File
@@ -194,6 +194,40 @@ class CollectTaskServiceTest(unittest.TestCase):
self.repository.get_task("COL-OTHER").status, TaskStatus.CLAIMED
)
def test_selected_task_cancelled_before_collector_starts_is_persisted(self):
self.repository.add_claimed_task(
NewClaimedTask(
remote_task_id="COL-CANCEL",
task_type=TaskType.COLLECT,
goods_url="https://example.test/COL-CANCEL",
)
)
calls = []
class AcceptGateway:
def submit_failure(self, *_args):
return SubmissionReceipt(
True, "FAILURE-001", "2026-08-07T08:00:00Z"
)
service = CollectTaskService(
AcceptGateway(),
self.repository,
self.client,
"USB-001",
cancelled=lambda: True,
collect_service_factory=lambda *_args: FakeCollector(calls),
)
outcome = service.execute_selected("COL-CANCEL")
self.assertEqual(outcome.kind, "cancelled")
self.assertEqual(calls, [])
self.assertEqual(
self.repository.get_task("COL-CANCEL").status,
TaskStatus.CANCELLED,
)
if __name__ == "__main__":
unittest.main()
+120
View File
@@ -21,6 +21,7 @@ from src.pdd_ui_event import (
)
from src.mock_admin_gateway import MockAdminGateway
from src.pdd_purchase_adapter import PddPurchaseAdapter, PurchasePageState
from src.pdd_collect_service import PddCollectError
from src.pdd_u2_purchase_adapter import create_u2_purchase_adapter
from src.settings_repository import SettingsRepository
from src.task_models import NewClaimedTask, TaskStatus, TaskSummary, TaskType
@@ -361,6 +362,125 @@ class PDDTaskPageEventTest(unittest.TestCase):
events.shutdown()
page.deleteLater()
def test_rerun_confirmation_has_clear_safe_cancel_action(self):
self._add_task(1)
first = self.repository.start_collect_run("PDD-001", "USB-001")
event = self.repository.save_collect_result(
"PDD-001", first.attempt_id, FakeCollectResult().to_pdd_data()
)
self.repository.mark_outbox_sent(event.id)
page = PDDTaskPage()
events = PDDTaskPageEvent(
page,
self.repository,
claim_gateway=RecordingClaimGateway(),
settings_repository=self._saved_settings(),
collect_service_factory=fake_collect_factory,
)
with patch("src.pdd_ui_event.MessageBox") as message_box:
message_box.return_value.exec.return_value = False
page.rerunRequested.emit("PDD-001")
message_box.return_value.cancelButton.setText.assert_called_once_with(
"暂不重新采集"
)
message_box.return_value.cancelButton.setFocus.assert_called_once_with()
self.assertFalse(events._claim_busy)
self.assertEqual(
self.repository.get_task("PDD-001").status, TaskStatus.SUCCEEDED
)
events.shutdown()
page.deleteLater()
def test_running_rerun_can_request_cooperative_cancel_once(self):
self._add_task(1)
first = self.repository.start_collect_run("PDD-001", "USB-001")
event = self.repository.save_collect_result(
"PDD-001", first.attempt_id, FakeCollectResult().to_pdd_data()
)
self.repository.mark_outbox_sent(event.id)
started = threading.Event()
def cancellable_factory(_address, _client_id, cancelled):
class CancellableCollector:
def collect(self, _task):
started.set()
while not cancelled():
time.sleep(0.01)
raise PddCollectError("PDD_CANCELLED", "采集任务已安全取消")
return CancellableCollector()
page = PDDTaskPage()
events = PDDTaskPageEvent(
page,
self.repository,
claim_gateway=RecordingClaimGateway(),
settings_repository=self._saved_settings(),
collect_service_factory=cancellable_factory,
)
with patch("src.pdd_ui_event.MessageBox") as message_box:
message_box.return_value.exec.return_value = True
page.rerunRequested.emit("PDD-001")
self.assertTrue(started.wait(1.0), "重新采集没有启动")
self.assertTrue(
wait_until(
self.app,
lambda: page.rerunButton.text() == "停止重新采集",
)
)
self.assertTrue(page.rerunButton.isEnabled())
page.rerunButton.click()
self.app.processEvents()
self.assertEqual(page.rerunButton.text(), "正在停止…")
self.assertFalse(page.rerunButton.isEnabled())
self.assertIn("等待手机当前操作结束", page.statusLabel.text())
self.assertTrue(
wait_until(self.app, lambda: not events._claim_busy),
"取消后工作线程没有按时结束",
)
self.assertEqual(page.rerunButton.text(), "重新执行")
self.assertIn("停止请求已处理", page.statusLabel.text())
events.shutdown()
page.deleteLater()
def test_rerun_feedback_has_close_button_and_replaces_previous(self):
page = PDDTaskPage()
events = PDDTaskPageEvent(page, self.repository)
events._show_rerun_warning("暂时不能重新执行", "测试警告")
first = events._rerun_feedback
self.assertIsNotNone(first)
events._show_rerun_error("重新采集失败", "测试错误")
second = events._rerun_feedback
self.assertIsNot(first, second)
close_buttons = [
button
for button in second.findChildren(type(page.rerunButton))
if button.text() == "关闭提示"
]
self.assertEqual(len(close_buttons), 1)
close_buttons[0].click()
self.app.processEvents()
self.assertIsNone(events._rerun_feedback)
events.shutdown()
page.deleteLater()
def test_late_rerun_success_does_not_override_cancel_status(self):
page = PDDTaskPage()
events = PDDTaskPageEvent(page, self.repository)
events._rerun_cancel_requested = True
events._on_rerun_outcome("succeeded", "采集成功", "PDD-001")
self.assertNotIn("采集成功", page.statusLabel.text())
self.assertIn("停止请求已处理", page.statusLabel.text())
events.shutdown()
page.deleteLater()
def test_query_failure_shows_readable_error(self):
page = PDDTaskPage()
events = PDDTaskPageEvent(page, BrokenRepository())