Skip to content

Commit

Permalink
Almost everything is now covered by unittests except for all parts wh…
Browse files Browse the repository at this point in the history
…ich really count
  • Loading branch information
matthiask committed Jul 4, 2024
1 parent b1d38a4 commit 80fb3cd
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 35 deletions.
43 changes: 42 additions & 1 deletion projects/test_views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from unittest.mock import Mock, patch

from authlib.little_auth.models import User
from django.test import Client, TestCase
from django.test.utils import override_settings

from projects.models import Project
from projects.models import Catalog, Project
from projects.translators import TranslationError


class ProjectsTest(TestCase):
Expand Down Expand Up @@ -75,6 +78,11 @@ def test_smoke(self):
)
self.assertEqual(r.content.decode("utf-8"), c.pofile)

r = su_client.post(
"/api/pofile/fr/djangojs/", headers={"x-project-token": p.token}
)
self.assertEqual(r.status_code, 405)

r = su_client.get(
"/api/pofile/de/djangojs/", headers={"x-project-token": p.token}
)
Expand Down Expand Up @@ -160,3 +168,36 @@ def test_smoke(self):

self.assertContains(r, '<td class="field-explicit_users">-</td>')
self.assertContains(r, '<td class="field-explicit_users">use***@***.com</td>')

def test_suggest(self):
c = Client()

r = c.get("/suggest/")
self.assertEqual(r.status_code, 405)

r = c.post("/suggest/")
self.assertEqual(r.status_code, 403)

user = User.objects.create_user("user@example.com", "user")
c.force_login(user)

r = c.post("/suggest/")
self.assertEqual(r.status_code, 400)

with patch(
"projects.views.translators.translate_by_deepl", lambda *a: "Bonjour"
):
r = c.post("/suggest/", {"language_code": "fr", "msgid": "Anything"})
self.assertEqual(r.status_code, 200)
self.assertEqual(r.json(), {"msgstr": "Bonjour"})

mock = Mock()
mock.side_effect = TranslationError("Oops")
with patch("projects.views.translators.translate_by_deepl", mock):
r = c.post("/suggest/", {"language_code": "fr", "msgid": "Anything"})
self.assertEqual(r.status_code, 200)
self.assertEqual(r.json(), {"error": "Oops"})

def test_invalid_catalog(self):
c = Catalog(language_code="it", domain="django", pofile="blub")
self.assertEqual(str(c), "Italian, django (Invalid)")
33 changes: 33 additions & 0 deletions projects/translators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import requests


class TranslationError(Exception):
pass


def translate_by_deepl(text, to_language, auth_key):
# Copied 1:1 from django-rosetta, thanks!
if auth_key.lower().endswith(":fx"):
endpoint = "https://api-free.deepl.com"
else:
endpoint = "https://api.deepl.com"

r = requests.post(
f"{endpoint}/v2/translate",
headers={"Authorization": f"DeepL-Auth-Key {auth_key}"},
data={
"target_lang": to_language.upper(),
"text": text,
},
timeout=5,
)
if r.status_code != 200:
raise TranslationError(
f"Deepl response is {r.status_code}. Please check your API key or try again later."
)
try:
return r.json().get("translations")[0].get("text")
except Exception as exc:
raise TranslationError(
"Deepl returned a non-JSON or unexpected response."
) from exc
39 changes: 5 additions & 34 deletions projects/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import polib
import requests
from django import forms, http
from django.conf import settings
from django.contrib.auth.decorators import login_required
Expand All @@ -9,8 +8,10 @@
from django.utils.timezone import localtime
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST

from form_rendering import adapt_rendering
from projects import translators
from projects.models import Catalog, Project


Expand Down Expand Up @@ -235,42 +236,12 @@ def catalog(request, project, language_code, domain):
)


class TranslationError(Exception):
pass


def translate_by_deepl(text, to_language, auth_key):
if auth_key.lower().endswith(":fx"):
endpoint = "https://api-free.deepl.com"
else:
endpoint = "https://api.deepl.com"

r = requests.post(
f"{endpoint}/v2/translate",
headers={"Authorization": f"DeepL-Auth-Key {auth_key}"},
data={
"target_lang": to_language.upper(),
"text": text,
},
timeout=5,
)
if r.status_code != 200:
raise TranslationError(
f"Deepl response is {r.status_code}. Please check your API key or try again later."
)
try:
return r.json().get("translations")[0].get("text")
except Exception as exc:
raise TranslationError(
"Deepl returned a non-JSON or unexpected response."
) from exc


class SuggestForm(forms.Form):
language_code = forms.CharField()
msgid = forms.CharField()


@require_POST
def suggest(request):
if not request.user.is_authenticated:
return http.HttpResponseForbidden()
Expand All @@ -279,10 +250,10 @@ def suggest(request):
if form.is_valid():
data = form.cleaned_data
try:
translation = translate_by_deepl(
translation = translators.translate_by_deepl(
data["msgid"], data["language_code"], settings.DEEPL_AUTH_KEY
)
except TranslationError as exc:
except translators.TranslationError as exc:
return http.JsonResponse({"error": str(exc)})
return http.JsonResponse({"msgstr": translation})

Expand Down

0 comments on commit 80fb3cd

Please sign in to comment.