from __future__ import annotations import unittest from tempfile import TemporaryDirectory from unittest.mock import patch from fastapi import FastAPI from fastapi.testclient import TestClient from sqlalchemy import BigInteger, create_engine from sqlalchemy.ext.compiler import compiles from sqlalchemy.orm import Session, sessionmaker from sqlalchemy.pool import StaticPool import app.models.document_archive # noqa: E402,F401 import app.models.master_data # noqa: E402,F401 import app.models.miniapp # noqa: E402,F401 import app.models.operations # noqa: E402,F401 import app.models.org # noqa: E402,F401 import app.models.planning # noqa: E402,F401 import app.models.sales # noqa: E402,F401 from app.api.routes.document_archives import normalize_document_type_key, router # noqa: E402 from app.db.session import get_db # noqa: E402 from app.models.base import Base # noqa: E402 from app.services.auth import require_authenticated_user # noqa: E402 @compiles(BigInteger, "sqlite") def _compile_big_integer_for_sqlite(type_, compiler, **kw) -> str: _ = type_, compiler, kw return "INTEGER" class DocumentArchiveRouteTest(unittest.TestCase): def setUp(self) -> None: engine = create_engine( "sqlite+pysqlite:///:memory:", connect_args={"check_same_thread": False}, poolclass=StaticPool, future=True, ) Base.metadata.create_all(engine) self.SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False, future=True) app = FastAPI() app.include_router(router, prefix="/document-archives") def override_get_db() -> Session: db = self.SessionLocal() try: yield db finally: db.close() def override_require_authenticated_user() -> dict[str, int]: return {"user_id": 123} app.dependency_overrides[get_db] = override_get_db app.dependency_overrides[require_authenticated_user] = override_require_authenticated_user self.client = TestClient(app) def test_normalize_document_type_key_supports_route_keys(self) -> None: self.assertEqual(normalize_document_type_key("sales-order"), "销售订单") self.assertEqual(normalize_document_type_key("purchase-order"), "采购订单") self.assertEqual(normalize_document_type_key("quality-inspection"), "质量校验单") self.assertEqual(normalize_document_type_key("production-material-out"), "生产领料出库单") self.assertEqual(normalize_document_type_key("production-inbound-settlement"), "生产入库结算单") self.assertEqual(normalize_document_type_key("warehouse-operation"), "仓库出入库单") self.assertEqual(normalize_document_type_key("仓库出入库单"), "仓库出入库单") def test_preview_missing_archive_returns_chinese_404(self) -> None: response = self.client.get("/document-archives/sales-order/999/latest/preview") self.assertEqual(response.status_code, 404) self.assertIn("归档文件不存在", response.json()["detail"]) def test_batch_download_missing_archives_returns_chinese_404(self) -> None: with TemporaryDirectory() as tmp_dir, patch("app.api.routes.document_archives.default_archive_root", return_value=tmp_dir): response = self.client.post( "/document-archives/batch-download", json={"document_type": "sales-order", "business_ids": [999]}, ) self.assertEqual(response.status_code, 404) self.assertIn("没有可下载的归档文件", response.json()["detail"]) if __name__ == "__main__": unittest.main()