# Part of Odoo. See LICENSE file for full copyright and licensing details. import json import requests from http import HTTPStatus from unittest.mock import patch from odoo.addons.base.tests.common import HttpCaseWithUserDemo from odoo.tests.common import JsonRpcException, new_test_user, tagged from odoo.tools import mute_logger SAMPLE = { "text": "
Al mal tiempo, buena cara.
", "src": "es", "en": "To bad weather, good face.
", "fr": "Au mauvais temps, bonne tĂȘte.
", "nl": "Bij slecht weer, goed gezicht.
", "lang": { "fr": "espagnol", "en": "Spanish", }, } def mock_response(fun): def wrapper(self, url, data=False, params=False, timeout=5): response = requests.Response() response.status_code = HTTPStatus.OK content = {"data": fun(self, url=url, data=data, params=params)} if not content["data"]: response.status_code = HTTPStatus.BAD_REQUEST content = {"error": {"message": "Mocked Error"}} response._content = json.dumps(content).encode() return response return wrapper # Google Cloud Translation Documentation: https://cloud.google.com/translate/docs/reference/api-overview?hl=en @tagged("post_install", "-at_install") class TestTranslationController(HttpCaseWithUserDemo): @classmethod def setUpClass(cls): super().setUpClass() cls.env["res.lang"]._activate_lang("fr_FR") cls.env["res.lang"]._activate_lang("en_US") cls.env.ref("base.user_admin").write({"lang": "fr_FR"}) cls.api_key = "VALIDKEY" cls.env["ir.config_parameter"].set_param("mail.google_translate_api_key", cls.api_key) cls.message = cls.env["mail.message"].create( { "body": SAMPLE["text"], "model": "res.partner", "res_id": cls.env.ref("base.user_admin").partner_id.id, "message_type": "comment", } ) cls.request_count = 0 @mock_response def _patched_post(self, url, data, params, timeout=5): self.request_count += 1 if f"/v2/detect?key={self.api_key}" in url: result = { "language": SAMPLE["src"], "isReliable": True, "confidence": 0.98, } return {"detections": [[result]]} if f"/v2/?key={self.api_key}" in url: return {"translations": [{"translatedText": SAMPLE[data.get("target")]}]} def _mock_translation_request(self, data): with patch.object(requests, "post", self._patched_post): return self.make_jsonrpc_request("/mail/message/translate", data) def test_update_message(self): self.authenticate("admin", "admin") result = self._mock_translation_request({"message_id": self.message.id}) self.assertFalse(result.get("error")) self.assertEqual(self.env["mail.message.translation"].search_count([]), 1) # The translation records should not be discarded if the body did not change. self.make_jsonrpc_request( "/mail/message/update_content", {"message_id": self.message.id, "body": None, "attachment_ids": []} ) self.assertEqual(self.env["mail.message.translation"].search_count([]), 1) self.make_jsonrpc_request( "/mail/message/update_content", {"message_id": self.message.id, "body": "update", "attachment_ids": []} ) self.assertFalse(self.env["mail.message.translation"].search_count([])) def test_translation_multi_users(self): new_test_user(self.env, "user_test_fr", groups="base.group_user", lang="fr_FR") new_test_user(self.env, "user_test_en", groups="base.group_user", lang="en_US") for login, target_lang in [("user_test_fr", "fr"), ("user_test_en", "en"), ("admin", "fr")]: self.authenticate(login, login) result = self._mock_translation_request({"message_id": self.message.id}) self.assertFalse(result.get("error")) self.assertEqual(result["body"], SAMPLE[target_lang]) self.assertEqual(result["lang_name"], SAMPLE["lang"][target_lang]) # There is one translation record per target language. self.assertEqual(self.env["mail.message.translation"].search_count([]), 2) # No API request should be sent if a translation value or source already exists. self.assertEqual(self.request_count, 3) def test_invalid_api_key(self): self.env["ir.config_parameter"].set_param("mail.google_translate_api_key", "INVALIDKEY") self.authenticate("demo", "demo") result = self._mock_translation_request({"message_id": self.message.id}) self.assertNotIn("body", result) self.assertNotIn("lang_name", result) self.assertTrue(result["error"]) def test_html_sanitization(self): self.env["res.lang"]._activate_lang("nl_NL") new_test_user(self.env, "user_test_nl", groups="base.group_user", lang="nl_NL") self.authenticate("user_test_nl", "user_test_nl") result = self._mock_translation_request({"message_id": self.message.id}) self.assertFalse(result.get("error")) self.assertHTMLEqual(result["body"], "Bij slecht weer, goed gezicht.
") translation = self.env["mail.message.translation"].search([]) self.assertEqual(len(translation), 1) self.assertHTMLEqual(translation.body, "Bij slecht weer, goed gezicht.
") def test_access_right(self): with self.assertRaises(JsonRpcException, msg="odoo.http.SessionExpiredException"): self._mock_translation_request({"message_id": self.message.id}) new_test_user(self.env, "user_test_portal", groups="base.group_portal", lang="fr_FR") self.authenticate("user_test_portal", "user_test_portal") with self.assertRaises(JsonRpcException, msg="odoo.exceptions.AccessError"), mute_logger("odoo.http"): self._mock_translation_request({"message_id": self.message.id})