Skip to content
This repository was archived by the owner on Mar 15, 2018. It is now read-only.

Commit fbdba00

Browse files
author
Rob Hudson
committed
Remove ability to edit name on app submission flow (bug 824734)
1 parent 654ece7 commit fbdba00

4 files changed

Lines changed: 109 additions & 76 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[
2+
{
3+
"pk": 10482,
4+
"model": "auth.user",
5+
"fields": {
6+
"username": "clouserw@gmail.com",
7+
"first_name": "Wil",
8+
"last_name": "Clouser",
9+
"is_active": 1,
10+
"is_superuser": 1,
11+
"is_staff": 1,
12+
"last_login": "2010-04-23 10:33:53",
13+
"groups": [],
14+
"user_permissions": [],
15+
"password": "sha1$a04e0$0512298efb3e6e7dbace3976474151d396078fdd",
16+
"email": "clouserw@gmail.com",
17+
"date_joined": "2007-03-05 13:09:38"
18+
}
19+
},
20+
{
21+
"pk": 10482,
22+
"model": "users.userprofile",
23+
"fields": {
24+
"display_collections_fav": 1,
25+
"display_collections": 1,
26+
"averagerating": "3.39",
27+
"confirmationcode": "",
28+
"notifycompat": 1,
29+
"picture_type": "image/jpeg",
30+
"occupation": "Internets",
31+
"homepage": "http://micropipes.com/blog/",
32+
"email": "clouserw@gmail.com",
33+
"location": "Portland, OR",
34+
"bio": 480997,
35+
"deleted": 0,
36+
"emailhidden": 0,
37+
"user": 10482,
38+
"password": "sha512$7b5436061f8c0902088c292c057be69fdb17312e2f71607c9c51641f5d876522$08d1d370d89e2ae92755fd03464a7276ca607c431d04a52d659f7a184f3f9918073637d82fc88981c7099c7c46a1137b9fdeb675304eb98801038905a9ee0600",
39+
"username": "clouserw",
40+
"display_name": "clouserw \u0627\u0644\u062a\u0637\u0628",
41+
"resetcode_expires": "2010-01-01 00:00:00",
42+
"resetcode": "",
43+
"created": "2007-03-05 13:09:38",
44+
"notes": "",
45+
"modified": "2010-03-19 13:50:38",
46+
"notifyevents": 1,
47+
"read_dev_agreement": "2012-08-20 00:00:00"
48+
}
49+
}
50+
]

mkt/submit/forms.py

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@
77
from tower import ugettext as _, ugettext_lazy as _lazy
88

99
import amo
10-
from addons.forms import AddonFormBasic
11-
from addons.models import Addon, AddonDeviceType, AddonUpsell
12-
from apps.users.notifications import app_surveys
10+
from addons.models import Addon, AddonUpsell, BlacklistedSlug
11+
from amo.utils import slug_validator
1312
from apps.users.models import UserNotification
13+
from apps.users.notifications import app_surveys
1414
from editors.models import RereviewQueue
1515
from files.models import FileUpload
1616
from files.utils import parse_addon
1717
from market.models import AddonPremium, Price
18-
from translations.widgets import TransInput, TransTextarea
1918
from translations.fields import TransField
19+
from translations.forms import TranslationFormMixin
20+
from translations.widgets import TransInput, TransTextarea
2021

21-
from mkt.constants import DEVICE_LOOKUP, FREE_PLATFORMS, PAID_PLATFORMS
22+
from mkt.constants import FREE_PLATFORMS, PAID_PLATFORMS
2223
from mkt.site.forms import AddonChoiceField, APP_PUBLIC_CHOICES
2324

2425

@@ -309,11 +310,14 @@ def save(self):
309310
self.addon.update(make_public=self.cleaned_data['make_public'])
310311

311312

