SurfSense/surfsense_backend/tests/integration/podcasts/test_brief_gate.py
CREDO23 c84525897b test(podcasts): relocate stateful tests to integration
Move the lifecycle service, Celery task bodies, and mark_failed coverage out of
DB-faking unit tests and into integration tests against a real Postgres, faking
only true externals (broker, object store, TTS, ffmpeg, billing, LLM). Add HTTP
slices for cancel, voices, scoping, and public-chat streaming. The unit tier is
now fake-free pure logic with no session doubles.
2026-06-11 06:27:00 +02:00

80 lines
2.4 KiB
Python

"""The brief review gate: edit the spec, then approve to start drafting.
Covers what the user can do while ``awaiting_brief`` — edit the brief under
optimistic concurrency and approve it — and the HTTP status codes the service's
guards map to when an edit races or comes too late.
"""
from __future__ import annotations
import pytest
pytestmark = pytest.mark.integration
BASE = "/api/v1/podcasts"
async def _create(client, search_space_id: int) -> dict:
resp = await client.post(
BASE,
json={
"title": "Episode",
"search_space_id": search_space_id,
"source_content": "Source content.",
},
)
assert resp.status_code == 201
return resp.json()
async def test_approve_brief_starts_drafting_and_enqueues_draft(
client, db_search_space, captured_tasks
):
podcast = await _create(client, db_search_space.id)
resp = await client.post(f"{BASE}/{podcast['id']}/brief/approve")
assert resp.status_code == 200
assert resp.json()["status"] == "drafting"
assert captured_tasks.draft == [((podcast["id"], db_search_space.id), {})]
assert captured_tasks.render == []
async def test_update_spec_bumps_version_and_persists(client, db_search_space):
podcast = await _create(client, db_search_space.id)
spec = podcast["spec"]
spec["focus"] = "A sharper angle"
resp = await client.patch(
f"{BASE}/{podcast['id']}/spec",
json={"spec": spec, "expected_version": podcast["spec_version"]},
)
assert resp.status_code == 200
body = resp.json()
assert body["spec_version"] == podcast["spec_version"] + 1
assert body["spec"]["focus"] == "A sharper angle"
assert body["status"] == "awaiting_brief"
async def test_update_spec_with_stale_version_conflicts(client, db_search_space):
podcast = await _create(client, db_search_space.id)
resp = await client.patch(
f"{BASE}/{podcast['id']}/spec",
json={"spec": podcast["spec"], "expected_version": 999},
)
assert resp.status_code == 409
async def test_update_spec_after_approval_is_rejected(client, db_search_space):
podcast = await _create(client, db_search_space.id)
await client.post(f"{BASE}/{podcast['id']}/brief/approve")
resp = await client.patch(
f"{BASE}/{podcast['id']}/spec",
json={"spec": podcast["spec"], "expected_version": podcast["spec_version"]},
)
assert resp.status_code == 409