cope nicer with paypal errors (bug 726814)
This commit is contained in:
Родитель
833c48ef4e
Коммит
1c93bd6375
|
@ -0,0 +1,19 @@
|
|||
import jingo
|
||||
import paypal
|
||||
|
||||
|
||||
def handle_paypal_error(fn):
|
||||
"""Wraps the view so that if a paypal error occurs, you show
|
||||
a more menaningful error message. May or may not make sense for
|
||||
all views, so providing as a decorator."""
|
||||
def wrapper(request, *args, **kw):
|
||||
try:
|
||||
return fn(request, *args, **kw)
|
||||
except paypal.PaypalError:
|
||||
# This is specific handling for the submission step.
|
||||
dest = request.GET.get('dest')
|
||||
return jingo.render(request, 'site/500_paypal.html',
|
||||
{'submission': dest == 'submission',
|
||||
'addon': kw.get('addon', None)},
|
||||
status=500)
|
||||
return wrapper
|
|
@ -9,13 +9,17 @@ from django.core import mail
|
|||
|
||||
from mock import patch, Mock
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
from test_utils import RequestFactory
|
||||
|
||||
import amo.tests
|
||||
from amo.urlresolvers import reverse
|
||||
from addons.models import Addon
|
||||
from stats.models import SubscriptionEvent, Contribution
|
||||
from users.models import UserProfile
|
||||
from paypal import views
|
||||
from paypal import views, PaypalError
|
||||
from paypal.decorators import handle_paypal_error
|
||||
|
||||
|
||||
URL_ENCODED = 'application/x-www-form-urlencoded'
|
||||
|
||||
|
@ -344,3 +348,36 @@ class TestEmbeddedPaymentsPaypal(amo.tests.TestCase):
|
|||
def test_email(self, urlopen):
|
||||
self.reversal(urlopen)
|
||||
eq_(len(mail.outbox), 1)
|
||||
|
||||
|
||||
class TestDecorators(amo.tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.func = Mock()
|
||||
self.get_request('/')
|
||||
|
||||
def get_request(self, url):
|
||||
self.request = RequestFactory().get(url)
|
||||
|
||||
@patch('jingo.render')
|
||||
def test_caught(self, render):
|
||||
self.func.side_effect = PaypalError
|
||||
view = handle_paypal_error(self.func)
|
||||
view(self.request)
|
||||
eq_(render.call_args[1]['status'], 500)
|
||||
eq_(render.call_args[0][1], 'site/500_paypal.html')
|
||||
|
||||
def test_not_caught(self):
|
||||
self.func.side_effect = ZeroDivisionError
|
||||
view = handle_paypal_error(self.func)
|
||||
self.assertRaises(ZeroDivisionError, view, self.request)
|
||||
|
||||
@patch('jingo.render')
|
||||
def test_submission(self, render):
|
||||
self.get_request('/?dest=submission')
|
||||
self.func.side_effect = PaypalError
|
||||
view = handle_paypal_error(self.func)
|
||||
addon = Addon.objects.create(type=amo.ADDON_WEBAPP)
|
||||
view(self.request, addon=addon)
|
||||
eq_(render.call_args[0][2]['submission'], True)
|
||||
eq_(render.call_args[0][2]['addon'], addon)
|
||||
|
|
|
@ -47,6 +47,7 @@ from files.utils import parse_addon
|
|||
from market.models import AddonPremium, Refund, AddonPaymentData
|
||||
from payments.models import InappConfig
|
||||
from paypal.check import Check
|
||||
from paypal.decorators import handle_paypal_error
|
||||
import paypal
|
||||
from search.views import BaseAjaxSearch
|
||||
from stats.models import Contribution
|
||||
|
@ -317,6 +318,7 @@ def paypal_setup_confirm(request, addon_id, addon, webapp, source='paypal'):
|
|||
|
||||
@write
|
||||
@dev_required(webapp=True, skip_submit_check=True)
|
||||
@handle_paypal_error
|
||||
def acquire_refund_permission(request, addon_id, addon, webapp=False):
|
||||
"""This is the callback from Paypal."""
|
||||
# Set up our redirects.
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
{% extends 'base_modal.html' if request.is_ajax() else 'developers/base_impala.html' %}
|
||||
|
||||
{% block title %}{{ hub_page_title(_('Oops')) }}{% endblock %}
|
||||
|
||||
{# TODO(apps): Finalize copy. #}
|
||||
|
||||
{% block content %}
|
||||
<section class="primary">
|
||||
<header>
|
||||
<h1>Oops!</h1>
|
||||
</header>
|
||||
<div class="island hero prose">
|
||||
<p class="paypal-error-message">
|
||||
We tried to communicate with PayPal to complete that request, but
|
||||
we got an error back. It could be on our end or it might be on the other.
|
||||
</p>
|
||||
{% if submission and addon %}
|
||||
<form method="post" action="{{ url('submit.app.payments.paypal', addon.app_slug) }}">
|
||||
{{ csrf() }}
|
||||
<input type="hidden" name="business_account" value="later" />
|
||||
<p>Setting up PayPal is required if you'd like to sell your app on
|
||||
the marketplace.</p>
|
||||
<p>
|
||||
<input type="submit" class="button" value="Setup PayPal later"> or
|
||||
<a href="{{ url('submit.app.payments.bounce', addon.app_slug) }}">try again</a>.
|
||||
</p>
|
||||
{% else %}
|
||||
<p>You can try refreshing the page, or try again later.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{# Hide "Internal Server Error" message. #}
|
||||
{% block outer_content %}{% endblock %}
|
|
@ -10,6 +10,7 @@ from pyquery import PyQuery as pq
|
|||
import waffle
|
||||
|
||||
import amo
|
||||
from amo.helpers import urlparams
|
||||
import amo.tests
|
||||
from amo.tests import close_to_now, formset, initial
|
||||
from amo.tests.test_helpers import get_image_path
|
||||
|
@ -23,6 +24,7 @@ from files.tests.test_models import UploadTest as BaseUploadTest
|
|||
from market.models import Price
|
||||
import mkt
|
||||
from mkt.submit.models import AppSubmissionChecklist
|
||||
import paypal
|
||||
from translations.models import Translation
|
||||
from users.models import UserProfile
|
||||
from webapps.models import Webapp
|
||||
|
@ -816,6 +818,36 @@ class TestPayments(TestSubmit):
|
|||
eq_(res.status_code, 302)
|
||||
self.assertRedirects(res, self.get_url('done'))
|
||||
|
||||
def get_acquire_url(self):
|
||||
url = self.webapp.get_dev_url('acquire_refund_permission')
|
||||
return urlparams(url, dest='submission', request_token='foo',
|
||||
verification_code='foo')
|
||||
|
||||
@mock.patch('paypal.get_permissions_token')
|
||||
@mock.patch('paypal.get_personal_data')
|
||||
def test_bounce_result_works(self, get_personal_data,
|
||||
get_permissions_token):
|
||||
self.webapp.update(premium_type=amo.ADDON_PREMIUM)
|
||||
get_permissions_token.return_value = 'foo'
|
||||
get_personal_data.return_value = {}
|
||||
res = self.client.get(self.get_acquire_url())
|
||||
eq_(res.status_code, 302)
|
||||
self.assertRedirects(res, self.get_url('payments.confirm'))
|
||||
|
||||
@mock.patch('paypal.get_permissions_token')
|
||||
def test_bounce_result_fails(self, get_permissions_token):
|
||||
self.webapp.update(premium_type=amo.ADDON_PREMIUM)
|
||||
get_permissions_token.side_effect = paypal.PaypalError
|
||||
res = self.client.get(self.get_acquire_url())
|
||||
eq_(res.status_code, 500)
|
||||
self.assertTemplateUsed(res, 'site/500_paypal.html')
|
||||
|
||||
doc = pq(res.content)
|
||||
eq_(doc('div.prose form a').attr('href'),
|
||||
self.get_url('payments.bounce'))
|
||||
eq_(doc('div.prose form').attr('action'),
|
||||
self.get_url('payments.paypal'))
|
||||
|
||||
def test_bad_paypal(self):
|
||||
# some tests for when it goes wrong
|
||||
raise SkipTest
|
||||
|
|
Загрузка…
Ссылка в новой задаче