From 9c3972d619cd2eed317634e9d4b02bba444feea2 Mon Sep 17 00:00:00 2001 From: Lawrence Mantin Date: Thu, 14 Aug 2025 09:23:29 -0500 Subject: [PATCH 1/2] Adds a new configuration group [azure_devops] that will allow setting the comment status other than "closed". --- .../git_providers/azuredevops_provider.py | 6 +- pr_agent/settings/configuration.toml | 2 + tests/unittest/test_azure_devops_comment.py | 59 +++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tests/unittest/test_azure_devops_comment.py diff --git a/pr_agent/git_providers/azuredevops_provider.py b/pr_agent/git_providers/azuredevops_provider.py index cba81654..7c1161d6 100644 --- a/pr_agent/git_providers/azuredevops_provider.py +++ b/pr_agent/git_providers/azuredevops_provider.py @@ -351,7 +351,11 @@ class AzureDevopsProvider(GitProvider): get_logger().debug(f"Skipping publish_comment for temporary comment: {pr_comment}") return None comment = Comment(content=pr_comment) - thread = CommentThread(comments=[comment], thread_context=thread_context, status="closed") + + status = get_settings().azure_devops.default_comment_status + if status is None: + status = "closed" + thread = CommentThread(comments=[comment], thread_context=thread_context, status=status) thread_response = self.azure_devops_client.create_thread( comment_thread=thread, project=self.workspace_slug, diff --git a/pr_agent/settings/configuration.toml b/pr_agent/settings/configuration.toml index ab04f463..86ea58dd 100644 --- a/pr_agent/settings/configuration.toml +++ b/pr_agent/settings/configuration.toml @@ -373,6 +373,8 @@ extra_instructions = "" # public - extra instructions to the auto best practices content = "" max_patterns = 5 # max number of patterns to be detected +[azure_devops] +default_comment_status = "closed" [azure_devops_server] pr_commands = [ diff --git a/tests/unittest/test_azure_devops_comment.py b/tests/unittest/test_azure_devops_comment.py new file mode 100644 index 00000000..1c9e8222 --- /dev/null +++ b/tests/unittest/test_azure_devops_comment.py @@ -0,0 +1,59 @@ +import unittest +from pr_agent.config_loader import get_settings +from unittest.mock import patch, MagicMock +from pr_agent.git_providers import AzureDevopsProvider + +class TestAzureDevopsProviderPublishComment(unittest.TestCase): + @patch("pr_agent.git_providers.azuredevops_provider.get_settings") + def test_publish_comment_default_closed(self, mock_get_settings): + # Simulate config with no default_comment_status + mock_settings = MagicMock() + mock_settings.azure_devops.default_comment_status = None + mock_settings.config.publish_output_progress = True + mock_get_settings.return_value = mock_settings + + with patch.object(AzureDevopsProvider, "_get_azure_devops_client", return_value=(MagicMock(), MagicMock())): + provider = AzureDevopsProvider() + provider.workspace_slug = "ws" + provider.repo_slug = "repo" + provider.pr_num = 1 + + # Patch CommentThread and create_thread + with patch("pr_agent.git_providers.azuredevops_provider.CommentThread") as MockThread: + provider.azure_devops_client.create_thread.return_value.comments = [MagicMock()] + provider.azure_devops_client.create_thread.return_value.comments[0].thread_id = 123 + provider.azure_devops_client.create_thread.return_value.id = 123 + + provider.publish_comment("test comment") + args, kwargs = MockThread.call_args + assert kwargs.get("status") == "closed" + + @patch("pr_agent.git_providers.azuredevops_provider.get_settings") + def test_publish_comment_active(self, mock_get_settings): + # Simulate config with default_comment_status = "active" + mock_settings = MagicMock() + mock_settings.azure_devops.default_comment_status = "active" + mock_settings.config.publish_output_progress = True + mock_get_settings.return_value = mock_settings + + with patch.object(AzureDevopsProvider, "_get_azure_devops_client", return_value=(MagicMock(), MagicMock())): + provider = AzureDevopsProvider() + provider.workspace_slug = "ws" + provider.repo_slug = "repo" + provider.pr_num = 1 + + # Patch CommentThread and create_thread + with patch("pr_agent.git_providers.azuredevops_provider.CommentThread") as MockThread: + provider.azure_devops_client.create_thread.return_value.comments = [MagicMock()] + provider.azure_devops_client.create_thread.return_value.comments[0].thread_id = 123 + provider.azure_devops_client.create_thread.return_value.id = 123 + + provider.publish_comment("test comment") + args, kwargs = MockThread.call_args + assert kwargs.get("status") == "active" + + def test_default_comment_status_from_config_file(self): + # Import get_settings directly to read from configuration.toml + status = get_settings().azure_devops.default_comment_status + # The expected value should match what's in your configuration.toml + self.assertEqual(status, "closed") \ No newline at end of file From 57ec112b4d50a4aab0e26511116bbd81402f2984 Mon Sep 17 00:00:00 2001 From: Lawrence Mantin Date: Thu, 14 Aug 2025 10:42:17 -0500 Subject: [PATCH 2/2] Update pr_agent/git_providers/azuredevops_provider.py applied suggestion. Co-authored-by: qodo-merge-for-open-source[bot] <189517486+qodo-merge-for-open-source[bot]@users.noreply.github.com> --- pr_agent/git_providers/azuredevops_provider.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pr_agent/git_providers/azuredevops_provider.py b/pr_agent/git_providers/azuredevops_provider.py index 7c1161d6..8665ae3e 100644 --- a/pr_agent/git_providers/azuredevops_provider.py +++ b/pr_agent/git_providers/azuredevops_provider.py @@ -352,9 +352,7 @@ class AzureDevopsProvider(GitProvider): return None comment = Comment(content=pr_comment) - status = get_settings().azure_devops.default_comment_status - if status is None: - status = "closed" + status = get_settings().azure_devops.get("default_comment_status", "closed") thread = CommentThread(comments=[comment], thread_context=thread_context, status=status) thread_response = self.azure_devops_client.create_thread( comment_thread=thread,