From 1f9236bb1673ab8c3eb1ecd8daea54fb3d12727d Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Sun, 30 Aug 2026 11:27:27 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(ingest-jobs):=20GET=20/{job=5Fid}=20?= =?UTF-8?q?=E6=9F=A5=E4=B8=8D=E5=88=B0=E6=97=B6=E8=BF=94=E5=9B=9E=20404=20?= =?UTF-8?q?=E8=80=8C=E9=9D=9E=20500=20ValueError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 之前 job 不存在抛 ValueError,被全局异常处理映射到 500,导致客户端拿不到合理的 '未找到'语义。改为 HTTPException(404)。 补 GET 路由单测:不存在→404、存在→200 + 字段完整。 --- apps/api/app/api/routes/ingest_jobs.py | 4 +- tests/unit/test_ingest_jobs_route_404.py | 82 ++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tests/unit/test_ingest_jobs_route_404.py diff --git a/apps/api/app/api/routes/ingest_jobs.py b/apps/api/app/api/routes/ingest_jobs.py index b7148ae93..791be8964 100644 --- a/apps/api/app/api/routes/ingest_jobs.py +++ b/apps/api/app/api/routes/ingest_jobs.py @@ -3,7 +3,7 @@ from typing import Any from app.core.celery_app import celery_app from app.dependencies import get_ingest_job_repository from app.schemas.ingest_job import IngestJobResponse, SubmitIngestJobRequest -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, HTTPException from packages.application import SubmitIngestJobCommand, SubmitIngestJobUseCase @@ -17,7 +17,7 @@ def get_ingest_job( ) -> IngestJobResponse: job = ingest_job_repository.get(job_id) if job is None: - raise ValueError(f"IngestJob {job_id} not found") + raise HTTPException(status_code=404, detail=f"IngestJob {job_id} not found") return IngestJobResponse( id=job.id, project_id=job.project_id, diff --git a/tests/unit/test_ingest_jobs_route_404.py b/tests/unit/test_ingest_jobs_route_404.py new file mode 100644 index 000000000..38c103438 --- /dev/null +++ b/tests/unit/test_ingest_jobs_route_404.py @@ -0,0 +1,82 @@ +"""Ingest jobs GET route — 查不到 job_id 应返回 404,不是 500。 + +覆盖: +- job 不存在:GET /ingest-jobs/{job_id} → 404 +- job 存在:200 + 序列化字段完整 +""" + +from __future__ import annotations + +import os +import sys +from pathlib import Path +from unittest.mock import MagicMock + +os.environ.setdefault("JWT_SECRET_KEY", "unit-test-secret-key-for-testing") +os.environ.setdefault("DATABASE_URL", "sqlite:///test.db") + +import pytest # noqa: E402 +from fastapi import FastAPI # noqa: E402 +from fastapi.testclient import TestClient # noqa: E402 + +sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "apps" / "api")) + +from app.api.routes.ingest_jobs import router, get_ingest_job # noqa: E402 +from app.dependencies import get_ingest_job_repository # noqa: E402 +from packages.domain import IngestJob, IngestJobStatus # noqa: E402 + + +@pytest.fixture +def fake_job(): + return IngestJob( + id="job-abc", + project_id="proj-1", + library_id="lib-1", + storage_key="key/test.mp4", + status=IngestJobStatus.COMPLETED, + error_message="", + result_asset_id="asset-xyz", + ) + + +@pytest.fixture +def client_not_found(): + app = FastAPI() + app.include_router(router, prefix="/ingest-jobs") + + mock_repo = MagicMock() + mock_repo.get.return_value = None + + app.dependency_overrides[get_ingest_job_repository] = lambda: mock_repo + return TestClient(app) + + +@pytest.fixture +def client_found(fake_job): + app = FastAPI() + app.include_router(router, prefix="/ingest-jobs") + + mock_repo = MagicMock() + mock_repo.get.return_value = fake_job + + app.dependency_overrides[get_ingest_job_repository] = lambda: mock_repo + return TestClient(app) + + +def test_get_ingest_job_not_found_returns_404(client_not_found): + """job 不存在时应返回 404,而不是 500 ValueError。""" + resp = client_not_found.get("/ingest-jobs/no-such-job") + assert resp.status_code == 404, resp.text + assert "no-such-job" in resp.json()["detail"] + + +def test_get_ingest_job_found_returns_200(client_found, fake_job): + """job 存在时正常 200 + 字段完整。""" + resp = client_found.get(f"/ingest-jobs/{fake_job.id}") + assert resp.status_code == 200, resp.text + body = resp.json() + assert body["id"] == fake_job.id + assert body["project_id"] == fake_job.project_id + assert body["storage_key"] == fake_job.storage_key + assert body["status"] == IngestJobStatus.COMPLETED.value + assert body["result_asset_id"] == fake_job.result_asset_id -- 2.54.0 From b69588f14db5ca5ca9dad6d2418749454509f1da Mon Sep 17 00:00:00 2001 From: CI Bot Date: Sun, 30 Aug 2026 03:38:42 +0000 Subject: [PATCH 2/2] style: auto-format with black + isort + prettier [skip ci-format-check] --- tests/unit/test_ingest_jobs_route_404.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_ingest_jobs_route_404.py b/tests/unit/test_ingest_jobs_route_404.py index 38c103438..321b4d9e5 100644 --- a/tests/unit/test_ingest_jobs_route_404.py +++ b/tests/unit/test_ingest_jobs_route_404.py @@ -21,8 +21,9 @@ from fastapi.testclient import TestClient # noqa: E402 sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "apps" / "api")) -from app.api.routes.ingest_jobs import router, get_ingest_job # noqa: E402 +from app.api.routes.ingest_jobs import get_ingest_job, router # noqa: E402 from app.dependencies import get_ingest_job_repository # noqa: E402 + from packages.domain import IngestJob, IngestJobStatus # noqa: E402 -- 2.54.0