Files
writer-work-flow/apps/api/tests/test_chain_deps.py
Yaojia Wang 2fe3bedfba fix(qa): 修 QA C1/H1/H2——写章/规则缺项目校验 + 立项向导字段覆盖
C1 (CRITICAL) stream_draft:对不存在 project 流式写章先 fail-fast 404,
  否则非法 id 静默烧一次付费/限流 LLM 调用并返 200。在触网关前查 project_repo.get。
H2 (HIGH) create_rule:给不存在 project 加规则原 FK 违例逃逸成 500 → 改为入库前
  校验项目存在返 404(仿 chain/_require_project)。
H1 (HIGH) ProjectWizard:第3步「立意」与第4步「主角/金手指」原共用 form.premise
  互相覆盖丢数据 → 新增独立 form.protagonist,toCreateRequest 合并两段进 premise
  (M1 projects 表仍只有 premise,不编造 API)。

回归测试:
- test_projects.py:stream_draft 不存在 project → 404 且网关零调用;已有 draft
  用例改 seed 真项目。
- test_rules.py:create_rule 不存在 project → 404 不写库;已有用例 seed 真项目。
- wizard.test.ts:premise+protagonist 合并不互相覆盖(2 例)。
门禁绿:ruff/format clean · mypy 210 · pytest 749 · 前端 tsc/lint/vitest 干净。
2026-06-24 17:17:35 +02:00

42 lines
1.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""chain_deps._libpq_conn_string 单测——剥离 SQLAlchemy 驱动后缀(回归)。
bugruntime checkpointer 工厂曾把 `postgresql+psycopg://…`settings 的 sync URL
原样喂给 `AsyncPostgresSaver.from_conn_string`psycopg 不识别 `+psycopg` 方言段 →
`ProgrammingError: missing "=" …` → 多章链 job 直接 failed。E2E 用 MemorySaver 覆盖,
从不走真 conn string故此路径无回归保护。本用例锁住「剥离后缀」语义。
"""
from __future__ import annotations
import pytest
from ww_api.services import chain_deps
class _StubSettings:
def __init__(self, url: str) -> None:
self.database_url_sync = url
@pytest.mark.parametrize(
("raw", "expected"),
[
(
"postgresql+psycopg://writer:writer@localhost:5432/writer",
"postgresql://writer:writer@localhost:5432/writer",
),
("postgresql+asyncpg://u:p@h:5432/db", "postgresql://u:p@h:5432/db"),
("postgresql://u:p@h:5432/db", "postgresql://u:p@h:5432/db"),
],
)
def test_libpq_conn_string_strips_driver_suffix(
monkeypatch: pytest.MonkeyPatch, raw: str, expected: str
) -> None:
# Arrange
monkeypatch.setattr(chain_deps, "get_settings", lambda: _StubSettings(raw))
# Act
result = chain_deps._libpq_conn_string()
# Assert
assert result == expected
assert "+psycopg" not in result
assert "+asyncpg" not in result