allow refunds, just not instant ones for in-app (bug 746417)

This commit is contained in:
Andy McKay 2012-04-18 07:37:34 -07:00
Родитель d0b25d4021
Коммит 9509f4bebe
6 изменённых файлов: 24 добавлений и 49 удалений

Просмотреть файл

@ -340,15 +340,8 @@ class Contribution(amo.models.ModelBase):
def get_absolute_refund_url(self):
return absolutify(self.get_refund_url())
def can_we_refund(self):
"""
We can only refund a purchase.
We cannot refund in-app payments; PayPal can however.
"""
return self.type == amo.CONTRIB_PURCHASE
def is_instant_refund(self):
if not self.can_we_refund():
if self.type != amo.CONTRIB_PURCHASE:
return False
limit = datetime.timedelta(seconds=settings.PAYPAL_REFUND_INSTANT)
return datetime.datetime.now() < (self.created + limit)

Просмотреть файл

@ -57,20 +57,17 @@ class TestContributionModel(amo.tests.TestCase):
def test_instant_refund(self):
self.con.update(created=datetime.now())
assert self.con.can_we_refund(), 'Refund on purchases'
assert self.con.is_instant_refund(), 'Refund should be instant'
def test_not_instant_refund(self):
diff = timedelta(seconds=settings.PAYPAL_REFUND_INSTANT + 10)
self.con.update(created=datetime.now() - diff)
assert self.con.can_we_refund(), 'Refund on purchases'
assert not self.con.is_instant_refund(), "Refund shouldn't be instant"
def test_refund_inapp_instant(self):
for ctype in ('CONTRIB_INAPP', 'CONTRIB_INAPP_PENDING'):
self.con.update(created=datetime.now(), type=getattr(amo, ctype))
assert not self.con.can_we_refund(), (
'No refund on %s inapp' % ctype)
assert not self.con.is_instant_refund(), (
'No refund on %s inapp' % ctype)
@ -79,12 +76,9 @@ class TestContributionModel(amo.tests.TestCase):
for ctype in ('CONTRIB_INAPP', 'CONTRIB_INAPP_PENDING'):
self.con.update(created=datetime.now() - diff,
type=getattr(amo, ctype))
assert not self.con.can_we_refund(), (
'No refund on %s inapp' % ctype)
assert not self.con.is_instant_refund(), (
'No refund on %s inapp' % ctype)
class TestEmail(amo.tests.TestCase):
fixtures = ['base/users', 'base/addon_3615']

Просмотреть файл

@ -2,14 +2,24 @@
<form method="post">
{{ csrf() }}
<p>
{% trans support_url=url('support', contribution.pk, 'author') %}
If you are unsatisfied with your purchase, you may request a
refund from the developer for up to 60 days. Requests within 30
minutes after purchase are automatically granted. If you are
having difficulty using the app, we encourage you to
<a href="{{ support_url }}">ask the developer for support</a> before
requesting a refund.
{% endtrans %}
{% if contribution.type == amo.CONTRIB_INAPP %}
{% trans support_url=url('support', contribution.pk, 'author') %}
If you are unsatisfied with your purchase, you may request a
refund from the developer for up to 60 days. If you are
having difficulty using the app, we encourage you to
<a href="{{ support_url }}">ask the developer for support</a> before
requesting a refund.
{% endtrans %}
{% else %}
{% trans support_url=url('support', contribution.pk, 'author') %}
If you are unsatisfied with your purchase, you may request a
refund from the developer for up to 60 days. Requests within 30
minutes after purchase are automatically granted. If you are
having difficulty using the app, we encourage you to
<a href="{{ support_url }}">ask the developer for support</a> before
requesting a refund.
{% endtrans %}
{% endif %}
</p>
<p class="form-footer">
<button type="submit">{{ _('Continue') }}</button> {{ _('or') }}

Просмотреть файл

@ -8,12 +8,8 @@
<li><a href="{{ url('support', contribution.pk, 'resources') }}">
{{ _('I have billing or payment concerns') }} &raquo;</a></li>
{% if waffle.switch('allow-refund') %}
{% if contribution.can_we_refund() %}
<li><a href="{{ url('support', contribution.pk, 'request') }}">
{{ _('I want to request a refund') }} &raquo;</a></li>
{% elif contribution.type == amo.CONTRIB_INAPP %}
<li>{{ _('In-app purchases cannot be refunded through the Marketplace.') }}</li>
{% endif %}
<li><a href="{{ url('support', contribution.pk, 'request') }}">
{{ _('I want to request a refund') }} &raquo;</a></li>
{% else %}
{# No L10n or even `loc` on purpose. #}
<li>

Просмотреть файл

@ -31,13 +31,6 @@ class TestRequestSupport(PurchaseBase):
eq_(doc('#support-start').find('a').eq(0).attr('href'),
self.get_support_url('author'))
def test_start_no_inapp_refund(self):
self.con.update(type=amo.CONTRIB_INAPP)
r = self.client.get(self.get_support_url())
content = r.content.decode('utf-8')
eq_(pq(content)('#support-start').find('a').length, 3)
assert self.get_support_url('request') not in content
def test_support_page_external_link(self):
self.app.support_url = 'http://omg.org/yes'
self.app.save()
@ -94,10 +87,10 @@ class TestRequestSupport(PurchaseBase):
res = self.client.post(self.get_support_url('mozilla'), {'b': 'c'})
assert 'text' in res.context['form'].errors
def test_no_request_inapp(self):
def test_request_inapp(self):
self.con.update(type=amo.CONTRIB_INAPP)
res = self.client.post(self.get_support_url('request'))
eq_(res.status_code, 403)
eq_(res.status_code, 302)
def test_refund_remove(self):
res = self.client.post(self.get_support_url('request'), {'remove': 1})
@ -127,11 +120,6 @@ class TestRequestSupport(PurchaseBase):
eq_(len(mail.outbox), 0)
self.assertRedirects(res, reverse('account.purchases'), 302)
def test_no_reason_inapp(self):
self.con.update(type=amo.CONTRIB_INAPP)
res = self.client.post(self.get_support_url('reason'))
eq_(res.status_code, 403)
@mock.patch('stats.models.Contribution.is_instant_refund')
def test_request_mails(self, is_instant_refund):
is_instant_refund.return_value = False

Просмотреть файл

@ -99,9 +99,6 @@ def support_mozilla(request, contribution, wizard):
@waffle_switch('allow-refund')
def refund_request(request, contribution, wizard):
if not contribution.can_we_refund():
return http.HttpResponseForbidden()
addon = contribution.addon
if request.method == 'POST':
return redirect('support', contribution.pk, 'reason')
@ -112,9 +109,6 @@ def refund_request(request, contribution, wizard):
@waffle_switch('allow-refund')
def refund_reason(request, contribution, wizard):
if not contribution.can_we_refund():
return http.HttpResponseForbidden()
addon = contribution.addon
if not 'request' in wizard.get_progress():
return redirect('support', contribution.pk, 'request')