312-
class AppDetailsBasicForm(AddonFormBasic):
313+
class AppDetailsBasicForm(TranslationFormMixin, happyforms.ModelForm):
314+
315+
def __init__(self, *args, **kw):
316+
self.request = kw.pop('request')
317+
super(AppDetailsBasicForm, self).__init__(*args, **kw)
318+
313319
"""Form for "Details" submission step."""
314-
name = TransField(max_length=128,
315-
widget=TransInput(attrs={'class': 'name l'}))
316-
slug = forms.CharField(max_length=30,
320+
app_slug = forms.CharField(max_length=30,
317321
widget=forms.TextInput(attrs={'class': 'm'}))
318322
summary = TransField(max_length=250,
319323
label=_lazy(u"Brief Summary:"),
@@ -325,10 +329,10 @@ class AppDetailsBasicForm(AddonFormBasic):
325329
help_text=_lazy(u'This description will appear on the details page.'),
326330
widget=TransTextarea(attrs={'rows': 4}))
327331
privacy_policy = TransField(widget=TransTextarea(attrs={'rows': 6}),
328-
label=_lazy(u'Privacy Policy:'),
329-
help_text=_lazy(u"A privacy policy that explains what "
330-
"data is transmitted from a user's computer and how "
331-
"it is used is required."))
332+
label=_lazy(u'Privacy Policy:'),
333+
help_text=_lazy(u"A privacy policy that explains what "
334+
"data is transmitted from a user's computer and how "
335+
"it is used is required."))
332336
homepage = TransField.adapt(forms.URLField)(required=False,
333337
verify_exists=False, label=_lazy(u'Homepage:'),
334338
help_text=_lazy(u'If your app has another homepage, enter its address '
@@ -364,13 +368,30 @@ class AppDetailsBasicForm(AddonFormBasic):
364368

365369
class Meta:
366370
model = Addon
367-
fields = ('flash', 'name', 'slug', 'summary', 'tags', 'description',
368-
'privacy_policy', 'homepage', 'support_url', 'support_email')
371+
fields = ('app_slug', 'summary', 'description', 'privacy_policy',
372+
'homepage', 'support_url', 'support_email')
373+
374+
def clean_app_slug(self):
375+
slug_field = 'app_slug'
376+
target = self.cleaned_data[slug_field]
377+
slug_validator(target, lower=False)
378+
379+
if target != getattr(self.instance, slug_field):
380+
if Addon.objects.filter(**{slug_field: target}).exists():
381+
raise forms.ValidationError(_('This slug is already in use.'))
382+
383+
if BlacklistedSlug.blocked(target):
384+
raise forms.ValidationError(
385+
_('The slug cannot be %s.' % target))
386+
return target
369387

370388
def save(self, *args, **kw):
371389
uses_flash = self.cleaned_data.get('flash')
372390
af = self.instance.get_latest_file()
373391
if af is not None:
374392
af.update(uses_flash=bool(uses_flash))
375393

376-
return super(AppDetailsBasicForm, self).save(*args, **kw)
394+
form = super(AppDetailsBasicForm, self).save(commit=False)
395+
form.save()
396+
397+
return form

mkt/submit/templates/submit/details.html

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ <h2>{{ title }}</h2>
3636
data-upload-url="{{ icon_upload_url }}">
3737
</div>
3838
</div>
39-
<div class="houdini{{ ' ready' if not (form_basic.name.errors or
40-
form_basic.slug.errors) }}">
39+
<div class="houdini{{ ' ready' if not form_basic.app_slug.errors }}">
4140
<div class="before">
4241
<!-- {{ addon.name }} -->
4342
<h2 class="output">{{ addon.name }}</h2>
@@ -50,20 +49,19 @@ <h2 class="output">{{ addon.name }}</h2>
5049
</div>
5150
<div class="after">
5251
<table>
53-
<tr{% if form_basic.name.errors %} class="error"{% endif %}>
52+
<tr>
5453
<th>
55-
<label for="{{ form_basic.name.auto_id }}">
54+
<label>
5655
{{ _('Name') }}
5756
</label>
5857
</th>
5958
<td>
60-
{{ form_basic.name }}
61-
{{ form_basic.name.errors }}
59+
{{ addon.name }}
6260
</td>
6361
</tr>
64-
<tr{% if form_basic.slug.errors %} class="error"{% endif %}>
62+
<tr{% if form_basic.app_slug.errors %} class="error"{% endif %}>
6563
<th>
66-
<label for="{{ form_basic.slug.auto_id }}">
64+
<label for="{{ form_basic.app_slug.auto_id }}">
6765
{{ _('App URL') }}
6866
</label>
6967
{{ tip(None, _('Select a unique URL for your detail page. '
@@ -72,9 +70,9 @@ <h2 class="output">{{ addon.name }}</h2>
7270
</th>
7371
<td>
7472
<div class="edit_with_prefix c">
75-
<span>{{ settings.SITE_URL }}/&hellip;/</span>{{ form_basic.slug }}
73+
<span>{{ settings.SITE_URL }}/&hellip;/</span>{{ form_basic.app_slug }}
7674
</div>
77-
{{ form_basic.slug.errors }}
75+
{{ form_basic.app_slug.errors }}
7876
</td>
7977
</tr>
8078
</table>

mkt/submit/tests/test_views.py

Lines changed: 14 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@
2828
from users.models import UserProfile
2929

3030
import mkt
31+
from mkt.site.fixtures import fixture
3132
from mkt.submit.forms import NewWebappVersionForm
3233
from mkt.submit.models import AppSubmissionChecklist
3334
from mkt.submit.decorators import read_dev_agreement_required
3435
from mkt.webapps.models import AddonExcludedRegion as AER, Webapp
3536

3637

3738
class TestSubmit(amo.tests.TestCase):
38-
fixtures = ['base/users']
39+
fixtures = fixture('user_999')
3940

4041
def setUp(self):
4142
self.user = self.get_user()
@@ -77,7 +78,7 @@ def _test_progress_display(self, completed, current):
7778

7879

7980
class TestProceed(TestSubmit):
80-
fixtures = ['base/users']
81+
fixtures = TestSubmit.fixtures
8182

8283
def setUp(self):
8384
super(TestProceed, self).setUp()
@@ -98,7 +99,7 @@ def test_is_anonymous(self):
9899

99100

100101
class TestTerms(TestSubmit):
101-
fixtures = ['base/users']
102+
fixtures = TestSubmit.fixtures
102103

103104
def setUp(self):
104105
super(TestTerms, self).setUp()
@@ -164,7 +165,7 @@ def test_read_dev_agreement_required(self):
164165

165166

166167
class TestManifest(TestSubmit):
167-
fixtures = ['base/users']
168+
fixtures = TestSubmit.fixtures
168169

169170
def setUp(self):
170171
super(TestManifest, self).setUp()
@@ -216,7 +217,7 @@ def post(self, expect_errors=False, data=None):
216217

217218

218219
class BaseWebAppTest(BaseUploadTest, UploadAddon, amo.tests.TestCase):
219-
fixtures = ['base/apps', 'base/users', 'base/platforms']
220+
fixtures = fixture('app_firefox', 'platform_all', 'user_999', 'user_10482')
220221

221222
def setUp(self):
222223
super(BaseWebAppTest, self).setUp()
@@ -394,8 +395,7 @@ def test_allow_duplicate_domains_from_js(self):
394395

395396

396397
class BasePackagedAppTest(BaseUploadTest, UploadAddon, amo.tests.TestCase):
397-
fixtures = ['base/apps', 'base/users', 'base/platforms',
398-
'webapps/337141-steamcube']
398+
fixtures = fixture('webapp_337141', 'user_999')
399399

400400
def setUp(self):
401401
super(BasePackagedAppTest, self).setUp()
@@ -479,7 +479,7 @@ def test_packaged_app_has_ids_file(self):
479479

480480

481481
class TestDetails(TestSubmit):
482-
fixtures = ['base/apps', 'base/users', 'webapps/337141-steamcube']
482+
fixtures = fixture('webapp_337141', 'user_999', 'user_10482')
483483

484484
def setUp(self):
485485
super(TestDetails, self).setUp()
@@ -570,8 +570,7 @@ def preview_formset(self, *args, **kw):
570570

571571
def get_dict(self, **kw):
572572
data = {
573-
'name': 'Test name',
574-
'slug': 'testname',
573+
'app_slug': 'testname',
575574
'summary': 'Hello!',
576575
'description': 'desc',
577576
'privacy_policy': 'XXX <script>alert("xss")</script>',
@@ -599,7 +598,6 @@ def check_dict(self, data=None, expected=None):
599598

600599
# Build a dictionary of expected results.
601600
expected_data = {
602-
'name': 'Test name',
603601
'app_slug': 'testname',
604602
'summary': 'Hello!',
605603
'description': 'desc',
@@ -711,41 +709,14 @@ def test_icon(self):
711709
for size in amo.ADDON_ICON_SIZES:
712710
fn = '%s-%s.png' % (ad.id, size)
713711
assert os.path.exists(os.path.join(ad.get_icon_dir(), fn)), (
714-
'Expected %s in %s' % (fn, os.listdir(ad.get_icon_dir())))
712+
'Expected %s in %s' % (fn, os.listdir(ad.get_icon_dir())))
715713

716714
def _setup_other_webapp(self):
717715
self._step()
718716
# Generate another webapp to test name uniqueness.
719717
app = amo.tests.addon_factory(type=amo.ADDON_WEBAPP, name='Cool App')
720718
eq_(reverse_name_lookup(app.name, webapp=True), app.id)
721719

722-
def test_name_unique(self):
723-
self._setup_other_webapp()
724-
r = self.client.post(self.url, self.get_dict(name='Cool App'))
725-
error = 'This name is already in use. Please choose another.'
726-
self.assertFormError(r, 'form_basic', 'name', error)
727-
728-
def test_name_unique_strip(self):
729-
# Make sure we can't sneak in a name by adding a space or two.
730-
self._setup_other_webapp()
731-
r = self.client.post(self.url, self.get_dict(name=' Cool App '))
732-
error = 'This name is already in use. Please choose another.'
733-
self.assertFormError(r, 'form_basic', 'name', error)
734-
735-
def test_name_unique_case(self):
736-
# Make sure unique names aren't case sensitive.
737-
self._setup_other_webapp()
738-
r = self.client.post(self.url, self.get_dict(name='cool app'))
739-
error = 'This name is already in use. Please choose another.'
740-
self.assertFormError(r, 'form_basic', 'name', error)
741-
742-
def test_name_required(self):
743-
self._step()
744-
r = self.client.post(self.url, self.get_dict(name=''))
745-
eq_(r.status_code, 200)
746-
self.assertFormError(r, 'form_basic', 'name',
747-
'This field is required.')
748-
749720
def test_screenshot_or_video_required(self):
750721
self._step()
751722
data = self.get_dict()
@@ -775,28 +746,21 @@ def test_unsaved_screenshot(self):
775746
eq_(form.find('input[name=files-0-unsaved_image_data]').val(),
776747
preview_uri)
777748

778-
def test_name_length(self):
779-
self._step()
780-
r = self.client.post(self.url, self.get_dict(name='a' * 129))
781-
eq_(r.status_code, 200)
782-
self.assertFormError(r, 'form_basic', 'name',
783-
'Ensure this value has at most 128 characters (it has 129).')
784-
785749
def test_slug_invalid(self):
786750
self._step()
787751
# Submit an invalid slug.
788-
d = self.get_dict(slug='slug!!! aksl23%%')
752+
d = self.get_dict(app_slug='slug!!! aksl23%%')
789753
r = self.client.post(self.url, d)
790754
eq_(r.status_code, 200)
791-
self.assertFormError(r, 'form_basic', 'slug',
755+
self.assertFormError(r, 'form_basic', 'app_slug',
792756
"Enter a valid 'slug' consisting of letters, numbers, underscores "
793757
"or hyphens.")
794758

795759
def test_slug_required(self):
796760
self._step()
797-
r = self.client.post(self.url, self.get_dict(slug=''))
761+
r = self.client.post(self.url, self.get_dict(app_slug=''))
798762
eq_(r.status_code, 200)
799-
self.assertFormError(r, 'form_basic', 'slug',
763+
self.assertFormError(r, 'form_basic', 'app_slug',
800764
'This field is required.')
801765

802766
def test_summary_required(self):

0 commit comments

Comments
 (0)