From 8a6d22ccb53f14a26876a06152b7a3b47ae1a8e1 Mon Sep 17 00:00:00 2001 From: Brandon Logan Date: Wed, 8 Jun 2016 17:08:40 -0500 Subject: [PATCH] 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 --- neutron/pecan_wsgi/controllers/resource.py | 6 +++- neutron/pecan_wsgi/controllers/utils.py | 4 ++- .../functional/pecan_wsgi/test_controllers.py | 29 +++++++++++++++---- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/neutron/pecan_wsgi/controllers/resource.py b/neutron/pecan_wsgi/controllers/resource.py index 20b287bd5c6..c3ab68b504c 100644 --- a/neutron/pecan_wsgi/controllers/resource.py +++ b/neutron/pecan_wsgi/controllers/resource.py @@ -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()}, diff --git a/neutron/pecan_wsgi/controllers/utils.py b/neutron/pecan_wsgi/controllers/utils.py index 70b690f8c14..6ee19e3ea04 100644 --- a/neutron/pecan_wsgi/controllers/utils.py +++ b/neutron/pecan_wsgi/controllers/utils.py @@ -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): diff --git a/neutron/tests/functional/pecan_wsgi/test_controllers.py b/neutron/tests/functional/pecan_wsgi/test_controllers.py index 3a02e303adb..2f083103d6b 100644 --- a/neutron/tests/functional/pecan_wsgi/test_controllers.py +++ b/neutron/tests/functional/pecan_wsgi/test_controllers.py @@ -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(