This commit is contained in:
Andy McKay 2013-04-02 13:40:43 -07:00
Родитель ae7701691b
Коммит a61aa9eff4
5 изменённых файлов: 66 добавлений и 11 удалений

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

@ -50,7 +50,7 @@ A list of the featured apps on the Marketplace.
GET /api/v1/home/featured/
:param dev: the device requesting the homepage, results will be tailored to the device which will be one of: `firefoxos` (Firefox OS), `desktop`, `android` (mobile).
:param category: the id of the category to filter on.
:param category: the id or slug of the category to filter on.
:param limit: the number of responses.
**Response**

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

@ -83,6 +83,28 @@ class JSONField(forms.Field):
return value
class SluggableModelChoiceField(forms.ModelChoiceField):
"""
A model choice field that can accept either a slug or a pk and adapts
itself based on that. Requries: `sluggable_to_field_name` to be set as
the field that we will base the slug on.
"""
def __init__(self, *args, **kw):
if 'sluggable_to_field_name' not in kw:
raise ValueError('sluggable_to_field_name is required.')
self.sluggable_to_field_name = kw.pop('sluggable_to_field_name')
return super(SluggableModelChoiceField, self).__init__(*args, **kw)
def to_python(self, value):
try:
if not value.isdigit():
self.to_field_name = self.sluggable_to_field_name
except AttributeError:
pass
return super(SluggableModelChoiceField, self).to_python(value)
def parse(file_, require_name=False, require_type=None):
try:
if not set(['data', 'type']).issubset(set(file_.keys())):

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

@ -1,11 +1,13 @@
import base64
from nose.tools import eq_
import mock
from nose.tools import eq_, ok_
from addons.models import Addon
import amo
import amo.tests
from mkt.api.forms import PreviewJSONForm, StatusForm
from mkt.api.forms import (PreviewJSONForm, SluggableModelChoiceField,
StatusForm)
class TestPreviewForm(amo.tests.TestCase, amo.tests.AMOPaths):
@ -73,3 +75,26 @@ class TestSubmitForm(amo.tests.TestCase):
self.addon.status = s
status = StatusForm(instance=self.addon).fields['status']
eq_([k for k, v in status.choices], [k])
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)

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

@ -2,16 +2,17 @@ from django import forms
from addons.models import Category
from mkt import regions
from mkt.api.forms import SluggableModelChoiceField
class Featured(forms.Form):
CHOICES = ('android', 'desktop', 'firefoxos')
dev = forms.ChoiceField(choices=[(c, c) for c in CHOICES],
required=False)
dev = forms.ChoiceField(choices=[(c, c) for c in CHOICES], required=False)
limit = forms.IntegerField(max_value=20, min_value=1, required=False)
category = forms.ModelChoiceField(queryset=Category.objects.all(),
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)

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

@ -18,7 +18,7 @@ from mkt.zadmin.models import FeaturedApp, FeaturedAppRegion
class TestForm(amo.tests.TestCase):
def lookup(self, region, device):
form = Featured({'device': device}, region=region)
form = Featured({'dev': device}, region=region)
ok_(form.is_valid(), form.errors)
return form.as_featured()
@ -71,7 +71,8 @@ class TestFeaturedHomeHandler(BaseOAuth):
super(TestFeaturedHomeHandler, self).setUp(api_name='home')
self.list_url = list_url('featured')
self.cat = Category.objects.create(name='awesome',
type=amo.ADDON_WEBAPP)
type=amo.ADDON_WEBAPP,
slug='awesome')
# App, no category, worldwide region.
self.app1 = Webapp.objects.create(status=amo.STATUS_PUBLIC,
@ -124,10 +125,16 @@ class TestFeaturedHomeHandler(BaseOAuth):
self.assertSetEqual([o['slug'] for o in data['objects']],
['app-1', 'app-3'])
def test_get_category(self):
res = self.anon.get(self.list_url, data={'category': self.cat.pk})
def _get_category(self, data):
res = self.anon.get(self.list_url, data=data)
data = json.loads(res.content)
eq_(res.status_code, 200)
eq_(data['meta']['total_count'], 1)
# App2 is in the category.
eq_(data['objects'][0]['slug'], self.app2.app_slug)
def test_get_category(self):
self._get_category({'category': self.cat.pk})
def test_get_slug(self):
self._get_category({'category': self.cat.slug})