Pecan: handle single fields query parameter

This also correctly handles the case where no fields are requested which seems
to have started to break.

Closes-Bug: #1590588
Change-Id: Ida1e3ff575c7fe6c3199c5f4393679bbf89c0fe1
This commit is contained in:
Brandon Logan 2016-06-08 17:08:40 -05:00
parent d72a21ae6f
commit 8a6d22ccb5
3 changed files with 31 additions and 8 deletions

View File

@ -100,7 +100,11 @@ class CollectionsController(utils.NeutronPecanController):
def get(self, *args, **kwargs):
# list request
fields = self._build_field_list(kwargs.pop('fields', []))
fields = kwargs.pop('fields', [])
# if only one fields query parameter is passed, pecan will not put
# that parameter in a list, so we need to convert it into a list
fields = fields if isinstance(fields, list) else [fields]
fields = self._build_field_list(fields)
_listify = lambda x: x if isinstance(x, list) else [x]
filters = api_common.get_filters_from_dict(
{k: _listify(v) for k, v in kwargs.items()},

View File

@ -103,7 +103,9 @@ class NeutronPecanController(object):
self._mandatory_fields = set()
def _build_field_list(self, request_fields):
return set(request_fields) | self._mandatory_fields
if request_fields:
return set(request_fields) | self._mandatory_fields
return []
@property
def plugin(self):

View File

@ -263,14 +263,31 @@ class TestResourceController(TestRootController):
self.assertIn(attribute, item)
self.assertEqual(len(expected), len(item))
def test_get_collection_with_fields_selector(self):
list_resp = self.app.get('/v2.0/ports.json?fields=id&fields=name',
headers={'X-Project-Id': 'tenid'})
def _test_get_collection_with_fields_selector(self, fields=None):
fields = fields or []
query_params = ['fields=%s' % field for field in fields]
url = '/v2.0/ports.json'
if query_params:
url = '%s?%s' % (url, '&'.join(query_params))
list_resp = self.app.get(url, headers={'X-Project-Id': 'tenid'})
self.assertEqual(200, list_resp.status_int)
for item in jsonutils.loads(list_resp.body).get('ports', []):
self.assertIn('id', item)
self.assertIn('name', item)
self.assertEqual(2, len(item))
for field in fields:
self.assertIn(field, item)
if fields:
self.assertEqual(len(fields), len(item))
else:
for field in ('id', 'name', 'device_owner'):
self.assertIn(field, item)
def test_get_collection_with_multiple_fields_selector(self):
self._test_get_collection_with_fields_selector(fields=['id', 'name'])
def test_get_collection_with_single_fields_selector(self):
self._test_get_collection_with_fields_selector(fields=['name'])
def test_get_collection_without_fields_selector(self):
self._test_get_collection_with_fields_selector(fields=[])
def test_get_item_with_fields_selector(self):
item_resp = self.app.get(