"""Email translation over the API, with LibreTranslate replaced by a stand-in.""" from __future__ import annotations import pytest from app import translation from tests.api.conftest import MailCtx, raw_mail TEXT = "Hello Lukas, I would like to ask about the project schedule for next month." @pytest.fixture def fake_service(monkeypatch: pytest.MonkeyPatch) -> dict[str, object]: calls: dict[str, object] = {"detect": 0, "translate": 0} async def detect(text: str) -> str: calls["detect"] = int(calls["detect"]) + 1 # type: ignore[call-overload] return "en" async def translate_html( html: str, source: str, target: str, keep: object = (), names: object = () ) -> str: calls["translate"] = int(calls["translate"]) + 1 # type: ignore[call-overload] calls["keep"] = list(keep) # type: ignore[call-overload] calls["names"] = list(names) # type: ignore[call-overload] assert source == "en" and target == "pl" return "
Cześć Łukasz
" monkeypatch.setattr(translation, "enabled", lambda: True) monkeypatch.setattr(translation, "detect", detect) monkeypatch.setattr(translation, "translate_html", translate_html) return calls async def test_language_is_found_once_and_kept( mail_ctx: MailCtx, fake_service: dict[str, object] ) -> None: msg = await mail_ctx.deliver(raw_mail("Project", html=f"{TEXT}
"), 1) for _ in range(2): resp = await mail_ctx.client.get(f"/api/messages/{msg.id}/html") assert resp.headers["X-Content-Language"] == "en" assert fake_service["detect"] == 1 (env,) = (await mail_ctx.client.get(f"/api/threads/{msg.thread_id}")).json()["messages"] assert env["content_language"] == "en" async def test_translation_is_cleaned_and_kept( mail_ctx: MailCtx, fake_service: dict[str, object] ) -> None: msg = await mail_ctx.deliver(raw_mail("Project", html=f"{TEXT}
"), 1) for _ in range(2): resp = await mail_ctx.client.get(f"/api/messages/{msg.id}/html", params={"translate": "pl"}) assert resp.status_code == 200 assert "Cześć Łukasz" in resp.text and "alert(1)" not in resp.text assert resp.headers["X-Translated-From"] == "en" assert resp.headers["X-Translated-To"] == "pl" assert fake_service["translate"] == 1 # the second came from the cache # The people on the message are names to keep if the model would change them. assert "News" in fake_service["names"] # type: ignore[operator] async def test_service_trouble_is_a_clear_error( mail_ctx: MailCtx, monkeypatch: pytest.MonkeyPatch, fake_service: dict[str, object] ) -> None: async def broken( html: str, source: str, target: str, keep: object = (), names: object = () ) -> str: raise translation.TranslationError("the translation service is unreachable") monkeypatch.setattr(translation, "translate_html", broken) msg = await mail_ctx.deliver(raw_mail("Project", html=f"{TEXT}
"), 1) resp = await mail_ctx.client.get(f"/api/messages/{msg.id}/html", params={"translate": "pl"}) assert resp.status_code == 503 assert resp.json()["error"]["code"] == "translation_failed" # The message itself still shows. assert (await mail_ctx.client.get(f"/api/messages/{msg.id}/html")).status_code == 200 async def test_off_without_a_service(mail_ctx: MailCtx, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setattr(translation, "enabled", lambda: False) msg = await mail_ctx.deliver(raw_mail("Project", html=f"{TEXT}
"), 1) resp = await mail_ctx.client.get(f"/api/messages/{msg.id}/html") assert "X-Content-Language" not in resp.headers info = (await mail_ctx.client.get("/api/translation/languages")).json() assert info == {"available": False, "languages": []}