pc translate sentences

This commit is contained in:
2026-10-08 10:08:16 +08:00
parent b28f809c46
commit 4746331515
8 changed files with 714 additions and 4 deletions

View File

@@ -248,6 +248,91 @@ def test_subtitle_translation_requires_login(tmp_path):
assert response.status_code == 401
LOCAL_SUBTITLE_HASH = "b" * 64
def _stub_translator(monkeypatch, client, requested=None):
requested = requested if requested is not None else []
def translate_sentences(sentences, **kwargs):
requested.append((sentences, kwargs))
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)
return requested
def test_local_english_subtitles_can_be_uploaded_for_translation(tmp_path, monkeypatch):
client = make_client(tmp_path)
requested = _stub_translator(monkeypatch, client)
missing = client.post(f"/api/v1/videos/{LOCAL_SUBTITLE_HASH}/subtitle-translation")
assert missing.status_code == 404
response = client.post(
f"/api/v1/videos/{LOCAL_SUBTITLE_HASH}/subtitle-translation",
json={
"duration_ms": 9000,
"algorithm_version": "local-pc",
"sentences": [
{"index": 0, "start_ms": 0, "end_ms": 4000, "text": "Hello.", "language": "en"},
{"index": 1, "start_ms": 4000, "end_ms": 9000, "text": "Nice to meet you.", "language": "en"},
],
},
)
assert response.status_code == 200, response.text
if not response.json().get("complete"):
response = wait_for_subtitle_translation(client, LOCAL_SUBTITLE_HASH)
payload = response.json()
assert payload["complete"] is True
assert payload["translations"] == [
{"index": 0, "zh_text": "中文0"},
{"index": 1, "zh_text": "中文1"},
]
assert requested[0][0] == [(0, "Hello."), (1, "Nice to meet you.")]
stored = client.get(f"/api/v1/videos/{LOCAL_SUBTITLE_HASH}/subtitle-translation")
assert stored.status_code == 200
assert stored.json()["translations"] == payload["translations"]
courses = client.get("/api/v1/courses")
assert courses.status_code == 200
assert all(item["video_hash"] != LOCAL_SUBTITLE_HASH for item in courses.json())
videos = client.get("/api/v1/videos")
assert videos.status_code == 200
assert all(item["video_hash"] != LOCAL_SUBTITLE_HASH for item in videos.json()["videos"])
def test_local_subtitle_upload_does_not_overwrite_course_sentences(tmp_path, monkeypatch):
client = make_client(tmp_path)
_ready_video(client.app.state.video_repository)
requested = _stub_translator(monkeypatch, client)
response = client.post(
f"/api/v1/videos/{VIDEO_HASH}/subtitle-translation",
json={
"duration_ms": 9000,
"algorithm_version": "local-pc",
"sentences": [
{"index": 0, "start_ms": 0, "end_ms": 4000, "text": "Changed.", "language": "en"},
{"index": 1, "start_ms": 4000, "end_ms": 9000, "text": "Also changed.", "language": "en"},
],
},
)
assert response.status_code == 200, response.text
if not response.json().get("complete"):
response = wait_for_subtitle_translation(client, VIDEO_HASH)
assert requested[0][0] == [(0, "Hello."), (1, "Nice to meet you.")]
document = client.app.state.video_repository.get_document(VIDEO_HASH)
assert [sentence.text for sentence in document.sentences] == ["Hello.", "Nice to meet you."]
def test_subtitle_translation_uses_full_document_and_is_cached(tmp_path, monkeypatch):
client = make_client(tmp_path)
_ready_video(client.app.state.video_repository)