From 6f4b9eeb315e4db72179e58ec9590921b2264b78 Mon Sep 17 00:00:00 2001 From: Spacetown Date: Sun, 20 Dec 2020 20:53:13 +0100 Subject: [PATCH 1/5] [Bitbucket] Fix AssertionError error in pagination. --- atlassian/bitbucket/base.py | 10 +--------- atlassian/bitbucket/cloud/base.py | 10 +--------- atlassian/bitbucket/server/base.py | 10 +--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/atlassian/bitbucket/base.py b/atlassian/bitbucket/base.py index 2a2153e02..2bd258d27 100644 --- a/atlassian/bitbucket/base.py +++ b/atlassian/bitbucket/base.py @@ -38,15 +38,7 @@ def _get_paged(self, url, params=None, data=None, flags=None, trailing=None, abs if "values" not in response: return - values = response.get("values", []) - if not response.get("size", -1) == len(values): - raise AssertionError( - "Wrong response for url [{}], the size attribute doesn't match the number of recieved values:\n{}".format( - self.url, response - ) - ) - - for value in values: + for value in response.get("values", []): yield value if self.cloud: diff --git a/atlassian/bitbucket/cloud/base.py b/atlassian/bitbucket/cloud/base.py index a3735be87..c45103dbe 100644 --- a/atlassian/bitbucket/cloud/base.py +++ b/atlassian/bitbucket/cloud/base.py @@ -58,15 +58,7 @@ def _get_paged(self, url, params=None, data=None, flags=None, trailing=None, abs if "values" not in response: return - values = response.get("values", []) - if not response.get("size", -1) == len(values): - raise AssertionError( - "Wrong response for url [{}], the size attribute doesn't match the number of recieved values:\n{}".format( - self.url, response - ) - ) - - for value in values: + for value in response.get("values", []): yield value url = response.get("next") diff --git a/atlassian/bitbucket/server/base.py b/atlassian/bitbucket/server/base.py index e45cfd4e3..37289c2f4 100644 --- a/atlassian/bitbucket/server/base.py +++ b/atlassian/bitbucket/server/base.py @@ -59,15 +59,7 @@ def _get_paged(self, url, params=None, data=None, flags=None, trailing=False, ab if "values" not in response: return - values = response.get("values", []) - if not response.get("size", -1) == len(values): - raise AssertionError( - "Wrong response for url [{}], the size attribute doesn't match the number of recieved values:\n{}".format( - self.url, response - ) - ) - - for value in values: + for value in response.get("values", []): yield value if response.get("nextPageStart") is None: From 4e2a9836f03c64d469a297e1a4ea1ca9be671622 Mon Sep 17 00:00:00 2001 From: Spacetown Date: Sun, 20 Dec 2020 21:00:16 +0100 Subject: [PATCH 2/5] Update test data. --- tests/responses/bitbucket/cloud/2.0/workspaces/GET | 4 ++-- .../bitbucket/server/rest/api/1.0/projects/PRJ/repos/GET | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/responses/bitbucket/cloud/2.0/workspaces/GET b/tests/responses/bitbucket/cloud/2.0/workspaces/GET index f38c84238..5b36784a9 100644 --- a/tests/responses/bitbucket/cloud/2.0/workspaces/GET +++ b/tests/responses/bitbucket/cloud/2.0/workspaces/GET @@ -1,7 +1,7 @@ responses[None] = { "page": 1, "pagelen": 2, - "size": 2, + "size": 3, "next": "workspaces?nextPage", "values": [ { @@ -46,7 +46,7 @@ responses[None] = { responses["nextPage"] = { "page": 2, "pagelen": 2, - "size": 1, + "size": 3, "values": [ { "created_on": "2020-10-28T12:00:00.0+00:00", diff --git a/tests/responses/bitbucket/server/rest/api/1.0/projects/PRJ/repos/GET b/tests/responses/bitbucket/server/rest/api/1.0/projects/PRJ/repos/GET index fa4b1d40f..1cdaa2529 100644 --- a/tests/responses/bitbucket/server/rest/api/1.0/projects/PRJ/repos/GET +++ b/tests/responses/bitbucket/server/rest/api/1.0/projects/PRJ/repos/GET @@ -1,5 +1,5 @@ responses[None] = { - "size": 2, + "size": 3, "limit": 2, "isLastPage": false, "values": [ @@ -64,7 +64,7 @@ responses[None] = { "nextPageStart": 5, } responses["start=5"] = { - "size": 1, + "size": 3, "limit": 2, "isLastPage": true, "values": [ From 3843148f2019a2a9608cc1957445acaad45e78f6 Mon Sep 17 00:00:00 2001 From: Spacetown Date: Sun, 20 Dec 2020 22:01:41 +0100 Subject: [PATCH 3/5] Fix default value for get_data. --- atlassian/bitbucket/cloud/base.py | 4 ++-- atlassian/bitbucket/server/base.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/atlassian/bitbucket/cloud/base.py b/atlassian/bitbucket/cloud/base.py index c45103dbe..40c454181 100644 --- a/atlassian/bitbucket/cloud/base.py +++ b/atlassian/bitbucket/cloud/base.py @@ -80,8 +80,8 @@ def update(self, **kwargs): def data(self): return copy.copy(self.__data) - def get_data(self, id): - return copy.copy(self.__data[id]) + def get_data(self, id, default=None): + return copy.copy(self.__data[id]) if id in self.__data else default def get_link(self, link): return self.__data["links"][link]["href"] diff --git a/atlassian/bitbucket/server/base.py b/atlassian/bitbucket/server/base.py index 37289c2f4..27470c545 100644 --- a/atlassian/bitbucket/server/base.py +++ b/atlassian/bitbucket/server/base.py @@ -100,8 +100,8 @@ def delete(self): def data(self): return copy.copy(self.__data) - def get_data(self, id): - return copy.copy(self.__data[id]) + def get_data(self, id, default=None): + return copy.copy(self.__data[id]) if id in self.__data else default def get_link(self, link): return [x["href"] for x in self.__data["links"][link]] From 8fffcffb26ca211c306fe3bdc6d1f01cda252d2d Mon Sep 17 00:00:00 2001 From: Spacetown Date: Sun, 20 Dec 2020 22:16:15 +0100 Subject: [PATCH 4/5] Consistence behavior of delete for OO interface. --- .../bitbucket/cloud/repositories/branchRestrictions.py | 2 +- atlassian/bitbucket/cloud/repositories/defaultReviewers.py | 2 +- atlassian/bitbucket/cloud/repositories/issues.py | 2 +- atlassian/bitbucket/cloud/workspaces/projects.py | 6 +++++- atlassian/bitbucket/server/base.py | 2 +- atlassian/bitbucket/server/common/__init__.py | 3 +-- atlassian/bitbucket/server/globalPermissions.py | 2 +- .../testrepository1/pipelines/{PipelineUuid}/GET | 1 - tests/test_bitbucket_cloud.py | 7 +++++++ 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/atlassian/bitbucket/cloud/repositories/branchRestrictions.py b/atlassian/bitbucket/cloud/repositories/branchRestrictions.py index 621f7f17e..bd156f1cf 100644 --- a/atlassian/bitbucket/cloud/repositories/branchRestrictions.py +++ b/atlassian/bitbucket/cloud/repositories/branchRestrictions.py @@ -144,6 +144,6 @@ def delete(self): Deletes the branch restriction """ data = super(BranchRestriction, self).delete(None) - if "errors" in data: + if data is None or "errors" in data: return return BranchRestriction(data, **self._new_session_args) diff --git a/atlassian/bitbucket/cloud/repositories/defaultReviewers.py b/atlassian/bitbucket/cloud/repositories/defaultReviewers.py index 0878b91cd..f25cccaed 100644 --- a/atlassian/bitbucket/cloud/repositories/defaultReviewers.py +++ b/atlassian/bitbucket/cloud/repositories/defaultReviewers.py @@ -95,6 +95,6 @@ def delete(self): Deletes the default reviewer """ data = super(DefaultReviewer, self).delete(None) - if "errors" in data: + if data is None or "errors" in data: return return DefaultReviewer(self.url, data, **self._new_session_args) diff --git a/atlassian/bitbucket/cloud/repositories/issues.py b/atlassian/bitbucket/cloud/repositories/issues.py index f75cac8c4..e5339d1bf 100644 --- a/atlassian/bitbucket/cloud/repositories/issues.py +++ b/atlassian/bitbucket/cloud/repositories/issues.py @@ -128,6 +128,6 @@ def delete(self): Deletes the issue """ data = super(Issue, self).delete(None) - if "errors" in data: + if data is None or "errors" in data: return return Issue(data, **self._new_session_args) diff --git a/atlassian/bitbucket/cloud/workspaces/projects.py b/atlassian/bitbucket/cloud/workspaces/projects.py index 9bc72b09b..654b7728d 100644 --- a/atlassian/bitbucket/cloud/workspaces/projects.py +++ b/atlassian/bitbucket/cloud/workspaces/projects.py @@ -151,4 +151,8 @@ def delete(self): """ Delete the project """ - return super(Project, self).delete(None) + data = super(Project, self).delete(None) + if data is None or "errors" in data: + return + return data + diff --git a/atlassian/bitbucket/server/base.py b/atlassian/bitbucket/server/base.py index 27470c545..e1f220526 100644 --- a/atlassian/bitbucket/server/base.py +++ b/atlassian/bitbucket/server/base.py @@ -92,7 +92,7 @@ def delete(self): if self.__can_delete is False: raise NotImplementedError("Delete not implemented for this object type.") data = super(BitbucketServerBase, self).delete(None) - if "errors" in data: + if data is None or "errors" in data: return return True diff --git a/atlassian/bitbucket/server/common/__init__.py b/atlassian/bitbucket/server/common/__init__.py index 2ed118058..f9b3e1d61 100644 --- a/atlassian/bitbucket/server/common/__init__.py +++ b/atlassian/bitbucket/server/common/__init__.py @@ -159,7 +159,7 @@ def delete(self): if self.url is None: raise NotImplementedError("Delete not implemented for this object type.") data = super(BitbucketServerBase, self).delete(None, params={"name": self.name}) - if "errors" in data: + if data is None or "errors" in data: return return True @@ -180,7 +180,6 @@ def __init__(self, data, *args, **kwargs): super(User, self).__init__(None, *args, data=data, **kwargs) def __userdata(self, key): - print(self.__dict__) if self.url is None: return self.get_data(key) return self.get_data("user")[key] diff --git a/atlassian/bitbucket/server/globalPermissions.py b/atlassian/bitbucket/server/globalPermissions.py index 6c1642a9e..c8d7d34f8 100644 --- a/atlassian/bitbucket/server/globalPermissions.py +++ b/atlassian/bitbucket/server/globalPermissions.py @@ -156,7 +156,7 @@ def delete(self): if self.url is None: raise NotImplementedError("Delete not implemented for this object type.") data = super(BitbucketServerBase, self).delete(None, params={"name": self.name}) - if "errors" in data: + if data is None or "errors" in data: return return True diff --git a/tests/responses/bitbucket/cloud/2.0/repositories/TestWorkspace1/testrepository1/pipelines/{PipelineUuid}/GET b/tests/responses/bitbucket/cloud/2.0/repositories/TestWorkspace1/testrepository1/pipelines/{PipelineUuid}/GET index 552407e93..080046ee4 100644 --- a/tests/responses/bitbucket/cloud/2.0/repositories/TestWorkspace1/testrepository1/pipelines/{PipelineUuid}/GET +++ b/tests/responses/bitbucket/cloud/2.0/repositories/TestWorkspace1/testrepository1/pipelines/{PipelineUuid}/GET @@ -50,7 +50,6 @@ responses[None] = { "account_id": "OwnerTestWorkspace1AccountId", }, "created_on": "2020-11-03T22:14:50.671Z", - "completed_on": "2020-11-03T22:14:53.173Z", "target": { "type": "pipeline_ref_target", "ref_type": "branch", diff --git a/tests/test_bitbucket_cloud.py b/tests/test_bitbucket_cloud.py index c78299403..5019c8403 100644 --- a/tests/test_bitbucket_cloud.py +++ b/tests/test_bitbucket_cloud.py @@ -3,6 +3,7 @@ import sys from atlassian import Bitbucket +from atlassian.bitbucket import Cloud BITBUCKET = None try: @@ -11,6 +12,9 @@ BITBUCKET = Bitbucket( "{}/bitbucket/cloud".format(mockup_server()), username="username", password="password", cloud=True ) + CLOUD = Cloud( + "{}/bitbucket/cloud".format(mockup_server()), username="username", password="password" + ) except ImportError: pass @@ -35,6 +39,9 @@ def test_trigger_pipeline(self): def test_get_pipeline(self): result = BITBUCKET.get_pipeline("TestWorkspace1", "testrepository1", "{PipelineUuid}") assert result["state"]["name"] == "COMPLETED", "Result of [get_pipeline(...)]" + result = CLOUD.workspaces.get("TestWorkspace1").repositories.get("testrepository1").pipelines.get("{PipelineUuid}") + assert result.get_data("state")["name"] == "COMPLETED", "Pipeline state" + assert result.completed_on() == "Never completed", "Pipeline completed time" @pytest.mark.skipif(sys.version_info < (3, 4), reason="requires python3.4") def test_stop_pipeline(self): From 89a61a0022a0d54e85577cc0d2b0700bf113fbe9 Mon Sep 17 00:00:00 2001 From: Spacetown Date: Tue, 22 Dec 2020 20:51:25 +0100 Subject: [PATCH 5/5] Fix tests. --- atlassian/bitbucket/cloud/workspaces/projects.py | 1 - tests/test_bitbucket_cloud.py | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/atlassian/bitbucket/cloud/workspaces/projects.py b/atlassian/bitbucket/cloud/workspaces/projects.py index 654b7728d..7279abd1b 100644 --- a/atlassian/bitbucket/cloud/workspaces/projects.py +++ b/atlassian/bitbucket/cloud/workspaces/projects.py @@ -155,4 +155,3 @@ def delete(self): if data is None or "errors" in data: return return data - diff --git a/tests/test_bitbucket_cloud.py b/tests/test_bitbucket_cloud.py index 5019c8403..96ef45063 100644 --- a/tests/test_bitbucket_cloud.py +++ b/tests/test_bitbucket_cloud.py @@ -12,9 +12,7 @@ BITBUCKET = Bitbucket( "{}/bitbucket/cloud".format(mockup_server()), username="username", password="password", cloud=True ) - CLOUD = Cloud( - "{}/bitbucket/cloud".format(mockup_server()), username="username", password="password" - ) + CLOUD = Cloud("{}/bitbucket/cloud".format(mockup_server()), username="username", password="password") except ImportError: pass @@ -39,9 +37,11 @@ def test_trigger_pipeline(self): def test_get_pipeline(self): result = BITBUCKET.get_pipeline("TestWorkspace1", "testrepository1", "{PipelineUuid}") assert result["state"]["name"] == "COMPLETED", "Result of [get_pipeline(...)]" - result = CLOUD.workspaces.get("TestWorkspace1").repositories.get("testrepository1").pipelines.get("{PipelineUuid}") + result = ( + CLOUD.workspaces.get("TestWorkspace1").repositories.get("testrepository1").pipelines.get("{PipelineUuid}") + ) assert result.get_data("state")["name"] == "COMPLETED", "Pipeline state" - assert result.completed_on() == "Never completed", "Pipeline completed time" + assert result.completed_on == "never completed", "Pipeline completed time" @pytest.mark.skipif(sys.version_info < (3, 4), reason="requires python3.4") def test_stop_pipeline(self):