diff options
| author | Dawid Rycerz <dawid@rycerz.xyz> | 2025-05-28 15:27:57 +0200 |
|---|---|---|
| committer | Dawid Rycerz <dawid@rycerz.xyz> | 2025-05-28 15:27:57 +0200 |
| commit | 0b819edceb307ce2f8ba6d58b37a86329b7d6ec0 (patch) | |
| tree | f8bc71742a93cd3cb6baa55ce81d14ad42c42720 /servers/gitlab_glab/tests/test_server.py | |
| parent | a56a1ea5fa18c28d2fc3d42bfa780c026ce9b52d (diff) | |
feat(gitlab_glab): add merge request diff functionality with large diff mitigation
- Add get_mr_diff method to GitLabServer class with support for all glab mr diff options
- Implement smart large diff handling that saves diffs > 100KB to temporary files
- Add comprehensive test coverage (7 new tests) achieving 95% coverage
- Support for MR ID/branch, color options, raw format, and repository selection
- Include proper error handling and logging
- Update README with usage examples and documentation
- Follow project coding standards with type hints and docstrings
Resolves large diff handling for LLM consumption while preserving full diff access.
Diffstat (limited to 'servers/gitlab_glab/tests/test_server.py')
| -rw-r--r-- | servers/gitlab_glab/tests/test_server.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/servers/gitlab_glab/tests/test_server.py b/servers/gitlab_glab/tests/test_server.py index ab93026..a7e74a4 100644 --- a/servers/gitlab_glab/tests/test_server.py +++ b/servers/gitlab_glab/tests/test_server.py @@ -585,3 +585,180 @@ class TestGitLabServer: # Verify the number of calls assert mock_run.call_count == len(working_dirs) + + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_success_small(self, mock_execute: MagicMock) -> None: + """Test successful MR diff retrieval with small diff.""" + # Mock successful command execution with small diff + diff_content = """diff --git a/file.txt b/file.txt +index 1234567..abcdefg 100644 +--- a/file.txt ++++ b/file.txt +@@ -1,3 +1,4 @@ + line 1 + line 2 ++new line + line 3""" + mock_execute.return_value = (True, diff_content) + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff( + working_directory=working_dir, + mr_id="123", + color="never", + raw=False, + repo="group/project", + ) + + assert "diff" in result + assert result["diff"] == diff_content + assert result["size_kb"] < 1 + assert result["temp_file_path"] is None + + # Verify command was called with correct arguments + mock_execute.assert_called_once_with( + ["mr", "diff", "123", "--color", "never", "-R", "group/project"], + working_dir, + ) + + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_success_current_branch(self, mock_execute: MagicMock) -> None: + """Test successful MR diff retrieval for current branch.""" + diff_content = "diff content" + mock_execute.return_value = (True, diff_content) + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff(working_directory=working_dir) + + assert "diff" in result + assert result["diff"] == diff_content + assert result["temp_file_path"] is None + + # Verify command was called without MR ID + mock_execute.assert_called_once_with( + ["mr", "diff", "--color", "never"], + working_dir, + ) + + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_with_raw_option(self, mock_execute: MagicMock) -> None: + """Test MR diff retrieval with raw option.""" + diff_content = "raw diff content" + mock_execute.return_value = (True, diff_content) + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff( + working_directory=working_dir, + mr_id="branch-name", + color="auto", + raw=True, + ) + + assert "diff" in result + assert result["diff"] == diff_content + + # Verify command was called with raw option + mock_execute.assert_called_once_with( + ["mr", "diff", "branch-name", "--color", "auto", "--raw"], + working_dir, + ) + + @patch("tempfile.NamedTemporaryFile") + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_large_diff_temp_file( + self, mock_execute: MagicMock, mock_temp_file: MagicMock + ) -> None: + """Test MR diff retrieval with large diff that gets saved to temp file.""" + # Create a large diff content (over 100KB) + large_diff = "x" * (101 * 1024) # 101 KB + mock_execute.return_value = (True, large_diff) + + # Mock temporary file + mock_file = MagicMock() + mock_file.name = "/tmp/mr_diff_12345.diff" + mock_temp_file.return_value.__enter__.return_value = mock_file + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff( + working_directory=working_dir, + mr_id="123", + max_size_kb=100, + ) + + assert result["diff_too_large"] is True + assert result["size_kb"] > 100 + assert result["max_size_kb"] == 100 + assert result["temp_file_path"] == "/tmp/mr_diff_12345.diff" + assert "message" in result + + # Verify temp file was created with correct parameters + mock_temp_file.assert_called_once_with( + mode='w', + suffix='.diff', + prefix='mr_diff_', + delete=False, + encoding='utf-8' + ) + mock_file.write.assert_called_once_with(large_diff) + + @patch("tempfile.NamedTemporaryFile") + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_large_diff_temp_file_error( + self, mock_execute: MagicMock, mock_temp_file: MagicMock + ) -> None: + """Test MR diff retrieval with large diff and temp file creation error.""" + # Create a large diff content + large_diff = "x" * (101 * 1024) # 101 KB + mock_execute.return_value = (True, large_diff) + + # Mock temporary file creation error + mock_temp_file.side_effect = Exception("Permission denied") + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff( + working_directory=working_dir, + mr_id="123", + max_size_kb=100, + ) + + assert "error" in result + assert "too large" in result["error"] + assert "Permission denied" in result["error"] + + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_command_failure(self, mock_execute: MagicMock) -> None: + """Test MR diff retrieval with command failure.""" + mock_execute.return_value = (False, {"error": "MR not found"}) + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff(working_directory=working_dir, mr_id="999") + + assert "error" in result + assert result["error"] == "MR not found" + + @patch.object(GitLabServer, "execute_glab_command") + def test_get_mr_diff_invalid_color_option(self, mock_execute: MagicMock) -> None: + """Test MR diff with invalid color option skips color parameter.""" + diff_content = "diff content" + mock_execute.return_value = (True, diff_content) + + server = GitLabServer() + working_dir = "/test/directory" + result = server.get_mr_diff( + working_directory=working_dir, + mr_id="123", + color="invalid", # Invalid color option + ) + + assert "diff" in result + # Invalid color options should be filtered out, only valid ones are added + mock_execute.assert_called_once_with( + ["mr", "diff", "123"], + working_dir, + ) |
