fix: 修复重新上报任务状态不一致 (#91)

This commit is contained in:
chengma
2026-08-10 11:18:06 +08:00
parent d81aa25b13
commit 077cba6831
7 changed files with 352 additions and 27 deletions
+76 -1
View File
@@ -15,6 +15,7 @@ from PyQt5.QtWidgets import QApplication
from qfluentwidgets import InfoBarPosition
from src.android_device_service import AndroidDeviceSearchError
from src.db import open_database
from src.pdd_ui import PDDTaskPage
from src.admin_gateway import AdminGatewayError, AdminTask, SubmissionReceipt
from src.pdd_ui_event import (
@@ -32,7 +33,13 @@ 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
from src.task_models import (
NewClaimedTask,
OutboxEventType,
TaskStatus,
TaskSummary,
TaskType,
)
from src.task_repository import TaskRepository
from src.ui_main import MainWindow
@@ -136,6 +143,7 @@ class RecordingResubmitGateway(RecordingClaimGateway):
self.failures = dict(failures or {})
self.delay = delay
self.submit_calls = []
self.failure_calls = []
def submit_result(self, task_id, idempotency_key, result):
self.submit_calls.append((task_id, idempotency_key, result))
@@ -146,6 +154,15 @@ class RecordingResubmitGateway(RecordingClaimGateway):
raise error
return SubmissionReceipt(True, f"RESULT-{task_id}", "2026-08-10T08:00:00Z")
def submit_failure(self, task_id, idempotency_key, failure):
self.failure_calls.append((task_id, idempotency_key, failure))
if self.delay:
time.sleep(self.delay)
error = self.failures.get(task_id)
if error is not None:
raise error
return SubmissionReceipt(True, f"FAILURE-{task_id}", "2026-08-10T08:00:00Z")
class FakeCollectResult:
def to_pdd_data(self):
@@ -457,6 +474,64 @@ class PDDTaskPageEventTest(unittest.TestCase):
events.shutdown()
page.deleteLater()
def test_resubmit_prioritizes_pending_failure_and_repairs_task_status(self):
self._add_task(1)
first = self.repository.start_collect_run("PDD-001", "USB-001")
result = self.repository.save_collect_result(
"PDD-001", first.attempt_id, FakeCollectResult().to_pdd_data()
)
self.repository.mark_outbox_sent(result.id)
self.repository.prepare_collect_rerun("PDD-001")
second = self.repository.start_collect_run("PDD-001", "USB-001")
failure = self.repository.save_collect_failure(
"PDD-001",
second.attempt_id,
TaskStatus.FAILED,
"SKU_PANEL_NOT_FOUND",
"规格面板加载超时",
False,
)
connection = open_database(self.db_path)
try:
with connection:
connection.execute(
"UPDATE pdd_tasks SET status = 'succeeded',"
" current_step = 'completed' WHERE remote_task_id = 'PDD-001'"
)
finally:
connection.close()
page = PDDTaskPage()
gateway = RecordingResubmitGateway()
events = PDDTaskPageEvent(page, self.repository, claim_gateway=gateway)
events.load_initial_tasks()
page.taskModel.setData(
page.taskModel.index(0, 0), Qt.Checked, Qt.CheckStateRole
)
with patch("src.pdd_ui_event.MessageBox") as message_box:
message_box.return_value.exec.return_value = True
page.resubmitButton.click()
self.assertTrue(wait_until(self.app, lambda: not events._resubmit_busy))
self.assertEqual(gateway.submit_calls, [])
self.assertEqual(len(gateway.failure_calls), 1)
task_id, idempotency_key, payload = gateway.failure_calls[0]
self.assertEqual(task_id, "PDD-001")
self.assertEqual(idempotency_key, failure.idempotency_key)
self.assertEqual(payload, failure.payload_json)
self.assertEqual(payload["status"], TaskStatus.FAILED.value)
self.assertEqual(
self.repository.get_outbox_event(failure.id).event_type,
OutboxEventType.TASK_FAILURE,
)
repaired = self.repository.get_task("PDD-001")
self.assertEqual(repaired.status, TaskStatus.FAILED)
self.assertEqual(repaired.last_error_code, "SKU_PANEL_NOT_FOUND")
self.device_checker.assert_not_called()
events.shutdown()
page.deleteLater()
def test_resubmit_confirmation_cancel_does_not_submit(self):
self._add_task(1)
page = PDDTaskPage()