def setUp(self): super(TestMobileReviews, self).setUp() self.addon = Addon.objects.get(id=1865) self.user = UserProfile.objects.get(email='*****@*****.**') self.login_regular() self.add = helpers.url('addons.reviews.add', self.addon.slug) self.list = helpers.url('addons.reviews.list', self.addon.slug)
def send_notification_email(self): if self.reply_to: # It's a reply. reply_url = helpers.url('addons.reviews.detail', self.addon.slug, self.reply_to.pk, add_prefix=False) data = { 'name': self.addon.name, 'reply_title': self.title, 'reply': self.body, 'reply_url': helpers.absolutify(reply_url) } recipients = [self.reply_to.user.email] subject = u'Mozilla Add-on Developer Reply: %s' % self.addon.name template = 'reviews/emails/reply_review.ltxt' perm_setting = 'reply' else: # It's a new review. reply_url = helpers.url('addons.reviews.reply', self.addon.slug, self.pk, add_prefix=False) data = { 'name': self.addon.name, 'rating': '%s out of 5 stars' % self.rating, 'review': self.body, 'reply_url': helpers.absolutify(reply_url) } recipients = [author.email for author in self.addon.authors.all()] subject = u'Mozilla Add-on User Review: %s' % self.addon.name template = 'reviews/emails/add_review.ltxt' perm_setting = 'new_review' send_mail_jinja( subject, template, Context(data), recipient_list=recipients, perm_setting=perm_setting)
def add(request, addon, template=None): if addon.has_author(request.user): raise PermissionDenied form = forms.ReviewForm(request.POST or None) if (request.method == 'POST' and form.is_valid() and not request.POST.get('detailed')): details = _review_details(request, addon, form) review = Review.objects.create(**details) if 'flag' in form.cleaned_data and form.cleaned_data['flag']: rf = ReviewFlag(review=review, user_id=request.user.id, flag=ReviewFlag.OTHER, note='URLs') rf.save() amo.log(amo.LOG.ADD_REVIEW, addon, review) log.debug('New review: %s' % review.id) reply_url = helpers.url('addons.reviews.reply', addon.slug, review.id, add_prefix=False) data = {'name': addon.name, 'rating': '%s out of 5 stars' % details['rating'], 'review': details['body'], 'reply_url': helpers.absolutify(reply_url)} emails = [a.email for a in addon.authors.all()] send_mail('reviews/emails/add_review.ltxt', u'Mozilla Add-on User Review: %s' % addon.name, emails, Context(data), 'new_review') return redirect(helpers.url('addons.reviews.list', addon.slug)) return render(request, template, dict(addon=addon, form=form))
def reply(request, addon, review_id): is_admin = acl.action_allowed(request, 'Addons', 'Edit') is_author = acl.check_addon_ownership(request, addon, dev=True) if not (is_admin or is_author): raise PermissionDenied review = get_object_or_404(Review.objects, pk=review_id, addon=addon) form = forms.ReviewReplyForm(request.POST or None) if request.method == 'POST' and form.is_valid(): d = dict(reply_to=review, addon=addon, defaults=dict(user=request.user)) reply, new = Review.objects.get_or_create(**d) for key, val in _review_details(request, addon, form).items(): setattr(reply, key, val) reply.save() action = 'New' if new else 'Edited' log.debug('%s reply to %s: %s' % (action, review_id, reply.id)) if new: reply_url = helpers.url('addons.reviews.detail', addon.slug, review.id, add_prefix=False) data = {'name': addon.name, 'reply_title': reply.title, 'reply': reply.body, 'reply_url': helpers.absolutify(reply_url)} emails = [review.user.email] sub = u'Mozilla Add-on Developer Reply: %s' % addon.name send_mail('reviews/emails/reply_review.ltxt', sub, emails, Context(data), 'reply') return redirect(helpers.url('addons.reviews.detail', addon.slug, review_id)) ctx = dict(review=review, form=form, addon=addon) return render(request, 'reviews/reply.html', ctx)
def test_edit_review_form(self): r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) self.assertTemplateUsed(r, 'reviews/edit_review.html') r = self.client.get( helpers.url('addons.reviews.detail', self.addon.slug, 218468)) self.assertTemplateUsed(r, 'reviews/edit_review.html')
def link(self, category): """Link for the feed as a whole""" if self.category: base = url('browse.search-tools.rss', self.category.slug) else: base = url('browse.search-tools.rss') return absolutify(base + '?sort=' + self.sort)
def send_notification_email(self): if self.reply_to: # It's a reply. reply_url = helpers.url("addons.reviews.detail", self.addon.slug, self.reply_to.pk, add_prefix=False) data = { "name": self.addon.name, "reply_title": self.title, "reply": self.body, "reply_url": helpers.absolutify(reply_url), } recipients = [self.reply_to.user.email] subject = u"Mozilla Add-on Developer Reply: %s" % self.addon.name template = "reviews/emails/reply_review.ltxt" perm_setting = "reply" else: # It's a new review. reply_url = helpers.url("addons.reviews.reply", self.addon.slug, self.pk, add_prefix=False) data = { "name": self.addon.name, "rating": "%s out of 5 stars" % self.rating, "review": self.body, "reply_url": helpers.absolutify(reply_url), } recipients = [author.email for author in self.addon.authors.all()] subject = u"Mozilla Add-on User Review: %s" % self.addon.name template = "reviews/emails/add_review.ltxt" perm_setting = "new_review" send_mail_jinja(subject, template, Context(data), recipient_list=recipients, perm_setting=perm_setting)
def test_edit_review_form(self): r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) self.assertTemplateUsed(r, 'reviews/edit_review.html') r = self.client.get(helpers.url('addons.reviews.detail', self.addon.slug, 218468)) self.assertTemplateUsed(r, 'reviews/edit_review.html')
def setUp(self): super(TestCreate, self).setUp() self.add = helpers.url('addons.reviews.add', self.addon.slug) self.client.login(username='******', password='******') self.user = UserProfile.objects.get(email='*****@*****.**') self.qs = Review.objects.filter(addon=1865) self.log_count = ActivityLog.objects.count self.more = self.addon.get_url_path(more=True) self.list = helpers.url('addons.reviews.list', self.addon.slug)
def test_edit(self): url = helpers.url('addons.reviews.edit', self.addon.slug, 218207) response = self.client.post(url, {'rating': 2, 'body': 'woo woo'}, X_REQUESTED_WITH='XMLHttpRequest') assert response.status_code == 200 assert response['Content-type'] == 'application/json' assert '%s' % Review.objects.get(id=218207).body == 'woo woo' response = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) doc = pq(response.content) assert doc('#review-218207 .review-edit').text() == 'Edit review'
def test_edit_reply(self): self.login_dev() url = helpers.url('addons.reviews.edit', self.addon.slug, 218468) response = self.client.post(url, {'title': 'fo', 'body': 'shizzle'}, X_REQUESTED_WITH='XMLHttpRequest') assert response.status_code == 200 reply = Review.objects.get(id=218468) assert '%s' % reply.title == 'fo' assert '%s' % reply.body == 'shizzle' response = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) doc = pq(response.content) assert doc('#review-218468 .review-reply-edit').text() == 'Edit reply'
def test_invalid_api_key(self, requests): # Mock requests. response = mock.Mock() response.status_code = 400 response.json.return_value = { 'error': { 'code': 400, 'errors': [{ 'domain': 'usageLimits', 'message': 'Bad Request', 'reason': 'keyInvalid' }], 'message': 'Bad Request' } } requests.get.return_value = response # Call translation. review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') assert r.status_code == 400
def test_regular_call(self): review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url) assert r.status_code == 302 assert r.get('Location') == 'https://translate.google.com/#auto/fr/yes'
def test_creation_triggers_email_and_logging(self): addon = Addon.objects.get(pk=4) addon_author = user_factory() addon.addonuser_set.create(user=addon_author) review_user = user_factory() review = Review.objects.create( user=review_user, addon=addon, body=u'Rêviiiiiiew', user_responsible=review_user) activity_log = ActivityLog.objects.latest('pk') assert activity_log.user == review_user assert activity_log.arguments == [addon, review] assert activity_log.action == amo.LOG.ADD_REVIEW.id assert len(mail.outbox) == 1 email = mail.outbox[0] reply_url = helpers.absolutify( helpers.url('addons.reviews.reply', addon.slug, review.pk, add_prefix=False)) assert email.subject == 'Mozilla Add-on User Review: my addon name' assert 'A user has left a review for your add-on,' in email.body assert 'my addon name' in email.body assert reply_url in email.body assert email.to == [addon_author.email] assert email.from_email == 'Mozilla Add-ons <*****@*****.**>'
def test_creation_triggers_email_and_logging(self): addon = Addon.objects.get(pk=4) addon_author = user_factory() addon.addonuser_set.create(user=addon_author) review_user = user_factory() review = Review.objects.create(user=review_user, addon=addon, body=u'Rêviiiiiiew', user_responsible=review_user) activity_log = ActivityLog.objects.latest('pk') assert activity_log.user == review_user assert activity_log.arguments == [addon, review] assert activity_log.action == amo.LOG.ADD_REVIEW.id assert len(mail.outbox) == 1 email = mail.outbox[0] reply_url = helpers.absolutify( helpers.url('addons.reviews.reply', addon.slug, review.pk, add_prefix=False)) assert email.subject == 'Mozilla Add-on User Review: my addon name' assert 'A user has left a review for your add-on,' in email.body assert 'my addon name' in email.body assert reply_url in email.body assert email.to == [addon_author.email] assert email.from_email == 'Mozilla Add-ons <*****@*****.**>'
def test_list(self): r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) assert r.status_code == 200 doc = pq(r.content) reviews = doc('#reviews .item') assert reviews.length == Review.objects.count() assert Review.objects.count() == 2 assert doc('.secondary .average-rating').length == 1 assert doc('.secondary .no-rating').length == 0 r = Review.objects.get(id=218207) item = reviews.filter('#review-218207') assert r.reply_to_id is None assert not item.hasClass('reply') assert item.length == 1 assert item.attr('data-rating') == str(r.rating) r = Review.objects.get(id=218468) item = reviews.filter('#review-218468') assert item.length == 1 assert r.reply_to_id == 218207 assert item.hasClass('reply') assert r.rating is None assert item.attr('data-rating') == ''
def test_list(self): r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) eq_(r.status_code, 200) doc = pq(r.content) reviews = doc('#reviews .item') eq_(reviews.length, Review.objects.count()) eq_(Review.objects.count(), 2) eq_(doc('.secondary .average-rating').length, 1) eq_(doc('.secondary .no-rating').length, 0) r = Review.objects.get(id=218207) item = reviews.filter('#review-218207') eq_(r.reply_to_id, None) eq_(item.hasClass('reply'), False) eq_(item.length, 1) eq_(item.attr('data-rating'), str(r.rating)) r = Review.objects.get(id=218468) item = reviews.filter('#review-218468') eq_(item.length, 1) eq_(r.reply_to_id, 218207) eq_(item.hasClass('reply'), True) eq_(r.rating, None) eq_(item.attr('data-rating'), '')
def test_edit_not_owner(self): url = helpers.url('addons.reviews.edit', self.addon.slug, 218468) r = self.client.post(url, { 'rating': 2, 'body': 'woo woo' }, X_REQUESTED_WITH='XMLHttpRequest') assert r.status_code == 403
def test_unicode_call(self): review = Review.objects.create(addon=self.addon, user=self.user, title='or', body=u'héhé 3%') url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url) assert r.status_code == 302 assert r.get('Location') == ( 'https://translate.google.com/#auto/fr/h%C3%A9h%C3%A9%203%25')
def test_delete_own_review(self): self.client.logout() self.login_dev() url = helpers.url('addons.reviews.delete', self.addon.slug, 218468) cnt = Review.objects.count() response = self.client.post(url) assert response.status_code == 200 assert Review.objects.count() == cnt - 1 assert not Review.objects.filter(pk=218468).exists()
def test_delete_own_review(self): self.client.logout() self.login_dev() url = helpers.url('addons.reviews.delete', self.addon.slug, 218468) cnt = Review.objects.count() response = self.client.post(url) eq_(response.status_code, 200) eq_(Review.objects.count(), cnt - 1) eq_(Review.objects.filter(pk=218468).exists(), False)
def test_unicode_call(self): review = Review.objects.create(addon=self.addon, user=self.user, title='or', body=u'héhé 3%') url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url) eq_(r.status_code, 302) eq_(r.get('Location'), 'https://translate.google.com/#auto/fr/h%C3%A9h%C3%A9%203%25')
def test_supports_dsb_hsb(self): # Make sure 3 character long locale codes resolve properly. for code in ('dsb', 'hsb'): review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, code) r = self.client.get(url) assert r.status_code == 302 expected = 'https://translate.google.com/#auto/{}/yes'.format(code) assert r.get('Location') == expected
def test_add_link_dev(self): """Ensure developer cannot see Add Review links.""" self.login_dev() r = self.client.get_ajax(self.more) assert pq(r.content)('#add-review').length == 0 r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) doc = pq(r.content) assert doc('#add-review').length == 0 assert doc('#add-first-review').length == 0
def test_empty_list(self): Review.objects.all().delete() assert Review.objects.count() == 0 r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) assert r.status_code == 200 doc = pq(r.content) assert doc('#reviews .item').length == 0 assert doc('#add-first-review').length == 1 assert doc('.secondary .average-rating').length == 0 assert doc('.secondary .no-rating').length == 1
def test_empty_list(self): Review.objects.all().delete() eq_(Review.objects.count(), 0) r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) eq_(r.status_code, 200) doc = pq(r.content) eq_(doc('#reviews .item').length, 0) eq_(doc('#add-first-review').length, 1) eq_(doc('.secondary .average-rating').length, 0) eq_(doc('.secondary .no-rating').length, 1)
def test_add_link_visitor(self): """ Ensure non-logged user can see Add Review links on details page but not on Reviews listing page. """ self.client.logout() r = self.client.get_ajax(self.more) assert pq(r.content)('#add-review').length == 1 r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) doc = pq(r.content) assert doc('#add-review').length == 0 assert doc('#add-first-review').length == 0
def reply(request, addon, review_id): is_admin = acl.action_allowed(request, 'Addons', 'Edit') is_author = acl.check_addon_ownership(request, addon, dev=True) if not (is_admin or is_author): raise PermissionDenied review = get_object_or_404(Review.objects, pk=review_id, addon=addon) form = forms.ReviewReplyForm(request.POST or None) if request.method == 'POST' and form.is_valid(): d = dict(reply_to=review, addon=addon, defaults=dict(user=request.user)) reply, new = Review.objects.get_or_create(**d) for key, val in _review_details(request, addon, form).items(): setattr(reply, key, val) reply.save() action = 'New' if new else 'Edited' log.debug('%s reply to %s: %s' % (action, review_id, reply.id)) if new: reply_url = helpers.url('addons.reviews.detail', addon.slug, review.id, add_prefix=False) data = { 'name': addon.name, 'reply_title': reply.title, 'reply': reply.body, 'reply_url': helpers.absolutify(reply_url) } emails = [review.user.email] sub = u'Mozilla Add-on Developer Reply: %s' % addon.name send_mail('reviews/emails/reply_review.ltxt', sub, emails, Context(data), 'reply') return redirect( helpers.url('addons.reviews.detail', addon.slug, review_id)) ctx = dict(review=review, form=form, addon=addon) return render(request, 'reviews/reply.html', ctx)
def test_invalid_api_key(self, requests): # Mock requests. response = mock.Mock() response.status_code = 400 response.json.return_value = {'error': {'code': 400, 'errors': [{ 'domain': 'usageLimits', 'message': 'Bad Request', 'reason': 'keyInvalid'}], 'message': 'Bad Request'}} requests.get.return_value = response # Call translation. review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') assert r.status_code == 400
def add(request, addon, template=None): if addon.has_author(request.user): raise PermissionDenied form = forms.ReviewForm(request.POST or None) if (request.method == 'POST' and form.is_valid() and not request.POST.get('detailed')): details = _review_details(request, addon, form) review = Review.objects.create(**details) if 'flag' in form.cleaned_data and form.cleaned_data['flag']: rf = ReviewFlag(review=review, user_id=request.user.id, flag=ReviewFlag.OTHER, note='URLs') rf.save() amo.log(amo.LOG.ADD_REVIEW, addon, review) log.debug('New review: %s' % review.id) reply_url = helpers.url('addons.reviews.reply', addon.slug, review.id, add_prefix=False) data = { 'name': addon.name, 'rating': '%s out of 5 stars' % details['rating'], 'review': details['body'], 'reply_url': helpers.absolutify(reply_url) } emails = [a.email for a in addon.authors.all()] send_mail('reviews/emails/add_review.ltxt', u'Mozilla Add-on User Review: %s' % addon.name, emails, Context(data), 'new_review') return redirect(helpers.url('addons.reviews.list', addon.slug)) return render(request, template, dict(addon=addon, form=form))
def add(request, addon, template=None): if addon.has_author(request.user): raise PermissionDenied form = forms.ReviewForm(request.POST or None) if (request.method == 'POST' and form.is_valid() and not request.POST.get('detailed')): details = _review_details(request, addon, form) review = Review.objects.create(**details) if 'flag' in form.cleaned_data and form.cleaned_data['flag']: rf = ReviewFlag(review=review, user_id=request.user.id, flag=ReviewFlag.OTHER, note='URLs') rf.save() return redirect(helpers.url('addons.reviews.list', addon.slug)) return render(request, template, dict(addon=addon, form=form))
def test_ajax_call(self, requests): # Mock requests. response = mock.Mock() response.status_code = 200 response.json.return_value = {u'data': {u'translations': [{ u'translatedText': u'oui', u'detectedSourceLanguage': u'en' }]}} requests.get.return_value = response # Call translation. review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') eq_(r.status_code, 200) eq_(json.loads(r.content), {"body": "oui", "title": "oui"})
def test_ajax_call(self, requests): # Mock requests. response = mock.Mock() response.status_code = 200 response.json.return_value = {u'data': {u'translations': [{ u'translatedText': u'oui', u'detectedSourceLanguage': u'en' }]}} requests.get.return_value = response # Call translation. review = self.review url = helpers.url('addons.reviews.translate', review.addon.slug, review.id, 'fr') r = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') assert r.status_code == 200 assert json.loads(r.content) == {"body": "oui", "title": "oui"}
def reply(request, addon, review_id): is_admin = acl.action_allowed(request, 'Addons', 'Edit') is_author = acl.check_addon_ownership(request, addon, dev=True) if not (is_admin or is_author): raise PermissionDenied review = get_object_or_404(Review.objects, pk=review_id, addon=addon) form = forms.ReviewReplyForm(request.POST or None) if request.method == 'POST' and form.is_valid(): kwargs = { 'reply_to': review, 'addon': addon, 'defaults': _review_details(request, addon, form) } reply, created = Review.unfiltered.update_or_create(**kwargs) return redirect( helpers.url('addons.reviews.detail', addon.slug, review_id)) ctx = {'review': review, 'form': form, 'addon': addon} return render(request, 'reviews/reply.html', ctx)
def reply(request, addon, review_id): is_admin = acl.action_allowed(request, 'Addons', 'Edit') is_author = acl.check_addon_ownership(request, addon, dev=True) if not (is_admin or is_author): raise PermissionDenied review = get_object_or_404(Review.objects, pk=review_id, addon=addon) form = forms.ReviewReplyForm(request.POST or None) if request.method == 'POST' and form.is_valid(): kwargs = { 'reply_to': review, 'addon': addon, 'defaults': _review_details(request, addon, form) } reply, created = Review.unfiltered.update_or_create(**kwargs) return redirect(helpers.url('addons.reviews.detail', addon.slug, review_id)) ctx = dict(review=review, form=form, addon=addon) return render(request, 'reviews/reply.html', ctx)
def test_reply_triggers_email_but_no_logging(self): review = Review.objects.get(id=1) user = user_factory() Review.objects.create( reply_to=review, user=user, addon=review.addon, body=u'Rêply', user_responsible=user) assert not ActivityLog.objects.exists() assert len(mail.outbox) == 1 email = mail.outbox[0] reply_url = helpers.absolutify( helpers.url('addons.reviews.detail', review.addon.slug, review.pk, add_prefix=False)) assert email.subject == 'Mozilla Add-on Developer Reply: my addon name' assert 'A developer has replied to your review' in email.body assert 'add-on my addon name' in email.body assert reply_url in email.body assert email.to == ['*****@*****.**'] assert email.from_email == 'Mozilla Add-ons <*****@*****.**>'
def test_list_item_actions(self): self.login_admin() self.make_it_my_review() r = self.client.get(helpers.url('addons.reviews.list', self.addon.slug)) reviews = pq(r.content)('#reviews .item') r = Review.objects.get(id=218207) item = reviews.filter('#review-218207') actions = item.find('.item-actions') assert actions.length == 1 classes = sorted(c.get('class') for c in actions.find('li a')) assert classes == ['delete-review', 'flag-review'] r = Review.objects.get(id=218468) item = reviews.filter('#review-218468') actions = item.find('.item-actions') assert actions.length == 1 classes = sorted(c.get('class') for c in actions.find('li a')) assert classes == ['delete-review', 'review-reply-edit']
def test_reply_triggers_email_but_no_logging(self): review = Review.objects.get(id=1) user = user_factory() Review.objects.create(reply_to=review, user=user, addon=review.addon, body=u'Rêply', user_responsible=user) assert not ActivityLog.objects.exists() assert len(mail.outbox) == 1 email = mail.outbox[0] reply_url = helpers.absolutify( helpers.url('addons.reviews.detail', review.addon.slug, review.pk, add_prefix=False)) assert email.subject == 'Mozilla Add-on Developer Reply: my addon name' assert 'A developer has replied to your review' in email.body assert 'add-on my addon name' in email.body assert reply_url in email.body assert email.to == ['*****@*****.**'] assert email.from_email == 'Mozilla Add-ons <*****@*****.**>'
def link(self): return absolutify(url('apps.appversions'))
def test_appversions_feed(self): assert self.client.get(url('apps.appversions.rss')).status_code == 200
def link(self): """Link for the feed as a whole""" return absolutify(url('devhub.feed_all'))