class Featured(forms.Form): CHOICES = ('android', 'desktop', 'firefoxos') dev = forms.ChoiceField(choices=[(c, c) for c in CHOICES], required=False) limit = forms.IntegerField(max_value=20, min_value=1, required=False) category = SluggableModelChoiceField(queryset=Category.objects.all(), sluggable_to_field_name='slug', required=False) region = forms.ChoiceField(choices=list(regions.REGIONS_DICT.items()), required=False) def __init__(self, data, region=None, **kw): data = data.copy() data['region'] = region super(Featured, self).__init__(data, **kw) def as_featured(self): device = self.cleaned_data['dev'] return { 'region': regions.REGIONS_DICT.get(self.cleaned_data['region'], regions.WORLDWIDE), 'mobile': device in ['android', 'firefoxos'], 'tablet': device == 'android', 'gaia': device == 'firefoxos', 'cat': self.cleaned_data['category'] }
class PaymentCheckForm(happyforms.Form): app = SluggableModelChoiceField(queryset=Addon.objects.filter( premium_type__in=amo.ADDON_HAS_PAYMENTS, type=amo.ADDON_WEBAPP), sluggable_to_field_name='app_slug') def clean_app(self): app = self.cleaned_data['app'] if not app.has_payment_account(): raise ValidationError(_('No payment account set up for that app')) return app
class CreateCommThreadForm(CreateCommNoteForm): app = SluggableModelChoiceField(queryset=Webapp.objects.all(), sluggable_to_field_name='app_slug') version = forms.CharField() def clean_version(self): version_num = self.cleaned_data['version'] versions = self.cleaned_data['app'].versions.filter( version=version_num).order_by('-created') if versions.exists(): return versions[0] raise forms.ValidationError( _('Version %s does not exist' % version_num))
class InstallForm(happyforms.Form): app = SluggableModelChoiceField(queryset=Webapp.objects.all(), sluggable_to_field_name='app_slug') def __init__(self, *args, **kwargs): self.request = kwargs.pop('request') super(InstallForm, self).__init__(*args, **kwargs) def clean_app(self): app = self.cleaned_data['app'] if app.is_premium(): raise forms.ValidationError('Use the receipt API for paid apps.') return app
class TestSluggableChoiceField(amo.tests.TestCase): def setUp(self): self.fld = SluggableModelChoiceField(mock.Mock(), sluggable_to_field_name='foo') def test_nope(self): with self.assertRaises(ValueError): SluggableModelChoiceField() def test_slug(self): self.fld.to_python(value='asd') ok_(self.fld.to_field_name, 'foo') def test_pk(self): self.fld.to_python(value='1') ok_(self.fld.to_field_name is None) def test_else(self): self.fld.to_python(value=None) ok_(self.fld.to_field_name is None)
class AppSlugForm(happyforms.Form): app = SluggableModelChoiceField(queryset=Webapp.objects.all(), sluggable_to_field_name='app_slug')
def setUp(self): self.fld = SluggableModelChoiceField(mock.Mock(), sluggable_to_field_name='foo')
class AppAbuseForm(AbuseForm): app = SluggableModelChoiceField(queryset=Webapp.objects.all(), sluggable_to_field_name='app_slug')
def test_nope(self): with self.assertRaises(ValueError): SluggableModelChoiceField()
class UnCCForm(happyforms.Form): pk = SluggableModelChoiceField(queryset=CommunicationThread.objects.all(), sluggable_to_field_name='id')
class PrepareWebAppForm(happyforms.Form): app = SluggableModelChoiceField(queryset=Webapp.objects.valid(), sluggable_to_field_name='app_slug')
class ExtensionSlugForm(happyforms.Form): extension = SluggableModelChoiceField(queryset=Extension.objects.all(), sluggable_to_field_name='slug')
class ApiSearchForm(forms.Form): q = forms.CharField(required=False, label=_lazy(u'Search'), widget=forms.TextInput(attrs={ 'autocomplete': 'off', 'placeholder': _lazy(u'Search') })) type = forms.ChoiceField(required=False, choices=ADDON_CHOICES, label=_lazy(u'Add-on type')) status = forms.ChoiceField(required=False, choices=STATUS_CHOICES, label=_lazy(u'Status')) cat = SluggableModelChoiceField(queryset=Category.objects.all(), sluggable_to_field_name='slug', required=False) device = forms.ChoiceField(required=False, choices=DEVICE_CHOICES, label=_lazy(u'Device type')) premium_types = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple(), required=False, label=_lazy(u'Premium types'), choices=PREMIUM_CHOICES) app_type = forms.ChoiceField(required=False, label=_lazy(u'App type'), choices=APP_TYPE_CHOICES) sort = forms.ChoiceField(required=False, choices=LISTING_SORT_CHOICES) # TODO: Drop this back to a reasonable value when we do pagination. limit = forms.IntegerField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kw): super(ApiSearchForm, self).__init__(*args, **kw) CATS = (Category.objects.filter(type=amo.ADDON_WEBAPP, weight__gte=0).values_list('id', flat=True)) self.fields['cat'].choices = [(pk, pk) for pk in CATS] self.initial.update({ 'type': 'app', 'status': 'pending', 'limit': 200, }) def clean_cat(self): if self.cleaned_data['cat']: return self.cleaned_data['cat'].pk def clean_type(self): return amo.MKT_ADDON_TYPES_API_LOOKUP.get(self.cleaned_data['type'], amo.ADDON_WEBAPP) def clean_status(self): status = self.cleaned_data['status'] if status == 'any': return 'any' return amo.STATUS_CHOICES_API_LOOKUP.get(status, amo.STATUS_PUBLIC) def clean_premium_types(self): pt_ids = [] for pt in self.cleaned_data.get('premium_types'): pt_id = amo.ADDON_PREMIUM_API_LOOKUP.get(pt) if pt_id is not None: pt_ids.append(pt_id) if pt_ids: return pt_ids return [] def clean_app_type(self): app_type = amo.ADDON_WEBAPP_TYPES_LOOKUP.get( self.cleaned_data.get('app_type')) if app_type: return app_type
class ApiSearchForm(forms.Form): q = forms.CharField(required=False, label=_lazy(u'Search'), widget=forms.TextInput(attrs={ 'autocomplete': 'off', 'placeholder': _lazy(u'Search') })) type = forms.ChoiceField(required=False, choices=ADDON_CHOICES, label=_lazy(u'Add-on type')) cat = SluggableModelChoiceField( queryset=Category.objects.filter(type=amo.ADDON_WEBAPP), sluggable_to_field_name='slug', required=False) device = forms.ChoiceField(required=False, choices=DEVICE_CHOICES, label=_lazy(u'Device type')) premium_types = forms.MultipleChoiceField( widget=forms.CheckboxSelectMultiple(), required=False, label=_lazy(u'Premium types'), choices=PREMIUM_CHOICES) # TODO: Make some fancy `MultipleCommaSeperatedChoiceField` field. app_type = forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple(), label=_lazy(u'App type'), choices=APP_TYPE_CHOICES) manifest_url = forms.CharField(required=False, label=_lazy('Manifest URL')) languages = forms.CharField(required=False, label=_lazy('Supported languages')) sort = forms.MultipleChoiceField(required=False, choices=LISTING_SORT_CHOICES) # TODO: Drop this back to a reasonable value when we do pagination. limit = forms.IntegerField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kw): super(ApiSearchForm, self).__init__(*args, **kw) # Clients understand cats via slugs, Zamboni thinks of them via IDs. self.fields['cat'].choices = (Category.objects.filter( type=amo.ADDON_WEBAPP, weight__gte=0).values_list('slug', 'id')) self.initial.update({ 'type': 'app', 'status': 'pending', 'limit': 200, }) def clean_cat(self): if self.cleaned_data['cat']: return self.cleaned_data['cat'].slug def clean_type(self): return amo.MKT_ADDON_TYPES_API.get(self.cleaned_data['type'], amo.ADDON_WEBAPP) def clean_premium_types(self): """After cleaned, return a list of ints for the constants.""" pt_ids = [] for pt in self.cleaned_data.get('premium_types'): pt_id = amo.ADDON_PREMIUM_API_LOOKUP.get(pt) if pt_id is not None: pt_ids.append(pt_id) return pt_ids def clean_app_type(self): """After cleaned, return a list of ints for the constants.""" at_ids = [] for at in self.cleaned_data.get('app_type'): at_id = amo.ADDON_WEBAPP_TYPES_LOOKUP.get(at) if at_id is not None: at_ids.append(at_id) return at_ids
class ReceiptForm(forms.Form): app = SluggableModelChoiceField( queryset=Addon.objects.filter(type=amo.ADDON_WEBAPP), sluggable_to_field_name='app_slug')