Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions src/objects/jira_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,25 @@ def create_issue(
self.add_attachment_to_issue(issue=issue, attachment_path=file_path)

if epic is not None:
epic_search = self.connection.search_issues(f"issue={epic}", maxResults=False)
if len(epic_search) == 1:
epic_id = epic_search[0].id
self.connection.add_issues_to_epic(
epic_id=epic_id,
issue_keys=issue.key,
try:
epic_search = self.connection.search_issues(f"issue={epic}", maxResults=False)
if len(epic_search) == 1:
epic_id = epic_search[0].id
self.connection.add_issues_to_epic(
epic_id=epic_id,
issue_keys=issue.key,
)
else:
LOGGER.warning(
f"Epic {epic} not found or not accessible; issue {issue} created without epic link",
)
except JIRAError as e:
LOGGER.warning(
f"Failed to link {issue} to epic {epic} "
f"(status {e.status_code}): {e.text}. "
f"Issue created without epic link.",
exc_info=True,
)
else:
LOGGER.error(f"Error finding Jira ID of epic {epic}")

if assignee is not None:
self.assign_issue(user_email=assignee, issue=issue.key)
Expand Down
67 changes: 67 additions & 0 deletions tests/unittests/objects/jira/test_jira.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,73 @@ def test_epic_lookup_uses_unquoted_issue_key_for_cloud_compatibility(self, mock_
issue_keys="TEST-1",
)

def test_epic_lookup_jira_error_does_not_crash(self, mock_jira):
mock_jira.connection.search_issues.side_effect = JIRAError(
"The requested epic cannot be viewed",
404,
"https://jira/rest/agile/1.0/epic",
)

with patch("src.objects.jira_base.LOGGER") as mock_logger:
issue = mock_jira.create_issue(
project="TEST",
summary="Test issue",
description="Description",
issue_type="Bug",
epic="INTEROP-9999",
)

assert issue is not None
assert issue.key == "TEST-1"
mock_jira.connection.add_issues_to_epic.assert_not_called()
warning_msg = mock_logger.warning.call_args[0][0]
assert "INTEROP-9999" in warning_msg
assert "Issue created without epic link" in warning_msg

def test_epic_lookup_empty_results_warns_without_error(self, mock_jira):
mock_jira.connection.search_issues.return_value = []

with patch("src.objects.jira_base.LOGGER") as mock_logger:
issue = mock_jira.create_issue(
project="TEST",
summary="Test issue",
description="Description",
issue_type="Bug",
epic="INTEROP-9999",
)

assert issue is not None
assert issue.key == "TEST-1"
mock_jira.connection.add_issues_to_epic.assert_not_called()
warning_msg = mock_logger.warning.call_args[0][0]
assert "INTEROP-9999" in warning_msg

def test_add_issues_to_epic_jira_error_does_not_crash(self, mock_jira):
epic_issue = MagicMock()
epic_issue.id = "20001"
mock_jira.connection.search_issues.return_value = [epic_issue]
mock_jira.connection.add_issues_to_epic.side_effect = JIRAError(
"You do not have permission to link to this epic",
403,
"https://jira/rest/agile/1.0/epic/20001/issue",
)

with patch("src.objects.jira_base.LOGGER") as mock_logger:
issue = mock_jira.create_issue(
project="TEST",
summary="Test issue",
description="Description",
issue_type="Bug",
epic="INTEROP-1234",
)

assert issue is not None
assert issue.key == "TEST-1"
mock_jira.connection.add_issues_to_epic.assert_called_once()
warning_msg = mock_logger.warning.call_args[0][0]
assert "INTEROP-1234" in warning_msg
assert "Issue created without epic link" in warning_msg


class TestJiraInitAuth:
@pytest.fixture
Expand Down
Loading