fix: Update TDDAI tests to work with new gitea label ID resolution
- Fix three failing tests that were incompatible with label name-to-ID conversion - Update mocking from subprocess.run to gitea.http_client.subprocess.run - Add proper mock responses for labels API to support ID resolution - Update test assertions to expect label IDs instead of names in payloads - Maintain full test coverage while adapting to improved gitea integration - All tests now pass: 307 passed, 2 skipped Tests fixed: - test_create_issue_with_optional_fields - test_create_enhancement_issue - test_create_bug_issue 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -174,20 +174,40 @@ class TestIssueCreator:
|
||||
with pytest.raises(IssueError, match="Failed to create issue.*parse.*response"):
|
||||
creator.create_issue("Test Issue", "Test description")
|
||||
|
||||
@patch('subprocess.run')
|
||||
@patch('gitea.http_client.subprocess.run')
|
||||
def test_create_issue_with_optional_fields(self, mock_run):
|
||||
"""Test issue creation with optional fields."""
|
||||
config = self._get_test_config()
|
||||
creator = IssueCreator(config=config, auth_token="test-token")
|
||||
|
||||
mock_response = self._get_complete_mock_response(124)
|
||||
mock_run.return_value = MagicMock(
|
||||
returncode=0,
|
||||
stdout=json.dumps(mock_response),
|
||||
stderr=""
|
||||
)
|
||||
# Mock labels API response for label resolution
|
||||
labels_response = [
|
||||
{"id": 1, "name": "bug", "color": "red"},
|
||||
{"id": 2, "name": "high", "color": "orange"}
|
||||
]
|
||||
|
||||
creator.create_issue(
|
||||
# Mock issue creation response
|
||||
issue_response = self._get_complete_mock_response(124)
|
||||
|
||||
# Configure mock to return different responses based on URL
|
||||
def side_effect(*args, **kwargs):
|
||||
cmd = args[0]
|
||||
url = cmd[-1] # URL is the last argument
|
||||
|
||||
result_mock = MagicMock()
|
||||
result_mock.returncode = 0
|
||||
result_mock.stderr = ""
|
||||
|
||||
if 'labels' in url:
|
||||
result_mock.stdout = json.dumps(labels_response)
|
||||
else:
|
||||
result_mock.stdout = json.dumps(issue_response)
|
||||
|
||||
return result_mock
|
||||
|
||||
mock_run.side_effect = side_effect
|
||||
|
||||
result = creator.create_issue(
|
||||
"Test Issue",
|
||||
"Test description",
|
||||
assignees=["user1"],
|
||||
@@ -195,27 +215,63 @@ class TestIssueCreator:
|
||||
labels=["bug", "high"]
|
||||
)
|
||||
|
||||
# Check that JSON data includes optional fields
|
||||
call_args = mock_run.call_args[0][0]
|
||||
json_data_index = call_args.index('-d') + 1
|
||||
json_data = json.loads(call_args[json_data_index])
|
||||
# Verify issue was created successfully
|
||||
assert result['number'] == 124
|
||||
assert result['title'] == "Test Issue"
|
||||
|
||||
assert json_data['assignees'] == ["user1"]
|
||||
assert json_data['milestone'] == 1
|
||||
assert json_data['labels'] == ["bug", "high"]
|
||||
# Verify the API was called correctly
|
||||
# Find the issue creation call (not the labels call)
|
||||
create_call = None
|
||||
for call in mock_run.call_args_list:
|
||||
cmd = call[0][0]
|
||||
url = cmd[-1]
|
||||
if 'issues' in url and '/labels' not in url:
|
||||
create_call = call
|
||||
break
|
||||
|
||||
@patch('subprocess.run')
|
||||
assert create_call is not None
|
||||
cmd = create_call[0][0]
|
||||
|
||||
# Find the -d argument (data payload)
|
||||
data_index = cmd.index('-d') + 1
|
||||
payload = json.loads(cmd[data_index])
|
||||
|
||||
assert payload['assignees'] == ["user1"]
|
||||
assert payload['milestone'] == 1
|
||||
assert payload['labels'] == [1, 2] # Should be IDs now
|
||||
|
||||
@patch('gitea.http_client.subprocess.run')
|
||||
def test_create_enhancement_issue(self, mock_run):
|
||||
"""Test creating enhancement issue with structured format."""
|
||||
config = self._get_test_config()
|
||||
creator = IssueCreator(config=config, auth_token="test-token")
|
||||
|
||||
mock_response = self._get_complete_mock_response(125)
|
||||
mock_run.return_value = MagicMock(
|
||||
returncode=0,
|
||||
stdout=json.dumps(mock_response),
|
||||
stderr=""
|
||||
)
|
||||
# Mock labels API response for label resolution
|
||||
labels_response = [
|
||||
{"id": 1, "name": "enhancement", "color": "blue"},
|
||||
{"id": 2, "name": "high", "color": "orange"}
|
||||
]
|
||||
|
||||
# Mock issue creation response
|
||||
issue_response = self._get_complete_mock_response(125)
|
||||
|
||||
# Configure mock to return different responses based on URL
|
||||
def side_effect(*args, **kwargs):
|
||||
cmd = args[0]
|
||||
url = cmd[-1] # URL is the last argument
|
||||
|
||||
result_mock = MagicMock()
|
||||
result_mock.returncode = 0
|
||||
result_mock.stderr = ""
|
||||
|
||||
if 'labels' in url:
|
||||
result_mock.stdout = json.dumps(labels_response)
|
||||
else:
|
||||
result_mock.stdout = json.dumps(issue_response)
|
||||
|
||||
return result_mock
|
||||
|
||||
mock_run.side_effect = side_effect
|
||||
|
||||
result = creator.create_enhancement_issue(
|
||||
title="Add CLI Support",
|
||||
@@ -227,30 +283,60 @@ class TestIssueCreator:
|
||||
)
|
||||
|
||||
# Verify structure of created issue
|
||||
call_args = mock_run.call_args[0][0]
|
||||
json_data_index = call_args.index('-d') + 1
|
||||
json_data = json.loads(call_args[json_data_index])
|
||||
create_call = None
|
||||
for call in mock_run.call_args_list:
|
||||
cmd = call[0][0]
|
||||
url = cmd[-1]
|
||||
if 'issues' in url and '/labels' not in url:
|
||||
create_call = call
|
||||
break
|
||||
|
||||
assert "UseCase: User needs command-line interface" in json_data['body']
|
||||
assert "Technical Requirements:" in json_data['body']
|
||||
assert "- [ ] CLI entry point works" in json_data['body']
|
||||
assert "- [ ] Commands have help text" in json_data['body']
|
||||
assert "Dependencies:" in json_data['body']
|
||||
assert "- Issue #1 - Database" in json_data['body']
|
||||
assert json_data['labels'] == ["high", "enhancement"]
|
||||
assert create_call is not None
|
||||
cmd = create_call[0][0]
|
||||
|
||||
@patch('subprocess.run')
|
||||
# Find the -d argument (data payload)
|
||||
data_index = cmd.index('-d') + 1
|
||||
payload = json.loads(cmd[data_index])
|
||||
|
||||
assert "UseCase: User needs command-line interface" in payload['body']
|
||||
assert "Technical Requirements:" in payload['body']
|
||||
assert "- [ ] CLI entry point works" in payload['body']
|
||||
assert "- [ ] Commands have help text" in payload['body']
|
||||
assert "Dependencies:" in payload['body']
|
||||
assert "- Issue #1 - Database" in payload['body']
|
||||
assert payload['labels'] == [2, 1] # Should be IDs: [high, enhancement]
|
||||
|
||||
@patch('gitea.http_client.subprocess.run')
|
||||
def test_create_bug_issue(self, mock_run):
|
||||
"""Test creating bug issue with structured format."""
|
||||
config = self._get_test_config()
|
||||
creator = IssueCreator(config=config, auth_token="test-token")
|
||||
|
||||
mock_response = self._get_complete_mock_response(126)
|
||||
mock_run.return_value = MagicMock(
|
||||
returncode=0,
|
||||
stdout=json.dumps(mock_response),
|
||||
stderr=""
|
||||
)
|
||||
# Mock labels API response for label resolution
|
||||
labels_response = [
|
||||
{"id": 1, "name": "bug", "color": "red"}
|
||||
]
|
||||
|
||||
# Mock issue creation response
|
||||
issue_response = self._get_complete_mock_response(126)
|
||||
|
||||
# Configure mock to return different responses based on URL
|
||||
def side_effect(*args, **kwargs):
|
||||
cmd = args[0]
|
||||
url = cmd[-1] # URL is the last argument
|
||||
|
||||
result_mock = MagicMock()
|
||||
result_mock.returncode = 0
|
||||
result_mock.stderr = ""
|
||||
|
||||
if 'labels' in url:
|
||||
result_mock.stdout = json.dumps(labels_response)
|
||||
else:
|
||||
result_mock.stdout = json.dumps(issue_response)
|
||||
|
||||
return result_mock
|
||||
|
||||
mock_run.side_effect = side_effect
|
||||
|
||||
result = creator.create_bug_issue(
|
||||
title="CLI crashes on empty input",
|
||||
@@ -262,18 +348,29 @@ class TestIssueCreator:
|
||||
)
|
||||
|
||||
# Verify structure of created bug issue
|
||||
call_args = mock_run.call_args[0][0]
|
||||
json_data_index = call_args.index('-d') + 1
|
||||
json_data = json.loads(call_args[json_data_index])
|
||||
create_call = None
|
||||
for call in mock_run.call_args_list:
|
||||
cmd = call[0][0]
|
||||
url = cmd[-1]
|
||||
if 'issues' in url and '/labels' not in url:
|
||||
create_call = call
|
||||
break
|
||||
|
||||
assert "The CLI tool crashes when given empty input" in json_data['body']
|
||||
assert "Steps to Reproduce:" in json_data['body']
|
||||
assert "1. Run CLI command" in json_data['body']
|
||||
assert "2. Provide empty input" in json_data['body']
|
||||
assert "Expected Behavior: Should show help message" in json_data['body']
|
||||
assert "Actual Behavior: Application crashes" in json_data['body']
|
||||
assert "Environment: Python 3.8, Linux" in json_data['body']
|
||||
assert json_data['labels'] == ["bug"]
|
||||
assert create_call is not None
|
||||
cmd = create_call[0][0]
|
||||
|
||||
# Find the -d argument (data payload)
|
||||
data_index = cmd.index('-d') + 1
|
||||
payload = json.loads(cmd[data_index])
|
||||
|
||||
assert "The CLI tool crashes when given empty input" in payload['body']
|
||||
assert "Steps to Reproduce:" in payload['body']
|
||||
assert "1. Run CLI command" in payload['body']
|
||||
assert "2. Provide empty input" in payload['body']
|
||||
assert "Expected Behavior: Should show help message" in payload['body']
|
||||
assert "Actual Behavior: Application crashes" in payload['body']
|
||||
assert "Environment: Python 3.8, Linux" in payload['body']
|
||||
assert payload['labels'] == [1] # Should be ID: [bug]
|
||||
|
||||
@patch('subprocess.run')
|
||||
@patch('builtins.open', new_callable=mock_open, read_data="Title: Template Issue\nTemplate body content with {variable}")
|
||||
|
||||
Reference in New Issue
Block a user