Merge pull request #1472 from vinyll/mkt_review_translations-944107
added review translation for reviewers (bug 944107)
This commit is contained in:
Коммит
49bd36db0a
|
@ -21,6 +21,7 @@ def addon_view(f, qs=Addon.objects.all):
|
|||
if addon_id and addon_id.isdigit():
|
||||
addon = get(id=addon_id)
|
||||
# Don't get in an infinite loop if addon.slug.isdigit().
|
||||
# Magically replace addon.id by its slug directly in the url.
|
||||
if addon.slug != addon_id:
|
||||
url = request.path.replace(addon_id, addon.slug)
|
||||
if request.GET:
|
||||
|
|
|
@ -24,20 +24,18 @@ class TestAddonView(amo.tests.TestCase):
|
|||
self.request.GET = {}
|
||||
|
||||
def test_301_by_id(self):
|
||||
r = self.view(self.request, str(self.addon.id))
|
||||
eq_(r.status_code, 301)
|
||||
eq_(r['Location'], self.slug_path)
|
||||
res = self.view(self.request, str(self.addon.id))
|
||||
self.assert3xx(res, self.slug_path, 301)
|
||||
|
||||
def test_301_with_querystring(self):
|
||||
self.request.GET = mock.Mock()
|
||||
self.request.GET.urlencode.return_value = 'q=1'
|
||||
r = self.view(self.request, str(self.addon.id))
|
||||
eq_(r.status_code, 301)
|
||||
eq_(r['Location'], self.slug_path + '?q=1')
|
||||
res = self.view(self.request, str(self.addon.id))
|
||||
self.assert3xx(res, self.slug_path + '?q=1', 301)
|
||||
|
||||
def test_200_by_slug(self):
|
||||
r = self.view(self.request, self.addon.slug)
|
||||
eq_(r, mock.sentinel.OK)
|
||||
res = self.view(self.request, self.addon.slug)
|
||||
eq_(res, mock.sentinel.OK)
|
||||
|
||||
def test_404_by_id(self):
|
||||
with self.assertRaises(http.Http404):
|
||||
|
@ -50,15 +48,14 @@ class TestAddonView(amo.tests.TestCase):
|
|||
def test_alternate_qs_301_by_id(self):
|
||||
qs = lambda: Addon.objects.filter(type=1)
|
||||
view = dec.addon_view_factory(qs=qs)(self.func)
|
||||
r = view(self.request, str(self.addon.id))
|
||||
eq_(r.status_code, 301)
|
||||
eq_(r['Location'], self.slug_path)
|
||||
res = view(self.request, str(self.addon.id))
|
||||
self.assert3xx(res, self.slug_path, 301)
|
||||
|
||||
def test_alternate_qs_200_by_slug(self):
|
||||
qs = lambda: Addon.objects.filter(type=1)
|
||||
view = dec.addon_view_factory(qs=qs)(self.func)
|
||||
r = view(self.request, self.addon.slug)
|
||||
eq_(r, mock.sentinel.OK)
|
||||
res = view(self.request, self.addon.slug)
|
||||
eq_(res, mock.sentinel.OK)
|
||||
|
||||
def test_alternate_qs_404_by_id(self):
|
||||
qs = lambda: Addon.objects.filter(type=2)
|
||||
|
@ -73,23 +70,23 @@ class TestAddonView(amo.tests.TestCase):
|
|||
view(self.request, self.addon.slug)
|
||||
|
||||
def test_addon_no_slug(self):
|
||||
a = Addon.objects.create(type=1, name='xxxx')
|
||||
r = self.view(self.request, a.slug)
|
||||
eq_(r, mock.sentinel.OK)
|
||||
app = Addon.objects.create(type=1, name='xxxx')
|
||||
res = self.view(self.request, app.slug)
|
||||
eq_(res, mock.sentinel.OK)
|
||||
|
||||
def test_slug_isdigit(self):
|
||||
a = Addon.objects.create(type=1, name='xxxx')
|
||||
a.update(slug=str(a.id))
|
||||
r = self.view(self.request, a.slug)
|
||||
app = Addon.objects.create(type=1, name='xxxx')
|
||||
app.update(slug=str(app.id))
|
||||
r = self.view(self.request, app.slug)
|
||||
eq_(r, mock.sentinel.OK)
|
||||
request, addon = self.func.call_args[0]
|
||||
eq_(addon, a)
|
||||
eq_(addon, app)
|
||||
|
||||
def test_app(self):
|
||||
a = Addon.objects.create(type=amo.ADDON_WEBAPP, name='xxxx')
|
||||
a.update(slug=str(a.id) + 'foo', app_slug=str(a.id))
|
||||
r = self.view(self.request, app_slug=str(a.id))
|
||||
eq_(r, mock.sentinel.OK)
|
||||
app = amo.tests.app_factory(name='xxxx')
|
||||
app.update(slug=str(app.id) + 'foo', app_slug=str(app.id))
|
||||
res = self.view(self.request, app_slug=str(app.id))
|
||||
eq_(res, mock.sentinel.OK)
|
||||
eq_(self.func.call_args[0][1].type, amo.ADDON_WEBAPP)
|
||||
|
||||
|
||||
|
|
|
@ -104,14 +104,11 @@ def _retrieve_translation(text, language):
|
|||
return translated, r
|
||||
|
||||
|
||||
@addon_view
|
||||
@waffle_switch('reviews-translate')
|
||||
def translate(request, addon, review_id, language):
|
||||
def translate_review(request, review, language):
|
||||
"""
|
||||
Use the Google Translate API for ajax, redirect to Google Translate for
|
||||
non ajax calls.
|
||||
Shared view splitted from the translate() views below for reusability
|
||||
purposes (This is shared with mkt.reviewers).
|
||||
"""
|
||||
review = get_object_or_404(Review.objects, pk=review_id, addon=addon)
|
||||
if '-' in language:
|
||||
language = language.split('-')[0]
|
||||
|
||||
|
@ -125,6 +122,17 @@ def translate(request, addon, review_id, language):
|
|||
lang=language, text=review.body))
|
||||
|
||||
|
||||
@addon_view
|
||||
@waffle_switch('reviews-translate')
|
||||
def translate(request, addon, review_id, language):
|
||||
"""
|
||||
Use the Google Translate API for ajax, redirect to Google Translate for
|
||||
non ajax calls.
|
||||
"""
|
||||
review = get_object_or_404(Review, pk=review_id, addon=addon)
|
||||
return translate_review(request, review, language)
|
||||
|
||||
|
||||
@addon_view
|
||||
@post_required
|
||||
@login_required(redirect=False)
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
INSERT INTO waffle_switch_mkt (name, active, note, created, modified)
|
||||
VALUES ('reviews-translate', 0,
|
||||
'This adds a "translate" button for addons reviews and enables '
|
||||
'reviews translations on click.', NOW(), NOW());
|
|
@ -28,6 +28,12 @@
|
|||
by {{ user }} on {{ date }}
|
||||
{{ stars }} ({{ locale }})
|
||||
{% endtrans %}
|
||||
{% if waffle.switch('reviews-translate') %}
|
||||
- <a class="translate" rel="nofollow" target="_blank"
|
||||
href="{{ url('reviewers.review_translate', review.instance.addon.slug, review.instance.id, LANG) }}">
|
||||
{{ _('translate') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
|
|
|
@ -25,7 +25,7 @@ import amo.tests
|
|||
import reviews
|
||||
from abuse.models import AbuseReport
|
||||
from access.models import Group, GroupUser
|
||||
from addons.models import AddonDeviceType
|
||||
from addons.models import Addon, AddonDeviceType
|
||||
from amo.helpers import absolutify
|
||||
from amo.tests import (app_factory, check_links, days_ago, formset, initial,
|
||||
req_factory_factory, version_factory)
|
||||
|
@ -2964,3 +2964,43 @@ class TestReviewPage(amo.tests.TestCase):
|
|||
res = app_review(req, app_slug=self.app.app_slug)
|
||||
doc = pq(res.content)
|
||||
eq_(doc('.content-rating').length, 2)
|
||||
|
||||
|
||||
class TestReviewTranslate(AppReviewerTest):
|
||||
|
||||
def setUp(self):
|
||||
self.login_as_editor()
|
||||
self.create_switch('reviews-translate')
|
||||
user = UserProfile.objects.create(username='diego')
|
||||
app = amo.tests.app_factory(slug='myapp')
|
||||
self.review = app.reviews.create(title=u'yes', body=u'oui',
|
||||
addon=app, user=user,
|
||||
editorreview=True, rating=4)
|
||||
|
||||
def test_regular_call(self):
|
||||
res = self.client.get(reverse('reviewers.review_translate',
|
||||
args=[self.review.addon.slug,
|
||||
self.review.id, 'fr']))
|
||||
self.assert3xx(res, 'https://translate.google.com/#auto/fr/oui', 302)
|
||||
|
||||
@mock.patch('reviews.views.requests')
|
||||
def test_ajax_call(self, requests):
|
||||
# Mock requests.
|
||||
response = mock.Mock(status_code=200)
|
||||
response.json.return_value = {
|
||||
u'data': {
|
||||
u'translations': [{
|
||||
u'translatedText': u'oui',
|
||||
u'detectedSourceLanguage': u'fr'
|
||||
}]
|
||||
}
|
||||
}
|
||||
requests.get.return_value = response
|
||||
|
||||
# Call translation.
|
||||
review = self.review
|
||||
res = self.client.get_ajax(reverse('reviewers.review_translate',
|
||||
args=[review.addon.slug, review.id,
|
||||
'fr']),)
|
||||
eq_(res.status_code, 200)
|
||||
eq_(res.content, '{"body": "oui", "title": "oui"}')
|
||||
|
|
|
@ -89,4 +89,8 @@ api_patterns = patterns('',
|
|||
api.ApproveRegion.as_view(), name='approve-region'),
|
||||
url(r'^reviewers/reviewing', api.ReviewingView.as_view(),
|
||||
name='reviewing-list'),
|
||||
url('^reviewers/(?P<addon_slug>[\w-]+)/review/(?P<review_pk>\d+)/translate'
|
||||
'/(?P<language>[a-z]{2}(-[A-Z]{2})?)$',
|
||||
views.review_translate,
|
||||
name='reviewers.review_translate'),
|
||||
)
|
||||
|
|
|
@ -17,6 +17,7 @@ import commonware.log
|
|||
import jingo
|
||||
import requests
|
||||
from tower import ugettext as _
|
||||
from waffle.decorators import waffle_switch
|
||||
|
||||
import amo
|
||||
from abuse.models import AbuseReport
|
||||
|
@ -39,6 +40,7 @@ from files.models import File
|
|||
from lib.crypto.packaged import SigningError
|
||||
from reviews.forms import ReviewFlagFormSet
|
||||
from reviews.models import Review, ReviewFlag
|
||||
from reviews.views import translate_review
|
||||
from translations.query import order_by_translation
|
||||
from users.models import UserProfile
|
||||
from zadmin.models import set_config, unmemoized_get_config
|
||||
|
@ -916,3 +918,10 @@ def attachment(request, attachment):
|
|||
response['Content-Disposition'] = 'attachment; filename=%s' % filename
|
||||
response['Content-Length'] = os.path.getsize(full_path)
|
||||
return response
|
||||
|
||||
|
||||
@waffle_switch('reviews-translate')
|
||||
@permission_required('Apps', 'Review')
|
||||
def review_translate(request, addon_slug, review_pk, language):
|
||||
review = get_object_or_404(Review, addon__slug=addon_slug, pk=review_pk)
|
||||
return translate_review(request, review, language)
|
||||
|
|
Загрузка…
Ссылка в новой задаче