From 793decf9d3946f155c45635a8d68601ef331adc7 Mon Sep 17 00:00:00 2001 From: vladkhard Date: Wed, 16 Jan 2019 15:46:53 +0200 Subject: [PATCH 1/4] add get_resource_item_historical method --- openprocurement_client/clients.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openprocurement_client/clients.py b/openprocurement_client/clients.py index 4478d3d..57d02d5 100755 --- a/openprocurement_client/clients.py +++ b/openprocurement_client/clients.py @@ -87,7 +87,10 @@ def _get_resource_item(self, url, headers=None): _headers.update(headers or {}) response_item = self.request('GET', url, headers=_headers) if response_item.status_code == 200: - return munchify(loads(response_item.text)) + data = loads(response_item.text) + if "x-revision-n" in response_item.headers: + data["x_revision_n"] = response_item.headers["x-revision-n"] + return munchify(data) raise InvalidResponse(response_item) @retry(stop_max_attempt_number=5) @@ -177,6 +180,12 @@ def get_resource_item(self, id, headers=None): "from 'openprocurement_client.clients'.") return self._get_resource_item('{}/{}'.format(self.prefix_path, id), headers=headers) + def get_resource_item_historical(self, id, revision="", headers=None): + if headers is None: + headers = {} + headers["x-revision-n"] = str(revision) + return self._get_resource_item('{}/{}/historical'.format(self.prefix_path, id), headers=headers) + def patch_credentials(self, id, access_token): LOGGER.warn("'pat' method is deprecated use APIResoucreClient.pat from " "from 'openprocurement_client.clients'.") From 2c8f6da0ded023aa70cf0afc2979284b16d0eddd Mon Sep 17 00:00:00 2001 From: vladkhard Date: Wed, 16 Jan 2019 15:47:35 +0200 Subject: [PATCH 2/4] add unittests for get_resource_item_historical method --- openprocurement_client/tests/main.py | 4 +- .../tests/test_api_base_client.py | 65 +++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 openprocurement_client/tests/test_api_base_client.py diff --git a/openprocurement_client/tests/main.py b/openprocurement_client/tests/main.py index a6e892f..dc83d2d 100644 --- a/openprocurement_client/tests/main.py +++ b/openprocurement_client/tests/main.py @@ -3,7 +3,8 @@ from openprocurement_client.tests import ( tests_resources, tests_sync, - test_registry_client + test_registry_client, + test_api_base_client ) @@ -12,6 +13,7 @@ def suite(): suite.addTest(tests_sync.suite()) suite.addTest(test_registry_client.suite()) suite.addTest(tests_resources.suite()) + suite.addTest(test_api_base_client.suite()) return suite diff --git a/openprocurement_client/tests/test_api_base_client.py b/openprocurement_client/tests/test_api_base_client.py new file mode 100644 index 0000000..7765317 --- /dev/null +++ b/openprocurement_client/tests/test_api_base_client.py @@ -0,0 +1,65 @@ +import unittest +import uuid +import mock +from json import dumps +from copy import deepcopy + +from openprocurement_client.exceptions import InvalidResponse +from test_registry_client import BaseTestClass +from openprocurement_client.clients import APIBaseClient + + +class APIBaseClientTestCase(BaseTestClass): + def setUp(self): + self.setting_up(client=APIBaseClient) + + def test_get_resource_item_historical(self): + class Response(object): + def __init__(self, status_code, text=None, headers=None): + self.status_code = status_code + self.text = text + self.headers = headers + + revisions_limit = 42 + response_text = { + "id": uuid.uuid4().hex, + "rev": 24 + } + + side_effect = [ + Response(200, dumps(response_text), {"x-revision-n": str(revisions_limit)}), + Response(200, dumps(response_text), {"x-revision-n": str(revisions_limit)}), + Response(200, dumps(response_text), {"x-revision-n": str(revisions_limit - 1)}), + Response(404), + Response(404), + Response(404), + ] + + self.client.request = mock.MagicMock(side_effect=side_effect) + + actual_response = deepcopy(response_text) + actual_response["x_revision_n"] = str(revisions_limit) + item_id = response_text["id"] + self.assertEqual(self.client.get_resource_item_historical(item_id, revision=""), actual_response) + self.assertEqual(self.client.get_resource_item_historical(item_id, revision=revisions_limit), actual_response) + actual_response["x_revision_n"] = str(revisions_limit - 1) + self.assertEqual(self.client.get_resource_item_historical( + item_id, revision=revisions_limit - 1), actual_response) + + for revision in (0, revisions_limit + 1, None): + with self.assertRaises(InvalidResponse) as e: + self.client.get_resource_item_historical(item_id, revision=revision) + self.assertEqual(e.exception.status_code, 404) + + def tearDown(self): + self.server.stop() + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(APIBaseClientTestCase)) + return suite + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') From 37e47cd64a1fd0de5969ff70ca39394cd60e3442 Mon Sep 17 00:00:00 2001 From: vladkhard Date: Mon, 11 Feb 2019 12:17:39 +0200 Subject: [PATCH 3/4] add x-revision-date header --- openprocurement_client/clients.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openprocurement_client/clients.py b/openprocurement_client/clients.py index 57d02d5..79c7a6d 100755 --- a/openprocurement_client/clients.py +++ b/openprocurement_client/clients.py @@ -88,8 +88,11 @@ def _get_resource_item(self, url, headers=None): response_item = self.request('GET', url, headers=_headers) if response_item.status_code == 200: data = loads(response_item.text) - if "x-revision-n" in response_item.headers: - data["x_revision_n"] = response_item.headers["x-revision-n"] + if isinstance(response_item.headers, dict): + if "x-revision-n" in response_item.headers: + data["x_revision_n"] = response_item.headers["x-revision-n"] + if "x-revision-date" in response_item.headers: + data["x_revision_date"] = response_item.headers["x-revision-date"] return munchify(data) raise InvalidResponse(response_item) @@ -180,10 +183,11 @@ def get_resource_item(self, id, headers=None): "from 'openprocurement_client.clients'.") return self._get_resource_item('{}/{}'.format(self.prefix_path, id), headers=headers) - def get_resource_item_historical(self, id, revision="", headers=None): + def get_resource_item_historical(self, id, revision="", date="", headers=None): if headers is None: headers = {} headers["x-revision-n"] = str(revision) + headers["x-revision-date"] = str(date) return self._get_resource_item('{}/{}/historical'.format(self.prefix_path, id), headers=headers) def patch_credentials(self, id, access_token): From 0d7f63367fac5be2ffd2d931d65a6525a523a365 Mon Sep 17 00:00:00 2001 From: vladkhard Date: Wed, 6 Mar 2019 14:10:16 +0200 Subject: [PATCH 4/4] change headers check --- openprocurement_client/clients.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openprocurement_client/clients.py b/openprocurement_client/clients.py index 79c7a6d..039c375 100755 --- a/openprocurement_client/clients.py +++ b/openprocurement_client/clients.py @@ -88,7 +88,7 @@ def _get_resource_item(self, url, headers=None): response_item = self.request('GET', url, headers=_headers) if response_item.status_code == 200: data = loads(response_item.text) - if isinstance(response_item.headers, dict): + if hasattr(response_item, "headers") and response_item.headers is not None: if "x-revision-n" in response_item.headers: data["x_revision_n"] = response_item.headers["x-revision-n"] if "x-revision-date" in response_item.headers: