addons-server/apps/devhub/tests/test_views.py

913 строки
34 KiB
Python
Исходник Обычный вид История

2010-10-08 07:08:41 +04:00
from decimal import Decimal
import re
2010-10-11 22:24:41 +04:00
import socket
2010-10-08 07:08:41 +04:00
2010-10-20 21:40:20 +04:00
from django import forms
2010-09-30 07:12:18 +04:00
from django.utils import translation
2010-10-11 22:24:41 +04:00
import mock
from nose.tools import eq_, assert_not_equal
from pyquery import PyQuery as pq
import test_utils
import amo
2010-10-11 22:24:41 +04:00
import paypal
from amo.urlresolvers import reverse
2010-10-08 07:08:41 +04:00
from addons.models import Addon, AddonUser, Charity
2010-10-20 21:40:20 +04:00
from applications.models import AppVersion
from devhub.forms import ContribForm, ProfileForm
from users.models import UserProfile
2010-10-05 23:24:31 +04:00
from versions.models import License, Version
class HubTest(test_utils.TestCase):
fixtures = ('browse/nameless-addon', 'base/users')
def setUp(self):
translation.activate('en-US')
self.url = reverse('devhub.index')
self.login_as_developer()
eq_(self.client.get(self.url).status_code, 200)
self.user_profile = UserProfile.objects.get(id=999)
self.num_addon_clones = 0
def login_as_developer(self):
self.client.login(username='regular@mozilla.com', password='password')
def clone_addon(self, num_copies, addon_id=57132):
for i in xrange(num_copies):
addon = Addon.objects.get(id=addon_id)
addon.id = addon.guid = None
addon.save()
AddonUser.objects.create(user=self.user_profile, addon=addon)
new_addon = Addon.objects.get(id=addon.id)
new_addon.name = 'addon-%s' % self.num_addon_clones
new_addon.save()
self.num_addon_clones += 1
class TestNav(HubTest):
def test_navbar(self):
r = self.client.get(self.url)
doc = pq(r.content)
eq_(doc('#navbar').length, 1)
def test_no_addons(self):
"""Check that no add-ons are displayed for this user."""
r = self.client.get(self.url)
doc = pq(r.content)
assert_not_equal(doc('#navbar ul li.top a').eq(0).text(),
'My Add-ons',
'My Add-ons menu should not be visible if user has no add-ons.')
def test_my_addons(self):
"""Check that the correct items are listed for the My Add-ons menu."""
# Assign this add-on to the current user profile.
addon = Addon.objects.get(id=57132)
AddonUser.objects.create(user=self.user_profile, addon=addon)
r = self.client.get(self.url)
doc = pq(r.content)
# Check the anchor for the 'My Add-ons' menu item.
eq_(doc('#navbar ul li.top a').eq(0).text(), 'My Add-ons')
# Check the anchor for the single add-on.
edit_url = reverse('devhub.addons.edit', args=[57132])
eq_(doc('#navbar ul li.top li a').eq(0).attr('href'), edit_url)
# Create 6 add-ons.
self.clone_addon(6)
r = self.client.get(self.url)
doc = pq(r.content)
# There should be 8 items in this menu.
eq_(doc('#navbar ul li.top').eq(0).find('ul li').length, 8)
# This should be the 8th anchor, after the 7 addons.
eq_(doc('#navbar ul li.top').eq(0).find('li a').eq(7).text(),
'Submit a New Add-on')
self.clone_addon(1)
r = self.client.get(self.url)
doc = pq(r.content)
eq_(doc('#navbar ul li.top').eq(0).find('li a').eq(7).text(),
'more add-ons...')
class TestDashboard(HubTest):
def setUp(self):
super(TestDashboard, self).setUp()
self.url = reverse('devhub.addons')
eq_(self.client.get(self.url).status_code, 200)
def test_no_addons(self):
"""Check that no add-ons are displayed for this user."""
r = self.client.get(self.url)
doc = pq(r.content)
eq_(doc('.item item').length, 0)
def test_addons_items(self):
"""Check that the correct info. is displayed for each add-on:
namely, that add-ons are paginated at 10 items per page, and that
when there is more than one page, the 'Sort by' header and pagination
footer appear.
"""
# Create 10 add-ons.
self.clone_addon(10)
r = self.client.get(self.url)
doc = pq(r.content)
# There should be 10 add-on listing items.
eq_(len(doc('.item .item-info')), 10)
# There should be neither a listing header nor a pagination footer.
eq_(doc('#addon-list-options').length, 0)
eq_(doc('.listing-footer .pagination').length, 0)
# Create 5 add-ons.
self.clone_addon(5)
r = self.client.get(self.url + '?page=2')
doc = pq(r.content)
# There should be 10 add-on listing items.
eq_(len(doc('.item .item-info')), 5)
# There should be a listing header and pagination footer.
eq_(doc('#addon-list-options').length, 1)
eq_(doc('.listing-footer .pagination').length, 1)
2010-09-30 07:12:18 +04:00
2010-10-20 21:40:20 +04:00
def formset(*args, **kw):
"""
Build up a formset-happy POST.
*args is a sequence of forms going into the formset.
prefix and initial_count can be set in **kw.
"""
prefix = kw.pop('prefix', 'form')
initial_count = kw.pop('initial_count', 0)
data = {prefix + '-TOTAL_FORMS': len(args),
prefix + '-INITIAL_FORMS': initial_count}
for idx, d in enumerate(args):
data.update(('%s-%s-%s' % (prefix, idx, k), v)
for k, v in d.items())
data.update(kw)
return data
2010-09-30 07:12:18 +04:00
class TestOwnership(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_3615']
def setUp(self):
self.url = reverse('devhub.addons.owner', args=[3615])
assert self.client.login(username='del@icio.us', password='password')
2010-10-05 23:24:31 +04:00
self.addon = Addon.objects.get(id=3615)
self.version = self.addon.current_version
2010-09-30 07:12:18 +04:00
def formset(self, *args, **kw):
2010-10-20 21:40:20 +04:00
defaults = {'builtin': License.OTHER, 'text': 'filler'}
defaults.update(kw)
return formset(*args, **defaults)
2010-09-30 07:12:18 +04:00
2010-10-05 23:24:31 +04:00
def get_version(self):
return Version.objects.no_cache().get(id=self.version.id)
2010-10-07 02:37:36 +04:00
def get_addon(self):
return Addon.objects.no_cache().get(id=self.addon.id)
class TestEditPolicy(TestOwnership):
def formset(self, *args, **kw):
init = self.client.get(self.url).context['user_form'].initial_forms
args = args + tuple(f.initial for f in init)
return super(TestEditPolicy, self).formset(*args, **kw)
def test_edit_eula(self):
old_eula = self.addon.eula
data = self.formset(eula='new eula', has_eula=True)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
addon = self.get_addon()
eq_(unicode(addon.eula), 'new eula')
eq_(addon.eula.id, old_eula.id)
def test_delete_eula(self):
assert self.addon.eula
r = self.client.post(self.url, self.formset(has_eula=False))
eq_(r.status_code, 302)
eq_(self.get_addon().eula, None)
2010-10-05 23:24:31 +04:00
class TestEditLicense(TestOwnership):
def setUp(self):
super(TestEditLicense, self).setUp()
self.version.license = None
self.version.save()
self.license = License.objects.create(builtin=1, name='bsd',
on_form=True)
def formset(self, *args, **kw):
init = self.client.get(self.url).context['user_form'].initial_forms
args = args + tuple(f.initial for f in init)
2010-10-13 00:53:05 +04:00
kw['initial_count'] = len(init)
2010-10-05 23:24:31 +04:00
data = super(TestEditLicense, self).formset(*args, **kw)
if 'text' not in kw:
del data['text']
return data
def test_success_add_builtin(self):
data = self.formset(builtin=1)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
eq_(self.license, self.get_version().license)
def test_success_add_custom(self):
data = self.formset(builtin=License.OTHER, text='text', name='name')
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
license = self.get_version().license
eq_(unicode(license.text), 'text')
eq_(unicode(license.name), 'name')
eq_(license.builtin, License.OTHER)
def test_success_edit_custom(self):
data = self.formset(builtin=License.OTHER, text='text', name='name')
r = self.client.post(self.url, data)
license_one = self.get_version().license
data = self.formset(builtin=License.OTHER, text='woo', name='name')
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
license_two = self.get_version().license
eq_(unicode(license_two.text), 'woo')
eq_(unicode(license_two.name), 'name')
eq_(license_two.builtin, License.OTHER)
eq_(license_two.id, license_one.id)
def test_success_switch_license(self):
data = self.formset(builtin=1)
r = self.client.post(self.url, data)
license_one = self.get_version().license
data = self.formset(builtin=License.OTHER, text='text', name='name')
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
license_two = self.get_version().license
eq_(unicode(license_two.text), 'text')
eq_(unicode(license_two.name), 'name')
eq_(license_two.builtin, License.OTHER)
assert license_one != license_two
# Make sure the old license wasn't edited.
license = License.objects.get(builtin=1)
eq_(unicode(license.name), 'bsd')
data = self.formset(builtin=1)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
license_three = self.get_version().license
eq_(license_three, license_one)
def test_custom_has_text(self):
data = self.formset(builtin=License.OTHER, name='name')
r = self.client.post(self.url, data)
eq_(r.status_code, 200)
self.assertFormError(r, 'license_form', None,
'License text is required when choosing Other.')
def test_custom_has_name(self):
data = self.formset(builtin=License.OTHER, text='text')
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
license = self.get_version().license
eq_(unicode(license.text), 'text')
eq_(unicode(license.name), 'Custom License')
eq_(license.builtin, License.OTHER)
def test_no_version(self):
# Make sure nothing bad happens if there's no version.
self.addon.update(_current_version=None)
Version.objects.all().delete()
data = self.formset(builtin=License.OTHER, text='text')
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
class TestEditAuthor(TestOwnership):
2010-09-30 07:12:18 +04:00
def test_success_add_user(self):
q = (AddonUser.objects.no_cache().filter(addon=3615)
.values_list('user', flat=True))
eq_(list(q.all()), [55021])
f = self.client.get(self.url).context['user_form'].initial_forms[0]
u = dict(user='regular@mozilla.com', listed=True,
2010-10-12 03:06:15 +04:00
role=amo.AUTHOR_ROLE_DEV, position=0)
2010-09-30 07:12:18 +04:00
data = self.formset(f.initial, u, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
eq_(list(q.all()), [55021, 999])
def test_success_edit_user(self):
# Add an author b/c we can't edit anything about the current one.
f = self.client.get(self.url).context['user_form'].initial_forms[0]
u = dict(user='regular@mozilla.com', listed=True,
2010-10-12 03:06:15 +04:00
role=amo.AUTHOR_ROLE_DEV, position=1)
2010-09-30 07:12:18 +04:00
data = self.formset(f.initial, u, initial_count=1)
self.client.post(self.url, data)
eq_(AddonUser.objects.get(addon=3615, user=999).listed, True)
# Edit the user we just added.
2010-10-13 00:53:05 +04:00
user_form = self.client.get(self.url).context['user_form']
one, two = user_form.initial_forms
del two.initial['listed']
empty = dict(user='', listed=True, role=5, position=0)
data = self.formset(one.initial, two.initial, empty, initial_count=2)
2010-09-30 07:12:18 +04:00
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
eq_(AddonUser.objects.no_cache().get(addon=3615, user=999).listed,
False)
2010-10-13 00:53:05 +04:00
def test_add_user_twice(self):
f = self.client.get(self.url).context['user_form'].initial_forms[0]
u = dict(user='regular@mozilla.com', listed=True,
role=amo.AUTHOR_ROLE_DEV, position=1)
data = self.formset(f.initial, u, u, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.status_code, 200)
eq_(r.context['user_form'].non_form_errors(),
['An author can only be listed once.'])
2010-09-30 07:12:18 +04:00
def test_success_delete_user(self):
data = self.formset(dict(user='regular@mozilla.com', listed=True,
2010-10-12 03:06:15 +04:00
role=amo.AUTHOR_ROLE_OWNER, position=1))
2010-09-30 07:12:18 +04:00
self.client.post(self.url, data)
one, two = self.client.get(self.url).context['user_form'].initial_forms
one.initial['DELETE'] = True
data = self.formset(one.initial, two.initial, initial_count=2)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
eq_(999, AddonUser.objects.get(addon=3615).user_id)
def test_switch_owner(self):
# See if we can transfer ownership in one POST.
f = self.client.get(self.url).context['user_form'].initial_forms[0]
f.initial['user'] = 'regular@mozilla.com'
data = self.formset(f.initial, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.status_code, 302)
eq_(999, AddonUser.objects.get(addon=3615).user_id)
def test_only_owner_can_edit(self):
f = self.client.get(self.url).context['user_form'].initial_forms[0]
u = dict(user='regular@mozilla.com', listed=True,
2010-10-12 03:06:15 +04:00
role=amo.AUTHOR_ROLE_DEV, position=0)
2010-09-30 07:12:18 +04:00
data = self.formset(f.initial, u, initial_count=1)
self.client.post(self.url, data)
self.client.login(username='regular@mozilla.com', password='password')
self.client.post(self.url, data, follow=True)
# Try deleting the other AddonUser
one, two = self.client.get(self.url).context['user_form'].initial_forms
one.initial['DELETE'] = True
data = self.formset(one.initial, two.initial, initial_count=2)
r = self.client.post(self.url, data, follow=True)
eq_(r.status_code, 403)
eq_(AddonUser.objects.filter(addon=3615).count(), 2)
def test_must_have_listed(self):
f = self.client.get(self.url).context['user_form'].initial_forms[0]
f.initial['listed'] = False
data = self.formset(f.initial, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.context['user_form'].non_form_errors(),
['At least one author must be listed.'])
def test_must_have_owner(self):
f = self.client.get(self.url).context['user_form'].initial_forms[0]
f.initial['role'] = amo.AUTHOR_ROLE_DEV
data = self.formset(f.initial, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.context['user_form'].non_form_errors(),
['Must have at least one owner.'])
def test_must_have_owner_delete(self):
f = self.client.get(self.url).context['user_form'].initial_forms[0]
f.initial['DELETE'] = True
data = self.formset(f.initial, initial_count=1)
r = self.client.post(self.url, data)
eq_(r.context['user_form'].non_form_errors(),
['Must have at least one owner.'])
2010-10-08 07:08:41 +04:00
class TestEditPayments(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_3615']
def setUp(self):
self.addon = self.get_addon()
self.foundation = Charity.objects.create(
id=amo.FOUNDATION_ORG, name='moz', url='$$.moz', paypal='moz.pal')
self.url = reverse('devhub.addons.payments', args=[self.addon.id])
assert self.client.login(username='del@icio.us', password='password')
2010-10-11 22:24:41 +04:00
self.paypal_mock = mock.Mock()
self.paypal_mock.return_value = (True, None)
paypal.check_paypal_id = self.paypal_mock
2010-10-08 07:08:41 +04:00
def get_addon(self):
return Addon.objects.no_cache().get(id=3615)
def post(self, *args, **kw):
d = dict(*args, **kw)
eq_(self.client.post(self.url, d).status_code, 302)
def check(self, **kw):
addon = self.get_addon()
for k, v in kw.items():
eq_(getattr(addon, k), v)
assert addon.wants_contributions
assert addon.takes_contributions
def test_success_dev(self):
self.post(recipient='dev', suggested_amount=2, paypal_id='greed@dev',
annoying=amo.CONTRIB_AFTER)
self.check(paypal_id='greed@dev', suggested_amount=2,
annoying=amo.CONTRIB_AFTER)
def test_success_foundation(self):
self.post(recipient='moz', suggested_amount=2, paypal_id='greed@dev',
annoying=amo.CONTRIB_ROADBLOCK)
self.check(paypal_id='greed@dev', suggested_amount=2,
charity=self.foundation, annoying=amo.CONTRIB_ROADBLOCK)
def test_success_charity(self):
d = dict(recipient='org', suggested_amount=11.5,
annoying=amo.CONTRIB_PASSIVE)
2010-10-11 22:24:41 +04:00
d.update({'charity-name': 'fligtar fund',
'charity-url': 'http://feed.me',
2010-10-08 07:08:41 +04:00
'charity-paypal': 'greed@org'})
self.post(d)
self.check(paypal_id='', suggested_amount=Decimal('11.50'),
charity=Charity.objects.get(name='fligtar fund'))
def test_dev_paypal_reqd(self):
d = dict(recipient='dev', suggested_amount=2,
annoying=amo.CONTRIB_PASSIVE)
r = self.client.post(self.url, d)
self.assertFormError(r, 'contrib_form', 'paypal_id',
2010-10-08 07:08:41 +04:00
'PayPal id required to accept contributions.')
def test_bad_paypal_id_dev(self):
2010-10-11 22:24:41 +04:00
self.paypal_mock.return_value = False, 'error'
d = dict(recipient='dev', suggested_amount=2, paypal_id='greed@dev',
annoying=amo.CONTRIB_AFTER)
r = self.client.post(self.url, d)
self.assertFormError(r, 'contrib_form', 'paypal_id', 'error')
def test_bad_paypal_id_charity(self):
self.paypal_mock.return_value = False, 'error'
d = dict(recipient='org', suggested_amount=11.5,
annoying=amo.CONTRIB_PASSIVE)
d.update({'charity-name': 'fligtar fund',
'charity-url': 'http://feed.me',
'charity-paypal': 'greed@org'})
r = self.client.post(self.url, d)
self.assertFormError(r, 'charity_form', 'paypal', 'error')
2010-10-11 22:24:41 +04:00
def test_paypal_timeout(self):
self.paypal_mock.side_effect = socket.timeout()
d = dict(recipient='dev', suggested_amount=2, paypal_id='greed@dev',
annoying=amo.CONTRIB_AFTER)
r = self.client.post(self.url, d)
self.assertFormError(r, 'contrib_form', 'paypal_id',
2010-10-11 22:24:41 +04:00
'Could not validate PayPal id.')
2010-10-08 07:08:41 +04:00
def test_charity_details_reqd(self):
d = dict(recipient='org', suggested_amount=11.5,
annoying=amo.CONTRIB_PASSIVE)
r = self.client.post(self.url, d)
self.assertFormError(r, 'charity_form', 'name',
'This field is required.')
eq_(self.get_addon().suggested_amount, None)
def test_switch_charity_to_dev(self):
self.test_success_charity()
self.test_success_dev()
eq_(self.get_addon().charity, None)
eq_(self.get_addon().charity_id, None)
def test_switch_charity_to_foundation(self):
self.test_success_charity()
self.test_success_foundation()
# This will break if we start cleaning up licenses.
old_charity = Charity.objects.get(name='fligtar fund')
assert old_charity.id != self.foundation
def test_switch_foundation_to_charity(self):
self.test_success_foundation()
self.test_success_charity()
moz = Charity.objects.get(id=self.foundation.id)
eq_(moz.name, 'moz')
eq_(moz.url, '$$.moz')
eq_(moz.paypal, 'moz.pal')
def test_contrib_form_initial(self):
eq_(ContribForm.initial(self.addon)['recipient'], 'dev')
self.addon.charity = self.foundation
eq_(ContribForm.initial(self.addon)['recipient'], 'moz')
self.addon.charity_id = amo.FOUNDATION_ORG + 1
eq_(ContribForm.initial(self.addon)['recipient'], 'org')
eq_(ContribForm.initial(self.addon)['annoying'], amo.CONTRIB_PASSIVE)
self.addon.annoying = amo.CONTRIB_AFTER
eq_(ContribForm.initial(self.addon)['annoying'], amo.CONTRIB_AFTER)
2010-10-12 21:51:17 +04:00
class TestDisablePayments(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_3615']
def setUp(self):
self.addon = Addon.objects.get(id=3615)
self.addon.update(wants_contributions=True, paypal_id='woohoo')
self.pay_url = reverse('devhub.addons.payments', args=[self.addon.id])
self.disable_url = reverse('devhub.addons.payments.disable',
args=[self.addon.id])
assert self.client.login(username='del@icio.us', password='password')
def test_statusbar_visible(self):
r = self.client.get(self.pay_url)
self.assertContains(r, '<div id="status-bar">')
self.addon.update(wants_contributions=False)
r = self.client.get(self.pay_url)
self.assertNotContains(r, '<div id="status-bar">')
def test_disable(self):
r = self.client.post(self.disable_url)
eq_(r.status_code, 302)
assert(r['Location'].endswith(self.pay_url))
eq_(Addon.uncached.get(id=3615).wants_contributions, False)
2010-10-13 20:14:01 +04:00
class TestEdit(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_3615',
'base/addon_5579']
2010-10-13 20:14:01 +04:00
def setUp(self):
super(TestEdit, self).setUp()
self.addon = self.get_addon()
2010-10-13 20:14:01 +04:00
assert self.client.login(username='del@icio.us', password='password')
self.url = reverse('devhub.addons.edit', args=[self.addon.id])
def get_addon(self):
return Addon.objects.no_cache().get(id=3615)
2010-10-13 20:14:01 +04:00
def get_url(self, section, edit=False):
args = [self.addon.id, section]
if edit:
args.append('edit')
return reverse('devhub.addons.section', args=args)
2010-10-13 20:14:01 +04:00
def test_redirect(self):
# /addon/:id => /addon/:id/edit
r = self.client.get('/en-US/developers/addon/3615/', follow=True)
url = reverse('devhub.addons.edit', args=[3615])
self.assertRedirects(r, url, 301)
2010-10-11 02:51:45 +04:00
def test_edit_basic(self):
old_name = self.addon.name
data = dict(name='new name',
slug='test_addon',
summary='new summary')
r = self.client.post(self.get_url('basic', True), data)
eq_(r.status_code, 200)
addon = self.get_addon()
eq_(unicode(addon.name), data['name'])
eq_(addon.name.id, old_name.id)
eq_(unicode(addon.slug), data['slug'])
eq_(unicode(addon.summary), data['summary'])
def test_edit_basic_slugs_unique(self):
Addon.objects.get(id=5579).update(slug='test_slug')
data = dict(name='new name',
slug='test_slug',
summary='new summary')
r = self.client.post(self.get_url('basic', True), data)
eq_(r.status_code, 200)
self.assertFormError(r, 'form', 'slug', 'This slug is already in use.')
def test_edit_basic_name_not_empty(self):
data = dict(name='',
slug=self.addon.slug,
summary=self.addon.summary)
r = self.client.post(self.get_url('basic', True), data)
eq_(r.status_code, 200)
self.assertFormError(r, 'form', 'name', 'This field is required.')
2010-10-15 08:12:56 +04:00
def test_edit_details(self):
data = dict(description='New description with <em>html</em>!',
default_locale='es-ES',
homepage='http://twitter.com/fligtarsmom')
r = self.client.post(self.get_url('details', True), data)
2010-10-15 08:12:56 +04:00
eq_(r.status_code, 200)
addon = self.get_addon()
for k in data:
eq_(unicode(getattr(addon, k)), data[k])
def test_edit_details_locale(self):
addon = self.get_addon()
addon.update(default_locale='en-US')
r = self.client.get(self.get_url('details', False))
2010-10-15 08:12:56 +04:00
doc = pq(r.content)
eq_(doc('.addon_edit_locale').eq(0).text(), "English (US)")
def test_edit_support(self):
data = dict(support_email='sjobs@apple.com',
support_url='http://apple.com/')
r = self.client.post(self.get_url('support', True), data)
eq_(r.status_code, 200)
addon = self.get_addon()
for k in data:
eq_(unicode(getattr(addon, k)), data[k])
def test_edit_support_getsatisfaction(self):
urls = [("getsatisfaction.com/abc/products/def", 'abcdef'), # GS URL
("getsatisfaction.com/abc/", 'abc'), # No company
("google.com", None)] # Delete GS
for (url, val) in urls:
data = dict(support_email='abc@def.com',
support_url=url)
r = self.client.post(self.get_url('support', True), data)
eq_(r.status_code, 200)
r = self.client.get(self.get_url('support', False))
doc = pq(r.content)
result = doc('.addon_edit_gs').eq(0).text()
result = re.sub('\W', '', result) if result else None
eq_(result, val)
def test_technical_on(self):
# Turn everything on
data = dict(developer_comments='Test comment!',
binary='on',
external_software='on',
site_specific='on',
view_source='on')
r = self.client.post(self.get_url('technical', True), data)
eq_(r.status_code, 200)
addon = self.get_addon()
for k in data:
if k == 'developer_comments':
eq_(unicode(getattr(addon, k)), unicode(data[k]))
else:
eq_(getattr(addon, k), True if data[k] == 'on' else False)
# Andddd offf
data = dict(developer_comments='Test comment!')
r = self.client.post(self.get_url('technical', True), data)
addon = self.get_addon()
eq_(addon.binary, False)
eq_(addon.external_software, False)
eq_(addon.site_specific, False)
eq_(addon.view_source, False)
2010-10-11 02:51:45 +04:00
class TestProfile(test_utils.TestCase):
fixtures = ['base/apps', 'base/users', 'base/addon_3615']
def setUp(self):
self.url = reverse('devhub.addons.profile', args=[3615])
assert self.client.login(username='del@icio.us', password='password')
self.addon = Addon.objects.get(id=3615)
self.version = self.addon.current_version
def get_addon(self):
return Addon.objects.no_cache().get(id=self.addon.id)
def enable_addon_contributions(self):
self.addon.wants_contributions = True
self.addon.paypal_id = 'somebody'
self.addon.save()
def post(self, *args, **kw):
d = dict(*args, **kw)
eq_(self.client.post(self.url, d).status_code, 302)
def check(self, **kw):
addon = self.get_addon()
for k, v in kw.items():
if k in ('the_reason', 'the_future'):
eq_(getattr(getattr(addon, k), 'localized_string'), unicode(v))
else:
eq_(getattr(addon, k), v)
def test_without_contributions_labels(self):
r = self.client.get(self.url)
doc = pq(r.content)
eq_(doc('label[for=id_the_reason] .optional').length, 1)
eq_(doc('label[for=id_the_future] .optional').length, 1)
def test_without_contributions_fields_optional(self):
self.post(the_reason='', the_future='')
self.check(the_reason='', the_future='')
self.post(the_reason='to be cool', the_future='')
self.check(the_reason='to be cool', the_future='')
self.post(the_reason='', the_future='hot stuff')
self.check(the_reason='', the_future='hot stuff')
self.post(the_reason='to be hot', the_future='cold stuff')
self.check(the_reason='to be hot', the_future='cold stuff')
def test_with_contributions_labels(self):
self.enable_addon_contributions()
r = self.client.get(self.url)
doc = pq(r.content)
assert doc('label[for=id_the_reason] .req').length, \
'the_reason field should be required.'
assert doc('label[for=id_the_future] .req').length, \
'the_future field should be required.'
def test_with_contributions_fields_required(self):
self.enable_addon_contributions()
d = dict(the_reason='', the_future='')
r = self.client.post(self.url, d)
eq_(r.status_code, 200)
self.assertFormError(r, 'profile_form', 'the_reason',
'This field is required.')
self.assertFormError(r, 'profile_form', 'the_future',
'This field is required.')
d = dict(the_reason='to be cool', the_future='')
r = self.client.post(self.url, d)
eq_(r.status_code, 200)
self.assertFormError(r, 'profile_form', 'the_future',
'This field is required.')
d = dict(the_reason='', the_future='hot stuff')
r = self.client.post(self.url, d)
eq_(r.status_code, 200)
self.assertFormError(r, 'profile_form', 'the_reason',
'This field is required.')
self.post(the_reason='to be hot', the_future='cold stuff')
self.check(the_reason='to be hot', the_future='cold stuff')
2010-10-20 21:40:20 +04:00
def initial(form):
"""Gather initial data from the form into a dict."""
data = {}
for name, field in form.fields.items():
if form.is_bound:
data[name] = form[name].data
else:
data[name] = form.initial.get(name, field.initial)
# The browser sends nothing for an unchecked checkbox.
if isinstance(field, forms.BooleanField):
val = field.to_python(data[name])
if not val:
del data[name]
return data
class TestVersionEdit(test_utils.TestCase):
2010-10-20 21:40:20 +04:00
fixtures = ['base/apps', 'base/users', 'base/addon_3615',
'base/thunderbird']
def setUp(self):
assert self.client.login(username='del@icio.us', password='password')
self.addon = self.get_addon()
self.version = self.get_version()
self.url = reverse('devhub.versions.edit',
args=[3615, self.version.id])
2010-10-20 21:40:20 +04:00
self.v1 = AppVersion(application_id=amo.FIREFOX.id, version='1.0')
self.v4 = AppVersion(application_id=amo.FIREFOX.id, version='4.0')
for v in self.v1, self.v4:
v.save()
def get_addon(self):
return Addon.objects.no_cache().get(id=3615)
def get_version(self):
return self.get_addon().current_version
2010-10-20 21:40:20 +04:00
def formset(self, *args, **kw):
defaults = {'approvalnotes': 'xxx'}
defaults.update(kw)
return formset(*args, **defaults)
def test_edit_notes(self):
2010-10-20 21:40:20 +04:00
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
d = formset(initial(f), releasenotes='xx', approvalnotes='yy',
initial_count=1)
r = self.client.post(self.url, d)
eq_(r.status_code, 302)
version = self.get_version()
eq_(unicode(version.releasenotes), 'xx')
eq_(unicode(version.approvalnotes), 'yy')
2010-10-20 21:40:20 +04:00
def test_add_appversion(self):
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
d = self.formset(initial(f), dict(application=18, min=28, max=29),
initial_count=1)
r = self.client.post(self.url, d)
eq_(r.status_code, 302)
apps = self.get_version().compatible_apps.keys()
eq_(apps, [amo.FIREFOX, amo.THUNDERBIRD])
def test_update_appversion(self):
av = self.version.apps.get()
eq_(av.min.version, '2.0')
eq_(av.max.version, '3.7a1pre')
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
d = initial(f)
d.update(min=self.v1.id, max=self.v4.id)
r = self.client.post(self.url,
self.formset(d, initial_count=1))
eq_(r.status_code, 302)
av = self.version.apps.get()
eq_(av.min.version, '1.0')
eq_(av.max.version, '4.0')
def test_delete_appversion(self):
# Add thunderbird compat so we can delete firefox.
self.test_add_appversion()
f = self.client.get(self.url).context['compat_form']
d = map(initial, f.initial_forms)
d[0]['DELETE'] = True
r = self.client.post(self.url, self.formset(*d, initial_count=2))
eq_(r.status_code, 302)
apps = self.get_version().compatible_apps.keys()
eq_(apps, [amo.THUNDERBIRD])
def test_unique_apps(self):
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
dupe = initial(f)
del dupe['id']
d = self.formset(initial(f), dupe, initial_count=1)
r = self.client.post(self.url, d)
eq_(r.status_code, 200)
# Because of how formsets work, the second form is expected to be a
# tbird version range. We got an error, so we're good.
def test_require_appversion(self):
old_av = self.version.apps.get()
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
d = initial(f)
d['DELETE'] = True
r = self.client.post(self.url, self.formset(d, initial_count=1))
eq_(r.status_code, 200)
eq_(self.version.apps.get(), old_av)
def test_proper_min_max(self):
f = self.client.get(self.url).context['compat_form'].initial_forms[0]
d = initial(f)
d['min'], d['max'] = d['max'], d['min']
r = self.client.post(self.url, self.formset(d, initial_count=1))
eq_(r.status_code, 200)
eq_(r.context['compat_form'].forms[0].non_field_errors(),
['Invalid version range'])