This commit is contained in:
2026-10-25 10:30:22 +08:00
parent 38894ba80c
commit ae84347912
11 changed files with 287 additions and 12 deletions

View File

@@ -212,3 +212,39 @@ def test_parse_translation_payload_accepts_fenced_json_and_numbered_lines():
12: "甲",
13: "乙",
}
def test_ai_tutor_retranslates_english_existing_cache(monkeypatch):
def fake_post(endpoint, headers, json, timeout):
return _translation_response_from_prompt(json)
monkeypatch.setattr("sentence_api.ai_tutor.requests.post", fake_post)
tutor = AITutor("https://ai.test/v1", "secret", "test-model", 1)
translated = tutor.translate_sentences(
[(0, "Hello."), (1, "Thanks.")],
existing={0: "Hello.", 1: "谢谢。"},
)
assert translated[0] == "中文0"
assert translated[1] == "谢谢。"
def test_ai_tutor_retries_when_translation_stays_english(monkeypatch):
calls = {"count": 0}
def fake_post(endpoint, headers, json, timeout):
calls["count"] += 1
if calls["count"] == 1:
return FakeResponse(
body={"choices": [{"message": {"content": '{"0":"Hello."}'}}]}
)
return FakeResponse(
body={"choices": [{"message": {"content": '{"0":"你好。"}'}}]}
)
monkeypatch.setattr("sentence_api.ai_tutor.requests.post", fake_post)
tutor = AITutor("https://ai.test/v1", "secret", "test-model", 1)
translated = tutor.translate_sentences([(0, "Hello.")])
assert translated == {0: "你好。"}
assert calls["count"] >= 2

View File

@@ -1165,3 +1165,91 @@ def test_admin_gap_repair_requires_transcriber(tmp_path):
response = client.post(f"/api/v1/admin/videos/{VIDEO_HASH}/repair-gaps")
assert response.status_code == 503
def test_admin_can_repair_missing_and_english_translations(tmp_path, monkeypatch):
client = make_client(tmp_path)
repository = client.app.state.video_repository
_ready_video(repository)
repository.save_sentence_translations(
VIDEO_HASH,
{0: "你好。", 1: "Nice to meet you."},
)
requested = []
def translate_sentences(sentences, **kwargs):
requested.append([index for index, _text in sentences])
existing = dict(kwargs.get("existing") or {})
result = {}
for index, _text in sentences:
current = existing.get(index, "")
if current and any("\u4e00" <= char <= "\u9fff" for char in current):
result[index] = current
else:
result[index] = f"补译{index}"
return result
class StubAITutor:
available = True
stub = StubAITutor()
stub.translate_sentences = translate_sentences
monkeypatch.setattr(client.app.state, "ai_tutor", stub)
client.app.state.subtitle_translations.ai_tutor = stub
client.app.state.subtitle_translations.post_wait_seconds = 0.2
snapshot = client.get(f"/api/v1/admin/videos/{VIDEO_HASH}/subtitle-translation")
assert snapshot.status_code == 200
assert snapshot.json()["missing_count"] == 1
response = client.post(
f"/api/v1/admin/videos/{VIDEO_HASH}/subtitle-translation/repair"
)
assert response.status_code == 200, response.text
payload = response.json()
if not payload.get("complete"):
finished = wait_for_subtitle_translation(client, VIDEO_HASH)
payload = client.get(f"/api/v1/admin/videos/{VIDEO_HASH}/subtitle-translation").json()
payload["attempted_count"] = response.json()["attempted_count"]
payload["complete"] = finished.json()["complete"]
assert payload["attempted_count"] == 1
assert payload["complete"] is True
assert payload["missing_count"] == 0
document = repository.get_document(VIDEO_HASH)
assert [sentence.zh_text for sentence in document.sentences] == ["你好。", "补译1"]
assert requested
def test_admin_translation_repair_keeps_complete_chinese(tmp_path, monkeypatch):
client = make_client(tmp_path)
repository = client.app.state.video_repository
_ready_video(repository)
repository.save_sentence_translations(
VIDEO_HASH,
{0: "你好。", 1: "见到你很高兴。"},
)
called = {"count": 0}
def translate_sentences(sentences, **kwargs):
called["count"] += 1
return {index: f"新{index}" for index, _text in sentences}
class StubAITutor:
available = True
stub = StubAITutor()
stub.translate_sentences = translate_sentences
monkeypatch.setattr(client.app.state, "ai_tutor", stub)
client.app.state.subtitle_translations.ai_tutor = stub
response = client.post(
f"/api/v1/admin/videos/{VIDEO_HASH}/subtitle-translation/repair"
)
assert response.status_code == 200, response.text
assert response.json()["attempted_count"] == 0
assert response.json()["missing_count"] == 0
assert called["count"] == 0
document = repository.get_document(VIDEO_HASH)
assert [sentence.zh_text for sentence in document.sentences] == ["你好。", "见到你很高兴。"]