porting /addons/contribute/$id to /addon/$id/contribute bug(565496)

This commit is contained in:
Sam Keen 2010-06-23 10:08:16 -07:00
Родитель 7fa1b50e22
Коммит cb29e6b382
6 изменённых файлов: 204 добавлений и 6 удалений

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

@ -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>"

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

@ -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'))
)