fix: StubGenerationTaskRepository补list_by_user_filtered方法 #306

Merged
xiaoxia merged 6 commits from fix/stub-generation-task-repository-filtered-methods into develop 2026-07-14 11:02:57 +08:00
5 changed files with 294 additions and 4 deletions
+64
View File
@@ -138,6 +138,70 @@ class StubGenerationTaskRepository:
def list_by_source_edit_plan(self, plan_id: str) -> list[GenerationTask]:
return [t for t in self._tasks.values() if getattr(t, "source_edit_plan_id", "") == plan_id]
def list_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按用户+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
) -> int:
"""按用户+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
def list_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按项目+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
) -> int:
"""按项目+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
class StubGeneratedVideoRepository:
def __init__(self, videos: dict[str, GeneratedVideo] | None = None):
+70 -4
View File
@@ -103,6 +103,70 @@ class StubGenerationTaskRepository:
def list_by_source_edit_plan(self, plan_id: str) -> list[GenerationTask]:
return [t for t in self._tasks.values() if getattr(t, "source_edit_plan_id", "") == plan_id]
def list_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按用户+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
) -> int:
"""按用户+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
def list_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按项目+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
) -> int:
"""按项目+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
class StubIngestJobRepository:
def __init__(self, jobs: dict[str, IngestJob] | None = None):
@@ -470,8 +534,8 @@ class TestRetryProjectTask:
assert data["task_type"] == "generation"
assert data["status"] == "pending"
assert "current_step" in data
# 验证新任务的 ID 不同于原任务
assert data["source_id"] != "gen-failed-1"
# 原地重试:source_id 保持不变(复用同一个任务
assert data["source_id"] == "gen-failed-1"
# 验证 Celery 任务被发送
assert mock_celery.send_task.called
@@ -630,11 +694,13 @@ class TestTaskCenterCrossEndpoint:
retry_resp = tc.post("/tasks/gen-fail-cross/retry")
assert retry_resp.status_code == 200
# 3. 再次列出,应有2个任务(旧的failed + 新的pending
# 3. 再次列出:原地重试,任务数不变(仍是1个),但状态变为 pending
list_resp2 = tc.get("/tasks")
assert list_resp2.status_code == 200
items2 = list_resp2.json()["items"]
assert len(items2) == 2
assert len(items2) == 1
assert items2[0]["status"] == "pending"
assert items2[0]["source_id"] == "gen-fail-cross"
test_app.dependency_overrides.clear()
@@ -193,6 +193,70 @@ class StubGenerationTaskRepository:
items.sort(key=lambda t: t.created_at, reverse=True)
return items[:limit]
def list_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按用户+状态筛选任务列表(stub实现)。"""
items = [t for t in self._store.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
) -> int:
"""按用户+状态筛选计数(stub实现)。"""
items = [t for t in self._store.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
def list_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按项目+状态筛选任务列表(stub实现)。"""
items = [t for t in self._store.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
) -> int:
"""按项目+状态筛选计数(stub实现)。"""
items = [t for t in self._store.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
# ── Fixtures ──────────────────────────────────────────────────────────────────
+64
View File
@@ -200,6 +200,70 @@ class StubGenerationTaskRepository:
def count_pending_total(self) -> int:
return 0
def list_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按用户+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_user_filtered(
self,
user_id: str,
*,
status: str | None = None,
) -> int:
"""按用户+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.created_by_user_id == user_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
def list_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
limit: int | None = None,
offset: int = 0,
) -> list:
"""按项目+状态筛选任务列表(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
# 按创建时间倒序
items.sort(key=lambda t: t.created_at or "", reverse=True)
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_project_filtered(
self,
project_id: str,
*,
status: str | None = None,
) -> int:
"""按项目+状态筛选计数(stub实现)。"""
items = [t for t in self._tasks.values() if t.project_id == project_id]
if status:
items = [t for t in items if str(t.status) == status]
return len(items)
# ---------------------------------------------------------------------------
# Service factory
@@ -64,6 +64,38 @@ class StubGenerationTaskRepository:
def count_pending_total(self):
return 0
def list_by_user_filtered(self, user_id, *, status=None, limit=None, offset=0):
items = [t for t in self._tasks.values() if getattr(t, "created_by_user_id", None) == user_id]
if status:
items = [t for t in items if getattr(t, "status", None) == status]
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_user_filtered(self, user_id, *, status=None):
items = [t for t in self._tasks.values() if getattr(t, "created_by_user_id", None) == user_id]
if status:
items = [t for t in items if getattr(t, "status", None) == status]
return len(items)
def list_by_project_filtered(self, project_id, *, status=None, limit=None, offset=0):
items = [t for t in self._tasks.values() if getattr(t, "project_id", None) == project_id]
if status:
items = [t for t in items if getattr(t, "status", None) == status]
if offset:
items = items[offset:]
if limit is not None:
items = items[:limit]
return items
def count_by_project_filtered(self, project_id, *, status=None):
items = [t for t in self._tasks.values() if getattr(t, "project_id", None) == project_id]
if status:
items = [t for t in items if getattr(t, "status", None) == status]
return len(items)
class StubGeneratedVideoRepository:
def __init__(self, videos=None):