porting /addons/contribute/$id to /addon/$id/contribute bug(565496)
This commit is contained in:
Родитель
7fa1b50e22
Коммит
cb29e6b382
|
@ -18,6 +18,8 @@ from addons.views import _details_collections_dropdown
|
|||
from users.models import UserProfile
|
||||
from translations.query import order_by_translation
|
||||
|
||||
import re
|
||||
|
||||
|
||||
class TestHomepage(amo.test_utils.ExtraSetup, test_utils.TestCase):
|
||||
fixtures = ['base/fixtures', 'base/global-stats', 'base/featured']
|
||||
|
@ -116,6 +118,105 @@ class TestContributeInstalled(test_utils.TestCase):
|
|||
eq_(title[:37], 'Thank you for installing Gmail S/MIME')
|
||||
|
||||
|
||||
class TestContribute(test_utils.TestCase):
|
||||
fixtures = ['base/fixtures']
|
||||
|
||||
def test_invalid_is_404(self):
|
||||
"""we get a 404 in case of invalid addon id"""
|
||||
response = self.client.get(reverse('addons.contribute', args=[1]))
|
||||
eq_(response.status_code, 404)
|
||||
|
||||
def test_redirect_params_no_type(self):
|
||||
"""Test that we have the required ppal params when no type is given"""
|
||||
response = self.client.get(reverse('addons.contribute',
|
||||
args=[592]), follow=True)
|
||||
redirect_url = response.redirect_chain[0][0]
|
||||
required_params = ['bn', 'business', 'charset', 'cmd', 'item_name',
|
||||
'no_shipping', 'notify_url',
|
||||
'return', 'item_number']
|
||||
for param in required_params:
|
||||
assert(redirect_url.find(param + '=') > -1), \
|
||||
"param [%s] not found" % param
|
||||
|
||||
def test_redirect_params_common(self):
|
||||
"""Test for the common values that do not change based on type,
|
||||
Check that they have expected values"""
|
||||
response = self.client.get(reverse('addons.contribute',
|
||||
args=[592]), follow=True)
|
||||
redirect_url = response.redirect_chain[0][0]
|
||||
assert(re.search('business=([^&]+)', redirect_url))
|
||||
common_params = {'bn': r'-AddonID592',
|
||||
'business': r'gmailsmime%40seantek.com',
|
||||
'charset': r'utf-8',
|
||||
'cmd': r'_donations',
|
||||
'item_name': r'Contribution\+for\+Gmail\+S%2FMIME',
|
||||
'no_shipping': r'1',
|
||||
'notify_url': r'%2Fservices%2Fpaypal',
|
||||
'return': r'x',
|
||||
'item_number': r'[a-f\d]{32}'}
|
||||
|
||||
message = 'param [%s] unexpected value: given [%s], ' \
|
||||
+ 'expected pattern [%s]'
|
||||
for param, value_pattern in common_params.items():
|
||||
match = re.search(r'%s=([^&]+)' % param, redirect_url)
|
||||
assert(match and re.search(value_pattern, match.group(1))), \
|
||||
message % (param, match.group(1), value_pattern)
|
||||
|
||||
def test_redirect_params_type_suggested(self):
|
||||
"""Test that we have the required ppal param when type
|
||||
suggested is given"""
|
||||
request_params = '?type=suggested'
|
||||
response = self.client.get(reverse('addons.contribute',
|
||||
args=[592]) + request_params,
|
||||
follow=True)
|
||||
redirect_url = response.redirect_chain[0][0]
|
||||
required_params = ['amount', 'bn', 'business', 'charset',
|
||||
'cmd', 'item_name', 'no_shipping', 'notify_url',
|
||||
'return', 'item_number']
|
||||
for param in required_params:
|
||||
assert(redirect_url.find(param + '=') > -1), \
|
||||
"param [%s] not found" % param
|
||||
|
||||
def test_redirect_params_type_onetime(self):
|
||||
"""Test that we have the required ppal param when
|
||||
type onetime is given"""
|
||||
request_params = '?type=onetime&onetime-amount=42'
|
||||
response = self.client.get(reverse('addons.contribute',
|
||||
args=[592]) + request_params,
|
||||
follow=True)
|
||||
redirect_url = response.redirect_chain[0][0]
|
||||
required_params = ['amount', 'bn', 'business', 'charset', 'cmd',
|
||||
'item_name', 'no_shipping', 'notify_url',
|
||||
'return', 'item_number']
|
||||
for param in required_params:
|
||||
assert(redirect_url.find(param + '=') > -1), \
|
||||
"param [%s] not found" % param
|
||||
|
||||
assert(redirect_url.find('amount=42') > -1)
|
||||
|
||||
def test_redirect_params_type_monthly(self):
|
||||
"""Test that we have the required ppal param when
|
||||
type monthly is given"""
|
||||
request_params = '?type=monthly&monthly-amount=42'
|
||||
response = self.client.get(reverse('addons.contribute',
|
||||
args=[592]) + request_params,
|
||||
follow=True)
|
||||
redirect_url = response.redirect_chain[0][0]
|
||||
required_params = ['no_note', 'a3', 't3', 'p3', 'bn', 'business',
|
||||
'charset', 'cmd', 'item_name', 'no_shipping',
|
||||
'notify_url', 'return', 'item_number']
|
||||
for param in required_params:
|
||||
assert(redirect_url.find(param + '=') > -1), \
|
||||
"param [%s] not found" % param
|
||||
|
||||
assert(redirect_url.find('cmd=_xclick-subscriptions') > -1), \
|
||||
'param a3 was not 42'
|
||||
assert(redirect_url.find('p3=12') > -1), 'param p3 was not 12'
|
||||
assert(redirect_url.find('t3=M') > -1), 'param t3 was not M'
|
||||
assert(redirect_url.find('a3=42') > -1), 'param a3 was not 42'
|
||||
assert(redirect_url.find('no_note=1') > -1), 'param no_note was not 1'
|
||||
|
||||
|
||||
class TestDeveloperPages(test_utils.TestCase):
|
||||
fixtures = ['base/fixtures', 'addons/eula+contrib-addon']
|
||||
|
||||
|
|
|
@ -15,9 +15,10 @@ detail_patterns = patterns('',
|
|||
{'page': 'roadblock'}, name='addons.roadblock'),
|
||||
url('^contribute/installed/', views.developers,
|
||||
{'page': 'installed'}, name='addons.installed'),
|
||||
('^contribute/thanks$', lambda r, addon_id: redirect('addons.detail',
|
||||
addon_id)),
|
||||
|
||||
url('^contribute/thanks', lambda r,
|
||||
addon_id: redirect('addons.detail', addon_id),
|
||||
name='addons.thanks'),
|
||||
url('^contribute/', views.contribute, name='addons.contribute'),
|
||||
('^about$', lambda r, addon_id: redirect('addons.installed',
|
||||
addon_id, permanent=True)),
|
||||
|
||||
|
|
|
@ -13,11 +13,15 @@ from amo.utils import sorted_groupby, randslice
|
|||
from amo import urlresolvers
|
||||
from amo.urlresolvers import reverse
|
||||
from bandwagon.models import Collection, CollectionFeature, CollectionPromo
|
||||
from stats.models import GlobalStat
|
||||
from stats.models import GlobalStat, Contribution
|
||||
from tags.models import Tag
|
||||
from translations.query import order_by_translation
|
||||
from .models import Addon
|
||||
|
||||
import hashlib
|
||||
import urllib
|
||||
import uuid
|
||||
|
||||
|
||||
def author_addon_clicked(f):
|
||||
"""Decorator redirecting clicks on "Other add-ons by author"."""
|
||||
|
@ -397,3 +401,82 @@ def developers(request, addon_id, page):
|
|||
return jingo.render(request, 'addons/developers.html',
|
||||
{'addon': addon, 'author_addons': author_addons,
|
||||
'page': page})
|
||||
|
||||
|
||||
def contribute(request, addon_id):
|
||||
|
||||
addon = get_object_or_404(Addon.objects.valid(), id=addon_id)
|
||||
|
||||
contrib_type = request.GET.get('type', '')
|
||||
is_suggested = contrib_type == 'suggested'
|
||||
source = request.GET.get('source', '')
|
||||
comment = request.GET.get('comment', '')
|
||||
|
||||
amount = {
|
||||
'suggested': addon.suggested_amount,
|
||||
'onetime': request.GET.get('onetime-amount', ''),
|
||||
'monthly': request.GET.get('monthly-amount', '')}.get(contrib_type, '')
|
||||
|
||||
contribution_uuid = hashlib.md5(str(uuid.uuid4())).hexdigest()
|
||||
|
||||
contrib = Contribution(addon_id=addon.id,
|
||||
amount=amount,
|
||||
source=source,
|
||||
source_locale=request.LANG,
|
||||
annoying=addon.annoying,
|
||||
uuid=str(contribution_uuid),
|
||||
is_suggested=is_suggested,
|
||||
suggested_amount=addon.suggested_amount,
|
||||
comment=comment)
|
||||
contrib.save()
|
||||
|
||||
return_url = "%s?%s" % (reverse('addons.thanks', args=[addon.id]),
|
||||
urllib.urlencode({'uuid': contribution_uuid}))
|
||||
|
||||
redirect_url_params = contribute_url_params(
|
||||
addon.paypal_id,
|
||||
addon.id,
|
||||
'Contribution for %s' % addon.name,
|
||||
return_url,
|
||||
amount,
|
||||
contribution_uuid,
|
||||
contrib_type == 'monthly',
|
||||
comment)
|
||||
|
||||
return http.HttpResponseRedirect(settings.PAYPAL_CGI_URL
|
||||
+ '?'
|
||||
+ urllib.urlencode(redirect_url_params))
|
||||
|
||||
|
||||
def contribute_url_params(business, addon_id, item_name, return_url,
|
||||
amount='', item_number='',
|
||||
monthly=False, comment=''):
|
||||
|
||||
"""Get all the data elements that will be URL params
|
||||
on the Paypal redirect URL"""
|
||||
|
||||
data = {'business': business,
|
||||
'item_name': item_name,
|
||||
'item_number': item_number,
|
||||
'bn': settings.PAYPAL_BN + '-AddonID' + str(addon_id),
|
||||
'no_shipping': '1',
|
||||
'return': return_url,
|
||||
'charset': 'utf-8',
|
||||
'notify_url': reverse('amo.paypal')}
|
||||
|
||||
if (not monthly):
|
||||
data['cmd'] = '_donations'
|
||||
if (amount):
|
||||
data['amount'] = amount
|
||||
else:
|
||||
data.update({
|
||||
'cmd': '_xclick-subscriptions',
|
||||
'p3': '12', # duration: for 12 months
|
||||
't3': 'M', # time unit, 'M' for month
|
||||
'a3': amount, # recurring contribution amount
|
||||
'no_note': '1'}) # required: no "note" text field for user
|
||||
|
||||
if (comment):
|
||||
data['custom'] = comment
|
||||
|
||||
return data
|
||||
|
|
|
@ -25,9 +25,18 @@ class TestRedirects(test.TestCase):
|
|||
assert r.redirect_chain[-1][0].endswith('/en-US/firefox/addon/4/')
|
||||
|
||||
def test_contribute_installed(self):
|
||||
"""`/addon/\d+/about` should go to `/addon/\d+/contribute/installed`."""
|
||||
"""`/addon/\d+/about` should go to
|
||||
`/addon/\d+/contribute/installed`."""
|
||||
r = self.client.get(u'addon/5326/about', follow=True)
|
||||
assert r.redirect_chain[-1][0].endswith('/en-US/firefox/addon/5326/contribute/installed/')
|
||||
redirect = r.redirect_chain[-1][0]
|
||||
assert redirect.endswith(
|
||||
'/en-US/firefox/addon/5326/contribute/installed/')
|
||||
|
||||
def test_contribute(self):
|
||||
"""`/addons/contribute/$id` should go to `/addon/$id/contribute`."""
|
||||
response = self.client.get(u'addon/5326/contribute', follow=True)
|
||||
redirect = response.redirect_chain[-1][0]
|
||||
assert redirect.endswith('/en-US/firefox/addon/5326/contribute/')
|
||||
|
||||
def test_utf8(self):
|
||||
"""Without proper unicode handling this will fail."""
|
||||
|
|
|
@ -447,6 +447,7 @@ CAKE_SESSION_TIMEOUT = 8640
|
|||
|
||||
# PayPal Settings
|
||||
PAYPAL_CGI_URL = 'https://www.paypal.com/cgi-bin/webscr'
|
||||
PAYPAL_BN = ''
|
||||
|
||||
# Email settings
|
||||
DEFAULT_FROM_EMAIL = "Mozilla Add-ons <nobody@mozilla.org>"
|
||||
|
|
3
urls.py
3
urls.py
|
@ -77,6 +77,9 @@ urlpatterns = patterns('',
|
|||
('^search-engines.*$',
|
||||
lambda r: redirect('browse.search-tools', permanent=True)),
|
||||
|
||||
('^addons/contribute/(\d+)/?$',
|
||||
lambda r, id: redirect('addons.contribute', id, permanent=True)),
|
||||
|
||||
# Firefox Cup page, /firefoxcup
|
||||
('^firefoxcup/', include('firefoxcup.urls'))
|
||||
)
|
||||
|
|
Загрузка…
Ссылка в новой задаче