Files
life-echo/api/tests/test_infra_regressions.py
Kevin 07979bfb09 feat(api): use Tencent ASR flash with 16k_zh_large and dev transcript logs
Replace CreateRecTask polling with recording-file flash API, add TENCENT_APP_ID,
remove server-side pydub slicing, and log ASR recognition text at INFO in development.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-25 11:28:22 +08:00

107 lines
3.1 KiB
Python

import httpx
import pytest
from app.adapters.asr.tencent_asr import TencentASRProvider
from app.core import chapter_pipeline_lock
from app.features.story import post_commit
def test_chapter_pipeline_lock_delegates_to_token_lock(
monkeypatch: pytest.MonkeyPatch,
) -> None:
handle = object()
recorded: dict[str, object] = {}
def fake_acquire(key: str, *, ttl_seconds: int) -> object:
recorded["key"] = key
recorded["ttl_seconds"] = ttl_seconds
return handle
def fake_release(arg: object) -> None:
recorded["released"] = arg
monkeypatch.setattr(chapter_pipeline_lock, "acquire_redis_lock", fake_acquire)
monkeypatch.setattr(chapter_pipeline_lock, "release_redis_lock", fake_release)
acquired = chapter_pipeline_lock.acquire_chapter_pipeline_lock(
"user-1", "childhood", ttl_seconds=120
)
chapter_pipeline_lock.release_chapter_pipeline_lock(acquired)
assert acquired is handle
assert recorded == {
"key": "lock:chapter:user-1:childhood",
"ttl_seconds": 120,
"released": handle,
}
def test_post_commit_reuses_singleton_redis_client(
monkeypatch: pytest.MonkeyPatch,
) -> None:
client = object()
def fake_get_sync_redis(*, decode_responses: bool):
assert decode_responses is True
return client
monkeypatch.setattr(post_commit, "get_sync_redis", fake_get_sync_redis)
first = post_commit._get_redis()
second = post_commit._get_redis()
assert first is second
assert first is client
@pytest.mark.asyncio
async def test_tencent_asr_flash_transcribe(
monkeypatch: pytest.MonkeyPatch,
) -> None:
captured: dict[str, object] = {}
class FakeAsyncClient:
async def __aenter__(self):
return self
async def __aexit__(self, *args):
return None
async def post(self, url, *, headers=None, content=None, timeout=None):
captured["url"] = url
captured["headers"] = headers
captured["content"] = content
captured["timeout"] = timeout
return httpx.Response(
200,
json={
"code": 0,
"request_id": "req-1",
"flash_result": [{"channel_id": 0, "text": " 你好,世界 "}],
},
)
monkeypatch.setattr(httpx, "AsyncClient", FakeAsyncClient)
provider = TencentASRProvider(
"sid",
"skey",
"1259220000",
engine_type="16k_zh_large",
)
text = await provider.transcribe(b"fake-audio", format="m4a")
assert text == "你好,世界"
assert captured["content"] == b"fake-audio"
assert captured["timeout"] == 60.0
url = str(captured["url"])
assert "engine_type=16k_zh_large" in url
assert "voice_format=m4a" in url
assert "/asr/flash/v1/1259220000?" in url
assert "secretid=sid" in url
headers = captured["headers"]
assert headers is not None
assert headers["Authorization"]
assert headers["Content-Type"] == "application/octet-stream"
assert headers["Content-Length"] == str(len(b"fake-audio"))