diff --git a/tests/utils/test_pagure.py b/tests/utils/test_pagure.py index 477a109..e0a0cd0 100644 --- a/tests/utils/test_pagure.py +++ b/tests/utils/test_pagure.py @@ -78,6 +78,70 @@ class TestPagureGetAuthHeader: assert exp_header == header +class TestPagureGetIssue: + """ + Test class for `toddlers.pagure.Pagure.get_issue` method. + """ + + def setup(self): + """ + Setup method for the test class. + """ + config = { + "pagure_url": "https://pagure.io", + "pagure_api_key": "Very secret key", + } + self.pagure = pagure.set_pagure(config) + self.pagure._requests_session = Mock() + + def test_get_issue(self): + """ + Assert that issue on pagure is retrieved correctly. + """ + response_mock = Mock() + response_mock.status_code = 200 + data = {"id": 100} + response_mock.json.return_value = data + + self.pagure._requests_session.get.return_value = response_mock + + issue_id = 100 + namespace = "test" + + result = self.pagure.get_issue(issue_id, namespace) + + self.pagure._requests_session.get.assert_called_with( + "https://pagure.io/api/0/test/issue/100", + headers=self.pagure.get_auth_header(), + ) + + assert result == data + + def test_get_issue_not_ok(self): + """ + Assert that failing to retrieve issue on pagure is handled correctly. + """ + response_mock = Mock() + response_mock.status_code = 500 + + self.pagure._requests_session.get.return_value = response_mock + + issue_id = 100 + namespace = "test" + + expected_error = "Couldn't retrieve issue '{}' from project '{}'".format( + issue_id, namespace + ) + + with pytest.raises(PagureError, match=expected_error): + self.pagure.get_issue(issue_id, namespace) + + self.pagure._requests_session.get.assert_called_with( + "https://pagure.io/api/0/test/issue/100", + headers=self.pagure.get_auth_header(), + ) + + class TestPagureCloseIssue: """ Test class for `toddlers.pagure.Pagure.close_issue` function. diff --git a/toddlers/utils/pagure.py b/toddlers/utils/pagure.py index c1a3d80..88bde25 100644 --- a/toddlers/utils/pagure.py +++ b/toddlers/utils/pagure.py @@ -51,10 +51,10 @@ class Pagure: Initialize pagure instance. Params: - config: This needs to have keys "pagure_url" and "pagure_api_key" + config: This needs to have keys "pagure_url" and "pagure_api_key" Raises: - `ValueError` if configuration value is missing + `ValueError` if configuration value is missing """ self._pagure_url = config.get("pagure_url", "") if not self._pagure_url: @@ -71,7 +71,7 @@ class Pagure: Get the HTTP header with authorization for the desired service. Returns: - A dictionary of the HTTP header + A dictionary of the HTTP header """ return { "Authorization": "token {0}".format(self._pagure_api_key), @@ -79,6 +79,47 @@ class Pagure: "Content-Type": "application/json", } + def get_issue(self, issue_id: int, namespace: str) -> dict: + """ + Get specific issue from project in pagure. + + Params: + issue_id: Issue to retrieve + namespace: Project namespace. For example: 'releng/fedora-scm-requests' + + Returns: + Dictionary containing pagure issue. + + Raises: + toddlers.utils.exceptions.PagureError when the issue couldn't be retrieved. + """ + api_url = "{0}/api/0/{1}/issue/{2}".format( + self._pagure_url, namespace, issue_id + ) + headers = self.get_auth_header() + + log.debug( + "Retrieving issue '{0}' from project '{1}'".format(issue_id, namespace) + ) + response = self._requests_session.get(api_url, headers=headers) + + result = {} + + if response.status_code == 200: + result = response.json() + return result + + log.error( + "Error when retrieving issue '{0}' from project '{1}'. " + "Got status_code '{2}'.".format(issue_id, namespace, response.status_code) + ) + + raise PagureError( + "Couldn't retrieve issue '{0}' from project '{1}'".format( + issue_id, namespace + ) + ) + def close_issue( self, issue_id: int, namespace: str, message: str, reason: str = "Closed" ): @@ -86,14 +127,14 @@ class Pagure: Close the issue defined by the id with provided message and reason. Params: - issue_id: Identifier of the issue - namespace: Project namespace. For example: 'releng/fedora-scm-requests' - message: Message to add when closing the ticket - reason: Reason to close the ticket with, this needs to be valid reason + issue_id: Identifier of the issue + namespace: Project namespace. For example: 'releng/fedora-scm-requests' + message: Message to add when closing the ticket + reason: Reason to close the ticket with, this needs to be valid reason accepted on the project issue tracker. Default: Fixed. Raises: - toddlers.utils.exceptions.PagureError when the issue couldn't be closed. + toddlers.utils.exceptions.PagureError when the issue couldn't be closed. """ issue_url = "{0}/{1}/issue/{2}".format(self._pagure_url, namespace, issue_id) api_url = "{0}/status".format(issue_url) @@ -128,12 +169,12 @@ class Pagure: Comment on issue defined by the id. Params: - issue_id: Identifier of the issue - namespace: Project namespace. For example: 'releng/fedora-scm-requests' - message: Message to add when closing the ticket + issue_id: Identifier of the issue + namespace: Project namespace. For example: 'releng/fedora-scm-requests' + message: Message to add when closing the ticket Raises: - toddlers.utils.exceptions.PagureError: When the issue couldn't be commented on. + toddlers.utils.exceptions.PagureError: When the issue couldn't be commented on. """ issue_url = "{0}/{1}/issue/{2}".format(self._pagure_url, namespace, issue_id) api_url = "{0}/comment".format(issue_url)