From ff5c4bd58748f1fd83fe76fa5979e26fd493c012 Mon Sep 17 00:00:00 2001 From: John Vu Date: Tue, 29 Mar 2022 21:29:11 -0700 Subject: [PATCH] Fix get_audit_log_events --- asana/page_iterator.py | 30 ++++++ asana/resources/audit_log_api.py | 15 ++- tests/test_client_audit_log_api.py | 152 +++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 tests/test_client_audit_log_api.py diff --git a/asana/page_iterator.py b/asana/page_iterator.py index b330886e..313c1d33 100644 --- a/asana/page_iterator.py +++ b/asana/page_iterator.py @@ -102,3 +102,33 @@ def __next__(self): return results else: time.sleep(self.options['poll_interval']) + + +class AuditLogAPIIterator(CollectionPageIterator): + """Iterator that returns the next page of audit_log_api""" + + def __next__(self): + """Override __next__ to stop when there is no more data""" + + # Compute the limit from the page size, and remaining item limit + self.options['limit'] = min( + self.page_size, self.item_limit - self.count) + # If there is no continuation value or computed limit is 0, we're done + if self.continuation == None or self.options['limit'] == 0: + raise StopIteration + # First call to __next__ + elif self.continuation == False: + result = self.get_initial() + # Subsequent calls to __next__ + else: + result = self.get_next() + # Extract the continuation from the response + self.continuation = result.get(self.CONTINUATION_KEY, None) + # Get the data + data = result.get('data', None) + # If there is no more data we're done. Otherwise, we update the count and return the data + if not data: + raise StopIteration + else: + self.count += len(data) + return data diff --git a/asana/resources/audit_log_api.py b/asana/resources/audit_log_api.py index 8c170737..43c3e30f 100644 --- a/asana/resources/audit_log_api.py +++ b/asana/resources/audit_log_api.py @@ -1,6 +1,19 @@ from .gen.audit_log_api import _AuditLogAPI +from ..page_iterator import AuditLogAPIIterator + class AuditLogAPI(_AuditLogAPI): """AuditLogAPI resource""" - pass + + def get_audit_log_events(self, workspace_gid, params={}, **options): + """Override get_audit_log_events to handle non-empty next_page parameter""" + path = "/workspaces/{workspace_gid}/audit_log_events".replace( + "{workspace_gid}", workspace_gid) + options = self.client._merge_options(options) + if options['iterator_type'] == 'items': + return AuditLogAPIIterator(self.client, path, params, options).items() + if options['iterator_type'] is None: + return self.client.get(path, params, **options) + raise Exception('Unknown value for "iterator_type" option: {}'.format( + str(options['iterator_type']))) diff --git a/tests/test_client_audit_log_api.py b/tests/test_client_audit_log_api.py new file mode 100644 index 00000000..ca0dc9fe --- /dev/null +++ b/tests/test_client_audit_log_api.py @@ -0,0 +1,152 @@ +from .helpers import * + + +class TestClientAuditLogAPI(ClientTestCase): + + def test_get_audit_log_events(self): + res = { + "data": [ + { + "actor": { + "actor_type": "user", + "email": "gregsanchez@example.com", + "gid": "1111", + "name": "Greg Sanchez" + }, + "context": { + "api_authentication_method": "cookie", + "client_ip_address": "1.1.1.1", + "context_type": "web", + "oauth_app_name": "string", + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" + }, + "created_at": "2021-01-01T00:00:00.000Z", + "details": {}, + "event_category": "deletion", + "event_type": "task_deleted", + "gid": "12345", + "resource": { + "email": "string", + "gid": "1111", + "name": "Example Task", + "resource_subtype": "milestone", + "resource_type": "task" + } + } + ], + "next_page": { + "offset": "a", + "path": "/workspaces/1337/audit_log_events?offset=a", + "uri": "https://app.asana.com/api/1.0/workspaces/1337/audit_log_events?offset=a" + } + } + responses.add(GET, 'http://app/workspaces/1337/audit_log_events?', + status=200, body=json.dumps(res), match_querystring=True) + self.assertEqual( + self.client.audit_log_api.get_audit_log_events("1337"), res['data']) + + def test_get_audit_log_events_iterator(self): + res1 = { + "data": [ + { + "actor": { + "actor_type": "user", + "email": "gregsanchez@example.com", + "gid": "1111", + "name": "Greg Sanchez" + }, + "context": { + "api_authentication_method": "cookie", + "client_ip_address": "1.1.1.1", + "context_type": "web", + "oauth_app_name": "string", + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" + }, + "created_at": "2021-01-01T00:00:00.000Z", + "details": {}, + "event_category": "deletion", + "event_type": "task_deleted", + "gid": "12345", + "resource": { + "email": "string", + "gid": "1111", + "name": "Example Task", + "resource_subtype": "milestone", + "resource_type": "task" + } + } + ], + "next_page": { + "offset": "a", + "path": "/workspaces/1337/audit_log_events?limit=1&offset=a", + "uri": "https://app.asana.com/api/1.0/workspaces/1337/audit_log_events?limit=1&offset=a" + } + } + res2 = { + "data": [ + { + "actor": { + "actor_type": "user", + "email": "tbizarro@example.com", + "gid": "1234", + "name": "Tim Bizarro" + }, + "context": { + "api_authentication_method": "cookie", + "client_ip_address": "1.1.1.1", + "context_type": "web", + "oauth_app_name": "string", + "user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" + }, + "created_at": "2021-01-01T00:00:00.000Z", + "details": {}, + "event_category": "deletion", + "event_type": "task_deleted", + "gid": "12345", + "resource": { + "email": "string", + "gid": "1111", + "name": "Example Task", + "resource_subtype": "milestone", + "resource_type": "task" + } + } + ], + "next_page": { + "offset": "b", + "path": "/workspaces/1337/audit_log_events?limit=1&offset=b", + "uri": "https://app.asana.com/api/1.0/workspaces/1337/audit_log_events?limit=1&offset=b" + } + } + res3 = { + "data": [], + "next_page": { + "offset": "c", + "path": "/workspaces/1337/audit_log_events?limit=1&offset=c", + "uri": "https://app.asana.com/api/1.0/workspaces/1337/audit_log_events?limit=1&offset=c" + } + } + res4 = { + "data": [], + "next_page": { + "offset": "d", + "path": "/workspaces/1337/audit_log_events?limit=1&offset=d", + "uri": "https://app.asana.com/api/1.0/workspaces/1337/audit_log_events?limit=1&offset=d" + } + } + responses.add(GET, 'http://app/workspaces/1337/audit_log_events?limit=1', + status=200, body=json.dumps(res1), match_querystring=True) + responses.add(GET, 'http://app/workspaces/1337/audit_log_events?limit=1&offset=a', + status=200, body=json.dumps(res2), match_querystring=True) + responses.add(GET, 'http://app/workspaces/1337/audit_log_events?limit=1&offset=b', + status=200, body=json.dumps(res3), match_querystring=True) + responses.add(GET, 'http://app/workspaces/1337/audit_log_events?limit=1&offset=c', + status=200, body=json.dumps(res4), match_querystring=True) + # Set iterator_type to 'items' to return an iterator + iterator = self.client.audit_log_api.get_audit_log_events( + "1337", page_size=1, iterator_type='items' + ) + # Iterator should stop on third call + self.assertEqual(next(iterator), res1['data'][0]) + self.assertEqual(next(iterator), res2['data'][0]) + self.assertRaises(StopIteration, next, (iterator))