From e71391eebfa918eb6ccd08740e1de745fda34575 Mon Sep 17 00:00:00 2001 From: Aleksey Stryukov Date: Mon, 24 Sep 2018 09:48:21 +0300 Subject: [PATCH] Remove docs include option --- src/openprocurement/api/tests/utils.py | 110 +++++++++++++++++++++++++ src/openprocurement/api/utils.py | 27 +++--- 2 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 src/openprocurement/api/tests/utils.py diff --git a/src/openprocurement/api/tests/utils.py b/src/openprocurement/api/tests/utils.py new file mode 100644 index 0000000000..483511bca2 --- /dev/null +++ b/src/openprocurement/api/tests/utils.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +from openprocurement.api.tests.base import BaseWebTest +from openprocurement.api.utils import APIResourceListing +from pyramid.testing import DummyRequest, testConfig +from mock import Mock + + +class ItemsListing(APIResourceListing): + def __init__(self, request, context): + super(ItemsListing, self).__init__(request, context) + + results = ( + Mock( + key=k, + value={ + "status": "active", + "title": "title#%d" % k, + "description": "description#%d" % k, + "bids": [1, k] + } + ) for k in range(5) + ) + + self.view_mock = Mock(return_value=results) + self.test_view_mock = Mock(return_value=results) + self.changes_view_mock = Mock(return_value=results) + self.test_changes_view_mock = Mock(return_value=results) + self.VIEW_MAP = { + u'': self.view_mock, + u'test': self.test_view_mock, + } + self.CHANGES_VIEW_MAP = { + u'': self.changes_view_mock, + u'test': self.test_changes_view_mock, + } + self.FEED = { + u'dateModified': self.VIEW_MAP, + u'changes': self.CHANGES_VIEW_MAP, + } + self.FIELDS = ('id', 'status', 'title', 'description') + + def item_serialize(_, data, fields): + return {i: j for i, j in data.items() if i in fields} + + self.serialize_func = item_serialize + self.object_name_for_listing = 'health' + self.log_message_id = 'items_list_custom' + + +class ResourceListingTestCase(BaseWebTest): + + def setUp(self): + super(ResourceListingTestCase, self).setUp() + + self.request = DummyRequest() + self.request.logging_context = {} + self.request._registry = self.app.app.registry + self.listing = ItemsListing(self.request, {}) + + def get_listing(self): + return self.listing.get() + + def test_get_listing(self): + self.get_listing() + self.listing.view_mock.assert_called_once_with( + self.db, + startkey='', stale='update_after', descending=False, limit=100 + ) + + def test_get_test_listing(self): + self.request.params = {"opt_fields": "id,status", "mode": "test"} + self.get_listing() + self.listing.test_view_mock.assert_called_once_with( + self.db, + startkey='', stale='update_after', descending=False, limit=100 + ) + + def test_get_changes_listing(self): + self.request.params = {"opt_fields": "id,status", "feed": "changes"} + self.get_listing() + self.listing.changes_view_mock.assert_called_once_with( + self.db, + startkey=0, stale='update_after', descending=False, limit=100 + ) + + def test_get_test_changes_listing(self): + self.request.params = {"opt_fields": "id,status", "feed": "changes", "mode": "test"} + self.get_listing() + self.listing.test_changes_view_mock.assert_called_once_with( + self.db, + startkey=0, stale='update_after', descending=False, limit=100 + ) + + def test_get_listing_opt_fields_subset(self): + self.request.params = {"opt_fields": "id,status"} + self.get_listing() + self.listing.view_mock.assert_called_once_with( + self.db, + startkey='', stale='update_after', descending=False, limit=100 + ) + + def test_get_listing_opt_fields_not_subset(self): + self.request.params = {"opt_fields": "id,status,title,description,bids"} + data = self.get_listing() + self.listing.view_mock.assert_called_once_with( + self.db, + startkey='', stale='update_after', descending=False, limit=100 + ) + self.assertEqual(len(data["data"]), 5) + self.assertEqual(set(data["data"][0].keys()), {"id", "status", "title", "description", "dateModified"}) diff --git a/src/openprocurement/api/utils.py b/src/openprocurement/api/utils.py index fc5bdfbf1b..d9b9460ba5 100644 --- a/src/openprocurement/api/utils.py +++ b/src/openprocurement/api/utils.py @@ -391,6 +391,8 @@ def __init__(self, request, context): class APIResourceListing(APIResource): + LIST_SEP = "," + def __init__(self, request, context): super(APIResourceListing, self).__init__(request, context) self.server = request.registry.couchdb_server @@ -402,10 +404,8 @@ def get(self): pparams = {} fields = self.request.params.get('opt_fields', '') if fields: - params['opt_fields'] = fields - pparams['opt_fields'] = fields - fields = fields.split(',') - view_fields = fields + ['dateModified', 'id'] + fields = set(fields.split(self.LIST_SEP)) & set(self.FIELDS) + limit = self.request.params.get('limit', '') if limit: params['limit'] = limit @@ -450,23 +450,18 @@ def get(self): else: view = partial(list_view, self.db, limit=view_limit, startkey=view_offset, descending=descending) if fields: - if not changes and set(fields).issubset(set(self.FIELDS)): - results = [ - (dict([(i, j) for i, j in x.value.items() + [('id', x.id), ('dateModified', x.key)] if i in view_fields]), x.key) - for x in view() - ] - elif changes and set(fields).issubset(set(self.FIELDS)): + params['opt_fields'] = pparams['opt_fields'] = self.LIST_SEP.join(fields) + view_fields = fields | {'dateModified', 'id'} + if changes: results = [ (dict([(i, j) for i, j in x.value.items() + [('id', x.id)] if i in view_fields]), x.key) for x in view() ] - elif fields: - self.LOGGER.info('Used custom fields for {} list: {}'.format(self.object_name_for_listing, ','.join(sorted(fields))), - extra=context_unpack(self.request, {'MESSAGE_ID': self.log_message_id})) - + else: results = [ - (self.serialize_func(self.request, i[u'doc'], view_fields), i.key) - for i in view(include_docs=True) + (dict([(i, j) for i, j in x.value.items() + [('id', x.id), ('dateModified', x.key)] if + i in view_fields]), x.key) + for x in view() ] else: results = [