Files
cmautobuy/client/test/test_pdd_ui_event.py
T

149 lines
4.9 KiB
Python

"""PDD 任务列表接入 SQLite 的离屏测试。"""
import os
import tempfile
import unittest
from pathlib import Path
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
from PyQt5.QtWidgets import QApplication
from src.pdd_ui import PDDTaskPage
from src.pdd_ui_event import PDDTaskPageEvent, summary_to_row
from src.mock_admin_gateway import MockAdminGateway
from src.settings_repository import SettingsRepository
from src.task_models import NewClaimedTask, TaskStatus, TaskSummary, TaskType
from src.task_repository import TaskRepository
from src.ui_main import MainWindow
class BrokenRepository:
"""模拟无法读取数据库的 Repository。"""
def list_tasks(self, filters=None, limit=50, offset=0):
raise RuntimeError("database is unavailable")
class PDDTaskPageEventTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.app = QApplication.instance() or QApplication([])
def setUp(self):
self.temp_directory = tempfile.TemporaryDirectory()
self.db_path = Path(self.temp_directory.name) / "client.db"
self.repository = TaskRepository(self.db_path)
def tearDown(self):
self.temp_directory.cleanup()
def _add_task(
self,
number: int,
task_type: TaskType = TaskType.COLLECT,
title: str = "测试商品",
) -> None:
self.repository.add_claimed_task(
NewClaimedTask(
remote_task_id=f"PDD-{number:03d}",
task_type=task_type,
goods_url=f"pdd://goods/{number}",
goods_id=str(number),
title=title,
target_color="黑色",
target_size="M",
price_cent=3990,
quantity=1 if task_type is TaskType.PURCHASE else None,
),
received_at="2026-08-06T08:00:00Z",
)
def test_initial_load_and_fetch_next_page(self):
for number in range(51):
self._add_task(number)
page = PDDTaskPage()
events = PDDTaskPageEvent(page, self.repository)
events.load_initial_tasks()
self.assertEqual(page.taskModel.data_row_count(), 50)
self.assertEqual(page.taskModel.row_at(0).remote_task_id, "PDD-050")
self.assertTrue(page.taskModel.canFetchMore())
page.taskModel.fetchMore()
self.assertEqual(page.taskModel.data_row_count(), 51)
self.assertEqual(page.taskModel.row_at(50).remote_task_id, "PDD-000")
self.assertFalse(page.taskModel.canFetchMore())
page.deleteLater()
def test_search_uses_type_status_and_keyword_together(self):
self._add_task(1, TaskType.COLLECT, "目标短袖")
self._add_task(2, TaskType.PURCHASE, "目标短袖")
self._add_task(3, TaskType.COLLECT, "其他商品")
page = PDDTaskPage()
events = PDDTaskPageEvent(page, self.repository)
page.searchRequested.emit(
{"task_type": "采集", "status": "待执行", "keyword": "目标"}
)
self.assertEqual(page.taskModel.data_row_count(), 1)
row = page.taskModel.row_at(0)
self.assertEqual(row.remote_task_id, "PDD-001")
self.assertEqual(row.task_type, "采集")
self.assertEqual(row.status, "待执行")
self.assertEqual(row.price_cents, 3990)
page.deleteLater()
def test_query_failure_shows_readable_error(self):
page = PDDTaskPage()
events = PDDTaskPageEvent(page, BrokenRepository())
events.load_initial_tasks()
self.assertFalse(page.emptyStateCard.isHidden())
self.assertEqual(page.emptyTitleLabel.text(), "任务加载失败")
self.assertIn("检查数据库", page.emptyMessageLabel.text())
self.assertFalse(page.taskModel.canFetchMore())
page.deleteLater()
def test_summary_to_row_does_not_copy_detail_json(self):
summary = TaskSummary(
id=1,
remote_task_id="PDD-001",
task_type=TaskType.PURCHASE,
goods_id=None,
title=None,
target_color=None,
target_size=None,
price_cent=None,
quantity=2,
status=TaskStatus.MANUAL_REVIEW,
updated_at="2026-08-06T08:00:00Z",
)
row = summary_to_row(summary)
self.assertEqual(row.task_type, "采购")
self.assertEqual(row.status, "需要人工处理")
self.assertEqual(row.goods_id, "")
self.assertFalse(hasattr(row, "pdd_data"))
def test_main_window_keeps_event_object_alive(self):
window = MainWindow(
task_repository=self.repository,
settings_repository=SettingsRepository(self.db_path),
admin_gateway=MockAdminGateway(),
)
self.assertIsInstance(window.pddTaskPageEvent, PDDTaskPageEvent)
self.assertEqual(window.pddTaskPage.taskModel.data_row_count(), 0)
window.close()
window.deleteLater()
if __name__ == "__main__":
unittest.main()