1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
from __future__ import annotations
import unittest
from pathlib import Path
from unittest.mock import mock_open, patch
from requests import Response
from requests.structures import CaseInsensitiveDict
from jira.exceptions import JIRAError
DUMMY_HEADERS = {"h": "nice headers"}
DUMMY_TEXT = "nice text"
DUMMY_URL = "https://nice.jira.tests"
DUMMY_STATUS_CODE = 200
PATCH_BASE = "jira.exceptions"
class ExceptionsTests(unittest.TestCase):
class MockResponse(Response):
def __init__(
self,
headers: dict | None = None,
text: str = "",
status_code: int = DUMMY_STATUS_CODE,
url: str = DUMMY_URL,
):
"""Sub optimal but we create a mock response like this."""
self.headers = CaseInsensitiveDict(headers if headers else {})
self._text = text
self.status_code = status_code
self.url = url
@property
def text(self):
return self._text
@text.setter
def text(self, new_text):
self._text = new_text
class MalformedMockResponse:
def __init__(
self,
headers: dict | None = None,
text: str = "",
status_code: int = DUMMY_STATUS_CODE,
url: str = DUMMY_URL,
):
if headers:
self.headers = headers
if text:
self.text = text
self.url = url
self.status_code = status_code
def test_jira_error_response_added(self):
err = JIRAError(
response=self.MockResponse(headers=DUMMY_HEADERS, text=DUMMY_TEXT)
)
err_str = str(err)
assert f"headers = {DUMMY_HEADERS}" in err_str
assert f"text = {DUMMY_TEXT}" in err_str
def test_jira_error_malformed_response(self):
# GIVEN: a malformed Response object, without headers or text set
bad_repsonse = self.MalformedMockResponse()
# WHEN: The JiraError's __str__ method is called
err = JIRAError(response=bad_repsonse)
err_str = str(err)
# THEN: there are no errors and neither headers nor text are in the result
assert "headers = " not in err_str
assert "text = " not in err_str
def test_jira_error_request_added(self):
err = JIRAError(
request=self.MockResponse(headers=DUMMY_HEADERS, text=DUMMY_TEXT)
)
err_str = str(err)
assert f"headers = {DUMMY_HEADERS}" in err_str
assert f"text = {DUMMY_TEXT}" in err_str
def test_jira_error_malformed_request(self):
# GIVEN: a malformed Response object, without headers or text set
bad_repsonse = self.MalformedMockResponse()
# WHEN: The JiraError's __str__ method is called
err = JIRAError(request=bad_repsonse)
err_str = str(err)
# THEN: there are no errors and neither headers nor text are in the result
assert "headers = " not in err_str
assert "text = " not in err_str
def test_jira_error_url_added(self):
assert f"url: {DUMMY_URL}" in str(JIRAError(url=DUMMY_URL))
def test_jira_error_status_code_added(self):
assert f"JiraError HTTP {DUMMY_STATUS_CODE}" in str(
JIRAError(status_code=DUMMY_STATUS_CODE)
)
def test_jira_error_text_added(self):
dummy_text = "wow\tthis\nis\nso cool"
assert f"text: {dummy_text}" in str(JIRAError(text=dummy_text))
def test_jira_error_log_to_tempfile_if_env_var_set(self):
# GIVEN: the right env vars are set and the tempfile's filename
env_vars = {"PYJIRA_LOG_TO_TEMPFILE": "so true"}
test_jira_error_filename = (
Path(__file__).parent / "test_jira_error_log_to_tempfile.bak"
)
# https://docs.python.org/3/library/unittest.mock.html#mock-open
mocked_open = mock_open()
# WHEN: a JIRAError's __str__ method is called and
# log details are expected to be sent to the tempfile
with (
patch.dict("os.environ", env_vars),
patch(f"{PATCH_BASE}.tempfile.mkstemp", autospec=True) as mock_mkstemp,
patch(f"{PATCH_BASE}.open", mocked_open),
):
mock_mkstemp.return_value = 0, str(test_jira_error_filename)
str(JIRAError(response=self.MockResponse(text=DUMMY_TEXT)))
# THEN: the known filename is opened and contains the exception details
mocked_open.assert_called_once_with(str(test_jira_error_filename), "w")
mock_file_stream = mocked_open()
assert f"text = {DUMMY_TEXT}" in mock_file_stream.write.call_args[0][0]
def test_jira_error_log_to_tempfile_not_used_if_env_var_not_set(self):
# GIVEN: no env vars are set and the tempfile's filename
env_vars = {}
test_jira_error_filename = (
Path(__file__).parent / "test_jira_error_log_to_tempfile.bak"
)
# https://docs.python.org/3/library/unittest.mock.html#mock-open
mocked_open = mock_open()
# WHEN: a JIRAError's __str__ method is called
with (
patch.dict("os.environ", env_vars),
patch(f"{PATCH_BASE}.tempfile.mkstemp", autospec=True) as mock_mkstemp,
patch(f"{PATCH_BASE}.open", mocked_open),
):
mock_mkstemp.return_value = 0, str(test_jira_error_filename)
str(JIRAError(response=self.MockResponse(text=DUMMY_TEXT)))
# THEN: no files are opened
mocked_open.assert_not_called()
|