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:
2025-09-28 23:34:20 +02:00
parent ad25b2a7d7
commit c4f8e4a3e9

View File

@@ -174,20 +174,40 @@ class TestIssueCreator:
with pytest.raises(IssueError, match="Failed to create issue.*parse.*response"): with pytest.raises(IssueError, match="Failed to create issue.*parse.*response"):
creator.create_issue("Test Issue", "Test description") 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): def test_create_issue_with_optional_fields(self, mock_run):
"""Test issue creation with optional fields.""" """Test issue creation with optional fields."""
config = self._get_test_config() config = self._get_test_config()
creator = IssueCreator(config=config, auth_token="test-token") creator = IssueCreator(config=config, auth_token="test-token")
mock_response = self._get_complete_mock_response(124) # Mock labels API response for label resolution
mock_run.return_value = MagicMock( labels_response = [
returncode=0, {"id": 1, "name": "bug", "color": "red"},
stdout=json.dumps(mock_response), {"id": 2, "name": "high", "color": "orange"}
stderr="" ]
)
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 Issue",
"Test description", "Test description",
assignees=["user1"], assignees=["user1"],
@@ -195,27 +215,63 @@ class TestIssueCreator:
labels=["bug", "high"] labels=["bug", "high"]
) )
# Check that JSON data includes optional fields # Verify issue was created successfully
call_args = mock_run.call_args[0][0] assert result['number'] == 124
json_data_index = call_args.index('-d') + 1 assert result['title'] == "Test Issue"
json_data = json.loads(call_args[json_data_index])
assert json_data['assignees'] == ["user1"] # Verify the API was called correctly
assert json_data['milestone'] == 1 # Find the issue creation call (not the labels call)
assert json_data['labels'] == ["bug", "high"] 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): def test_create_enhancement_issue(self, mock_run):
"""Test creating enhancement issue with structured format.""" """Test creating enhancement issue with structured format."""
config = self._get_test_config() config = self._get_test_config()
creator = IssueCreator(config=config, auth_token="test-token") creator = IssueCreator(config=config, auth_token="test-token")
mock_response = self._get_complete_mock_response(125) # Mock labels API response for label resolution
mock_run.return_value = MagicMock( labels_response = [
returncode=0, {"id": 1, "name": "enhancement", "color": "blue"},
stdout=json.dumps(mock_response), {"id": 2, "name": "high", "color": "orange"}
stderr="" ]
)
# 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( result = creator.create_enhancement_issue(
title="Add CLI Support", title="Add CLI Support",
@@ -227,30 +283,60 @@ class TestIssueCreator:
) )
# Verify structure of created issue # Verify structure of created issue
call_args = mock_run.call_args[0][0] create_call = None
json_data_index = call_args.index('-d') + 1 for call in mock_run.call_args_list:
json_data = json.loads(call_args[json_data_index]) 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 create_call is not None
assert "Technical Requirements:" in json_data['body'] cmd = create_call[0][0]
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"]
@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): def test_create_bug_issue(self, mock_run):
"""Test creating bug issue with structured format.""" """Test creating bug issue with structured format."""
config = self._get_test_config() config = self._get_test_config()
creator = IssueCreator(config=config, auth_token="test-token") creator = IssueCreator(config=config, auth_token="test-token")
mock_response = self._get_complete_mock_response(126) # Mock labels API response for label resolution
mock_run.return_value = MagicMock( labels_response = [
returncode=0, {"id": 1, "name": "bug", "color": "red"}
stdout=json.dumps(mock_response), ]
stderr=""
) # 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( result = creator.create_bug_issue(
title="CLI crashes on empty input", title="CLI crashes on empty input",
@@ -262,18 +348,29 @@ class TestIssueCreator:
) )
# Verify structure of created bug issue # Verify structure of created bug issue
call_args = mock_run.call_args[0][0] create_call = None
json_data_index = call_args.index('-d') + 1 for call in mock_run.call_args_list:
json_data = json.loads(call_args[json_data_index]) 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 create_call is not None
assert "Steps to Reproduce:" in json_data['body'] cmd = create_call[0][0]
assert "1. Run CLI command" in json_data['body']
assert "2. Provide empty input" in json_data['body'] # Find the -d argument (data payload)
assert "Expected Behavior: Should show help message" in json_data['body'] data_index = cmd.index('-d') + 1
assert "Actual Behavior: Application crashes" in json_data['body'] payload = json.loads(cmd[data_index])
assert "Environment: Python 3.8, Linux" in json_data['body']
assert json_data['labels'] == ["bug"] 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('subprocess.run')
@patch('builtins.open', new_callable=mock_open, read_data="Title: Template Issue\nTemplate body content with {variable}") @patch('builtins.open', new_callable=mock_open, read_data="Title: Template Issue\nTemplate body content with {variable}")