Skip to content

feat: Add comprehensive test suite for GitHub bot functionality#146

Open
abuzarmahmood wants to merge 5 commits intomainfrom
145-write-tests-for-github_bot-functionality-which-works-on-abuzarmahmoodtest_repo
Open

feat: Add comprehensive test suite for GitHub bot functionality#146
abuzarmahmood wants to merge 5 commits intomainfrom
145-write-tests-for-github_bot-functionality-which-works-on-abuzarmahmoodtest_repo

Conversation

@abuzarmahmood
Copy link
Owner

No description provided.

@abuzarmahmood
Copy link
Owner Author

Generated edit command:

Summary of User's Issues and Requests

The user has requested the development of tests for the GitHub bot functionality, specifically targeting the repository "abuzarmahmood/test_repo". The last comment in the issue thread, "[ develop_issue ]", suggests a focus on developing or enhancing the issue handling capabilities of the bot.

Overview of Plan to Address the Issues

  1. Identify Relevant Files:

    • The files that need to be modified or referenced include:
      • agents.py
      • git_utils.py
      • response_agent.py
      • branch_handler.py
      • triggers.py
      • bot_tools.py
  2. Develop Test Cases:

    • Create test cases for core functionalities of the GitHub bot, including agent creation, API interactions, response generation, branch management, and trigger detection.
    • Test the response agent flows by creating issues and pull requests on the test repository, ensuring these can be deleted after testing.

Specific Details of Changes to be Made

  1. Agent Creation and Configuration Tests

    • File: agents.py
    • Description: Test the creation of user agents.
    • Code Snippet:
      def test_create_user_agent():
          user_agent = create_user_agent()
          assert isinstance(user_agent, UserProxyAgent)
          assert user_agent.name == "User"
  2. GitHub API Interaction Tests

    • File: git_utils.py
    • Description: Test GitHub client and repository retrieval.
    • Code Snippet:
      def test_get_github_client():
          client = get_github_client()
          assert isinstance(client, Github)
      
      def test_get_repository():
          client = get_github_client()
          repo = get_repository(client, "abuzarmahmood/test_repo")
          assert isinstance(repo, Repository)
  3. Response Generation Validation

    • File: response_agent.py
    • Description: Validate prompt generation for response agents.
    • Code Snippet:
      def test_generate_prompt():
          issue = mock_issue()
          prompt = generate_prompt("edit_assistant", "abuzarmahmood/test_repo", "/path/to/repo", {}, issue)
          assert "Suggest what changes can be made to resolve this issue" in prompt
  4. Branch Management Tests

    • File: branch_handler.py
    • Description: Test branch checkout functionality.
    • Code Snippet:
      def test_checkout_branch():
          checkout_branch("/path/to/repo", "test-branch", create=True)
          assert get_current_branch("/path/to/repo") == "test-branch"
  5. Trigger Detection Tests

    • File: triggers.py
    • Description: Test detection of specific tags in issues.
    • Code Snippet:
      def test_has_blech_bot_tag():
          issue = mock_issue_with_label("blech_bot")
          assert has_blech_bot_tag(issue) is True
  6. Utility Function Tests

    • File: bot_tools.py
    • Description: Test token estimation utility.
    • Code Snippet:
      def test_estimate_tokens():
          text = "This is a test string."
          assert estimate_tokens(text) == 5
  7. Testing Response Agent Flows

    • File: response_agent.py
    • Description: Test the creation and management of issues and pull requests.
    • Code Snippet:
      def test_response_agent_flows():
          client = get_github_client()
          repo = get_repository(client, "abuzarmahmood/test_repo")
          issue = repo.create_issue(title="Test Issue", body="This is a test issue.")
          pr = repo.create_pull(title="Test PR", body="This is a test pull request.", head="test-branch", base="main")
          
          # Ensure issue and PR are created
          assert issue is not None
          assert pr is not None
          
          # Clean up after test
          issue.edit(state="closed")
          pr.edit(state="closed")

By implementing these tests, the GitHub bot's functionality can be thoroughly validated, ensuring it operates correctly across various scenarios, including the creation and management of issues and pull requests.


This response was automatically generated by blech_bot using model gpt-4o

Aider output:

View Aider Output
The --sonnet flag is deprecated and will be removed in a future version. Please use --model sonnet instead.
Aider v0.80.1
Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, infinite output
Weak model: anthropic/claude-3-5-haiku-20241022
Git repo: .git with 13 files
Repo-map: using 4096 tokens, auto refresh


src/agents.py

src/bot_tools.py

src/branch_handler.py

src/git_utils.py

src/response_agent.py

src/triggers.py
I'll create test files for the GitHub bot functionality. Based on your request, I'll focus on developing tests for the core        
components of the bot.                                                                                                             

Let's create a test directory and test files for each of the main components:                                                      

tests/test_agents.py                                                                                                               

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the agents module                                                                                                        
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.agents import (                                                                                                           
    create_user_agent,                                                                                                             
    create_agent,                                                                                                                  
    generate_prompt,                                                                                                               
    is_terminate_msg,                                                                                                              
    register_functions                                                                                                             
)                                                                                                                                  
from autogen import UserProxyAgent, AssistantAgent                                                                                 
                                                                                                                                   
                                                                                                                                   
def test_create_user_agent():                                                                                                      
    """Test creation of user agent"""                                                                                              
    user_agent = create_user_agent()                                                                                               
    assert isinstance(user_agent, UserProxyAgent)                                                                                  
    assert user_agent.name == "User"                                                                                               
    assert user_agent.human_input_mode == "NEVER"                                                                                  
                                                                                                                                   
                                                                                                                                   
def test_create_agent():                                                                                                           
    """Test creation of assistant agent"""                                                                                         
    llm_config = {"model": "test-model", "api_key": "test-key"}                                                                    
    agent = create_agent("file_assistant", llm_config)                                                                             
    assert isinstance(agent, AssistantAgent)                                                                                       
    assert agent.name == "file_assistant"                                                                                          
    assert "analyze this GitHub issue" in agent.system_message.lower()                                                             
                                                                                                                                   
                                                                                                                                   
def test_is_terminate_msg():                                                                                                       
    """Test  message detection"""                                                                                         
    assert is_terminate_msg({"content": "Done. "}) is True                                                                
    assert is_terminate_msg({"content": "Not done yet"}) is False                                                                  
    assert is_terminate_msg({"content": "."}) is True                                                                     
    assert is_terminate_msg({"content": ""}) is False                                                                              
                                                                                                                                   
                                                                                                                                   
@patch('src.agents.parse_comments')                                                                                                
def test_generate_prompt(mock_parse_comments):                                                                                     
    """Test prompt generation for different agent types"""                                                                         
    # Setup mock                                                                                                                   
    mock_parse_comments.return_value = ("Last comment", "Comments string", ["comment1"])                                           
                                                                                                                                   
    # Mock issue and details                                                                                                       
    issue = MagicMock()                                                                                                            
    issue.number = 123                                                                                                             
    issue.title = "Test Issue"                                                                                                     
                                                                                                                                   
    details = {                                                                                                                    
        "title": "Test Issue",                                                                                                     
        "body": "This is a test issue"                                                                                             
    }                                                                                                                              
                                                                                                                                   
    # Test file_assistant prompt                                                                                                   
    prompt = generate_prompt("file_assistant", "test/repo", "/path/to/repo", details, issue)                                       
    assert "Please analyze this GitHub issue" in prompt                                                                            
    assert "Repository: test/repo" in prompt                                                                                       
                                                                                                                                   
    # Test edit_assistant prompt                                                                                                   
    prompt = generate_prompt("edit_assistant", "test/repo", "/path/to/repo", details, issue)                                       
    assert "Suggest what changes can be made to resolve this issue" in prompt                                                      
                                                                                                                                   
    # Test feedback_assistant prompt                                                                                               
    prompt = generate_prompt(                                                                                                      
        "feedback_assistant",                                                                                                      
        "test/repo",                                                                                                               
        "/path/to/repo",                                                                                                           
        details,                                                                                                                   
        issue,                                                                                                                     
        original_response="Original response",                                                                                     
        feedback_text="Feedback text"                                                                                              
    )                                                                                                                              
    assert "Process this user feedback" in prompt                                                                                  
    assert "Original response" in prompt                                                                                           
    assert "Feedback text" in prompt                                                                                               
                                                                                                                                   
                                                                                                                                   
def test_register_functions():                                                                                                     
    """Test function registration with agent"""                                                                                    
    agent = MagicMock()                                                                                                            
    agent.register_for_llm = MagicMock(return_value=lambda x: x)                                                                   
    agent.register_for_execution = MagicMock(return_value=lambda x: x)                                                             
                                                                                                                                   
    # Define test function                                                                                                         
    def test_func():                                                                                                               
        """Test function docstring"""                                                                                              
        pass                                                                                                                       
                                                                                                                                   
    # Test LLM registration                                                                                                        
    result = register_functions(agent, "llm", [test_func])                                                                         
    assert agent.register_for_llm.called                                                                                           
    assert agent.register_for_llm.call_args[1]["name"] == "test_func"                                                              
    assert "Test function docstring" in agent.register_for_llm.call_args[1]["description"]                                         
                                                                                                                                   
    # Test execution registration                                                                                                  
    agent.reset_mock()                                                                                                             
    result = register_functions(agent, "execution", [test_func])                                                                   
    assert agent.register_for_execution.called                                                                                     
    assert agent.register_for_execution.call_args[1]["name"] == "test_func"                                                        
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_git_utils.py                                                                                                            

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the git_utils module                                                                                                     
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.git_utils import (                                                                                                        
    clean_response,                                                                                                                
    get_github_client,                                                                                                             
    get_repository,                                                                                                                
    get_issue_comments,                                                                                                            
    get_issue_details,                                                                                                             
    write_issue_response,                                                                                                          
    is_pull_request                                                                                                                
)                                                                                                                                  
from github import Github                                                                                                          
from github.Repository import Repository                                                                                           
                                                                                                                                   
                                                                                                                                   
def test_clean_response():                                                                                                         
    """Test cleaning response text"""                                                                                              
    # Test removing                                                                                                       
    response = "This is a response. "                                                                                     
    cleaned = clean_response(response)                                                                                             
    assert "" not in cleaned                                                                                              
    assert cleaned == "This is a response."                                                                                        
                                                                                                                                   
    # Test handling signatures                                                                                                     
    response = "Response\n\n---\n*This response was automatically generated by blech_bot*"                                         
    cleaned = clean_response(response)                                                                                             
    assert cleaned == response                                                                                                     
                                                                                                                                   
    # Test handling duplicate signatures                                                                                           
    response = "Response\n\n---\n*This response was automatically generated by blech_bot*\n\n---\n*This response was automatically 
generated by blech_bot*"                                                                                                           
    cleaned = clean_response(response)                                                                                             
    assert cleaned.count("*This response was automatically generated by blech_bot*") == 1                                          
                                                                                                                                   
                                                                                                                                   
@patch('src.git_utils.Github')                                                                                                     
@patch('src.git_utils.os')                                                                                                         
def test_get_github_client(mock_os, mock_github):                                                                                  
    """Test GitHub client initialization"""                                                                                        
    # Setup mock                                                                                                                   
    mock_os.getenv.return_value = "test-token"                                                                                     
    mock_github.return_value = "github-client"                                                                                     
                                                                                                                                   
    # Call function                                                                                                                
    client = get_github_client()                                                                                                   
                                                                                                                                   
    # Verify                                                                                                                       
    mock_os.getenv.assert_called_with('GITHUB_TOKEN')                                                                              
    mock_github.assert_called_with("test-token")                                                                                   
    assert client == "github-client"                                                                                               
                                                                                                                                   
    # Test error case                                                                                                              
    mock_os.getenv.return_value = None                                                                                             
    with pytest.raises(ValueError):                                                                                                
        get_github_client()                                                                                                        
                                                                                                                                   
                                                                                                                                   
@patch('src.git_utils.get_github_client')                                                                                          
def test_get_repository(mock_get_client):                                                                                          
    """Test repository retrieval"""                                                                                                
    # Setup mock                                                                                                                   
    mock_client = MagicMock()                                                                                                      
    mock_repo = MagicMock(spec=Repository)                                                                                         
    mock_client.get_repo.return_value = mock_repo                                                                                  
    mock_get_client.return_value = mock_client                                                                                     
                                                                                                                                   
    # Call function                                                                                                                
    repo = get_repository(mock_client, "test/repo")                                                                                
                                                                                                                                   
    # Verify                                                                                                                       
    mock_client.get_repo.assert_called_with("test/repo")                                                                           
    assert repo == mock_repo                                                                                                       
                                                                                                                                   
    # Test error case                                                                                                              
    mock_client.get_repo.side_effect = Exception("Repo not found")                                                                 
    with pytest.raises(ValueError):                                                                                                
        get_repository(mock_client, "nonexistent/repo")                                                                            
                                                                                                                                   
                                                                                                                                   
def test_get_issue_comments():                                                                                                     
    """Test filtering issue comments"""                                                                                            
    # Create mock issue with comments                                                                                              
    issue = MagicMock()                                                                                                            
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "Comment with app.grapite.dev reference"                                                                       
                                                                                                                                   
    # Setup mock comments                                                                                                          
    issue.get_comments.return_value = [comment1, comment2]                                                                         
                                                                                                                                   
    # Call function                                                                                                                
    comments = get_issue_comments(issue)                                                                                           
                                                                                                                                   
    # Verify filtering                                                                                                             
    assert len(comments) == 1                                                                                                      
    assert comments[0].body == "Normal comment"                                                                                    
                                                                                                                                   
                                                                                                                                   
def test_get_issue_details():                                                                                                      
    """Test extracting issue details"""                                                                                            
    # Create mock issue                                                                                                            
    issue = MagicMock()                                                                                                            
    issue.number = 123                                                                                                             
    issue.title = "Test Issue"                                                                                                     
    issue.body = "Issue body"                                                                                                      
    issue.state = "open"                                                                                                           
    issue.created_at = "2023-01-01"                                                                                                
    issue.updated_at = "2023-01-02"                                                                                                
    issue.comments = 5                                                                                                             
                                                                                                                                   
    label = MagicMock()                                                                                                            
    label.name = "bug"                                                                                                             
    issue.labels = [label]                                                                                                         
                                                                                                                                   
    assignee = MagicMock()                                                                                                         
    assignee.login = "testuser"                                                                                                    
    issue.assignees = [assignee]                                                                                                   
                                                                                                                                   
    # Call function                                                                                                                
    details = get_issue_details(issue)                                                                                             
                                                                                                                                   
    # Verify                                                                                                                       
    assert details["number"] == 123                                                                                                
    assert details["title"] == "Test Issue"                                                                                        
    assert details["body"] == "Issue body"                                                                                         
    assert details["state"] == "open"                                                                                              
    assert details["created_at"] == "2023-01-01"                                                                                   
    assert details["updated_at"] == "2023-01-02"                                                                                   
    assert details["comments_count"] == 5                                                                                          
    assert details["labels"] == ["bug"]                                                                                            
    assert details["assignees"] == ["testuser"]                                                                                    
                                                                                                                                   
                                                                                                                                   
@patch('src.git_utils.create_issue_comment')                                                                                       
def test_write_issue_response(mock_create_comment):                                                                                
    """Test writing response to issue"""                                                                                           
    # Setup                                                                                                                        
    issue = MagicMock()                                                                                                            
    response = "Test response"                                                                                                     
                                                                                                                                   
    # Call function                                                                                                                
    write_issue_response(issue, response)                                                                                          
                                                                                                                                   
    # Verify signature was added                                                                                                   
    mock_create_comment.assert_called_once()                                                                                       
    called_with = mock_create_comment.call_args[0][1]                                                                              
    assert "Test response" in called_with                                                                                          
    assert "*This response was automatically generated by blech_bot" in called_with                                                
                                                                                                                                   
                                                                                                                                   
def test_is_pull_request():                                                                                                        
    """Test detection of pull requests"""                                                                                          
    # Create mock issue and PR                                                                                                     
    issue = MagicMock()                                                                                                            
    issue.html_url = "https://github.com/test/repo/issues/1"                                                                       
                                                                                                                                   
    pr = MagicMock()                                                                                                               
    pr.html_url = "https://github.com/test/repo/pull/2"                                                                            
                                                                                                                                   
    # Test                                                                                                                         
    assert is_pull_request(issue) is False                                                                                         
    assert is_pull_request(pr) is True                                                                                             
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_branch_handler.py                                                                                                       

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the branch_handler module                                                                                                
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.branch_handler import (                                                                                                   
    get_issue_related_branches,                                                                                                    
    get_current_branch,                                                                                                            
    checkout_branch,                                                                                                               
    delete_branch,                                                                                                                 
    back_to_master_branch,                                                                                                         
    push_changes                                                                                                                   
)                                                                                                                                  
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.os')                                                                                                    
@patch('src.branch_handler.git.Repo')                                                                                              
def test_get_issue_related_branches(mock_repo, mock_os):                                                                           
    """Test finding branches related to an issue"""                                                                                
    # Setup mocks                                                                                                                  
    mock_issue = MagicMock()                                                                                                       
    mock_issue.number = 123                                                                                                        
    mock_issue.title = "Test Issue"                                                                                                
                                                                                                                                   
    mock_os.getcwd.return_value = "/original/dir"                                                                                  
    mock_os.popen.return_value.read.return_value = "branch-123\thttp://github.com/test/repo"                                       
                                                                                                                                   
    # Call function                                                                                                                
    branches = get_issue_related_branches("/path/to/repo", mock_issue)                                                             
                                                                                                                                   
    # Verify                                                                                                                       
    mock_os.chdir.assert_any_call("/path/to/repo")                                                                                 
    mock_os.chdir.assert_called_with("/original/dir")                                                                              
    mock_os.popen.assert_called_with("gh issue develop -l 123")                                                                    
    assert branches == [("branch-123", "http://github.com/test/repo")]                                                             
                                                                                                                                   
    # Test fallback when gh command returns no branches                                                                            
    mock_os.popen.return_value.read.return_value = ""                                                                              
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
    mock_repo_instance.heads = []                                                                                                  
    mock_repo_instance.git.ls_remote.return_value = ""                                                                             
                                                                                                                                   
    branches = get_issue_related_branches("/path/to/repo", mock_issue)                                                             
    assert branches == []                                                                                                          
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.git.Repo')                                                                                              
def test_get_current_branch(mock_repo):                                                                                            
    """Test getting current branch name"""                                                                                         
    # Setup mock                                                                                                                   
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
    mock_repo_instance.active_branch.name = "test-branch"                                                                          
                                                                                                                                   
    # Call function                                                                                                                
    branch = get_current_branch("/path/to/repo")                                                                                   
                                                                                                                                   
    # Verify                                                                                                                       
    mock_repo.assert_called_with("/path/to/repo")                                                                                  
    assert branch == "test-branch"                                                                                                 
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.git.Repo')                                                                                              
def test_checkout_branch(mock_repo):                                                                                               
    """Test branch checkout functionality"""                                                                                       
    # Setup mock                                                                                                                   
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
    mock_repo_instance.heads = ["main"]                                                                                            
                                                                                                                                   
    # Test creating new branch                                                                                                     
    checkout_branch("/path/to/repo", "test-branch", create=True)                                                                   
                                                                                                                                   
    # Verify                                                                                                                       
    mock_repo.assert_called_with("/path/to/repo")                                                                                  
    mock_repo_instance.git.clean.assert_called_with('-f')                                                                          
    mock_repo_instance.create_head.assert_called_with("test-branch")                                                               
    mock_repo_instance.git.checkout.assert_called_with("test-branch")                                                              
    mock_repo_instance.git.reset.assert_called_with('--hard', 'origin/test-branch')                                                
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.git.Repo')                                                                                              
def test_delete_branch(mock_repo):                                                                                                 
    """Test branch deletion"""                                                                                                     
    # Setup mock                                                                                                                   
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
    mock_repo_instance.heads = ["test-branch"]                                                                                     
                                                                                                                                   
    # Call function                                                                                                                
    delete_branch("/path/to/repo", "test-branch", force=True)                                                                      
                                                                                                                                   
    # Verify                                                                                                                       
    mock_repo.assert_called_with("/path/to/repo")                                                                                  
    mock_repo_instance.delete_head.assert_called_with("test-branch", force=True)                                                   
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.git.Repo')                                                                                              
def test_back_to_master_branch(mock_repo):                                                                                         
    """Test switching back to master/main branch"""                                                                                
    # Setup mock                                                                                                                   
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
                                                                                                                                   
    # Test with master branch                                                                                                      
    mock_repo_instance.heads = ["master", "other"]                                                                                 
    back_to_master_branch("/path/to/repo")                                                                                         
    mock_repo_instance.git.checkout.assert_called_with("master")                                                                   
                                                                                                                                   
    # Test with main branch                                                                                                        
    mock_repo_instance.heads = ["main", "other"]                                                                                   
    back_to_master_branch("/path/to/repo")                                                                                         
    mock_repo_instance.git.checkout.assert_called_with("main")                                                                     
                                                                                                                                   
    # Test with neither branch                                                                                                     
    mock_repo_instance.heads = ["develop", "other"]                                                                                
    with pytest.raises(ValueError):                                                                                                
        back_to_master_branch("/path/to/repo")                                                                                     
                                                                                                                                   
                                                                                                                                   
@patch('src.branch_handler.git.Repo')                                                                                              
def test_push_changes(mock_repo):                                                                                                  
    """Test pushing changes to remote"""                                                                                           
    # Setup mock                                                                                                                   
    mock_repo_instance = MagicMock()                                                                                               
    mock_repo.return_value = mock_repo_instance                                                                                    
    mock_repo_instance.active_branch.name = "test-branch"                                                                          
                                                                                                                                   
    # Test normal push                                                                                                             
    push_changes("/path/to/repo")                                                                                                  
    mock_repo_instance.git.push.assert_called_with('origin', 'test-branch')                                                        
                                                                                                                                   
    # Test force push                                                                                                              
    push_changes("/path/to/repo", force=True)                                                                                      
    mock_repo_instance.git.push.assert_called_with('origin', 'test-branch', '--force')                                             
                                                                                                                                   
    # Test with specific branch                                                                                                    
    push_changes("/path/to/repo", branch_name="feature-branch")                                                                    
    mock_repo_instance.git.push.assert_called_with('origin', 'feature-branch')                                                     
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_triggers.py                                                                                                             

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the triggers module                                                                                                      
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.triggers import (                                                                                                         
    has_blech_bot_tag,                                                                                                             
    has_generate_edit_command_trigger,                                                                                             
    has_bot_response,                                                                                                              
    has_user_feedback,                                                                                                             
    has_develop_issue_trigger,                                                                                                     
    has_pull_request_trigger,                                                                                                      
    has_pr_creation_comment                                                                                                        
)                                                                                                                                  
                                                                                                                                   
                                                                                                                                   
def test_has_blech_bot_tag():                                                                                                      
    """Test detection of blech_bot tag"""                                                                                          
    # Create mock issue with blech_bot label                                                                                       
    issue_with_tag = MagicMock()                                                                                                   
    label = MagicMock()                                                                                                            
    label.name = "blech_bot"                                                                                                       
    issue_with_tag.labels = [label]                                                                                                
                                                                                                                                   
    # Create mock issue without blech_bot label                                                                                    
    issue_without_tag = MagicMock()                                                                                                
    other_label = MagicMock()                                                                                                      
    other_label.name = "bug"                                                                                                       
    issue_without_tag.labels = [other_label]                                                                                       
                                                                                                                                   
    # Test                                                                                                                         
    assert has_blech_bot_tag(issue_with_tag) is True                                                                               
    assert has_blech_bot_tag(issue_without_tag) is False                                                                           
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_generate_edit_command_trigger(mock_get_comments):                                                                     
    """Test detection of generate_edit_command trigger"""                                                                          
    # Setup mock comments                                                                                                          
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "[ generate_edit_command ]"                                                                                    
                                                                                                                                   
    # Test with trigger                                                                                                            
    mock_get_comments.return_value = [comment1, comment2]                                                                          
    assert has_generate_edit_command_trigger(MagicMock()) is True                                                                  
                                                                                                                                   
    # Test without trigger                                                                                                         
    mock_get_comments.return_value = [comment1]                                                                                    
    assert has_generate_edit_command_trigger(MagicMock()) is False                                                                 
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_bot_response(mock_get_comments):                                                                                      
    """Test detection of bot response"""                                                                                           
    # Setup mock comments                                                                                                          
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "This comment was generated by blech_bot"                                                                      
                                                                                                                                   
    # Test with bot response                                                                                                       
    mock_get_comments.return_value = [comment1, comment2]                                                                          
    assert has_bot_response(MagicMock()) is True                                                                                   
                                                                                                                                   
    # Test without bot response                                                                                                    
    mock_get_comments.return_value = [comment1]                                                                                    
    assert has_bot_response(MagicMock()) is False                                                                                  
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_user_feedback(mock_get_comments):                                                                                     
    """Test detection of user feedback after bot response"""                                                                       
    # Setup mock comments                                                                                                          
    bot_comment = MagicMock()                                                                                                      
    bot_comment.body = "This comment was generated by blech_bot"                                                                   
    user_comment = MagicMock()                                                                                                     
    user_comment.body = "User feedback"                                                                                            
                                                                                                                                   
    # Test with user feedback after bot comment                                                                                    
    mock_get_comments.return_value = [bot_comment, user_comment]                                                                   
    assert has_user_feedback(MagicMock()) is True                                                                                  
                                                                                                                                   
    # Test without user feedback after bot comment                                                                                 
    mock_get_comments.return_value = [user_comment, bot_comment]                                                                   
    assert has_user_feedback(MagicMock()) is False                                                                                 
                                                                                                                                   
    # Test with no bot comment                                                                                                     
    mock_get_comments.return_value = [user_comment]                                                                                
    assert has_user_feedback(MagicMock()) is False                                                                                 
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_develop_issue_trigger(mock_get_comments):                                                                             
    """Test detection of develop_issue trigger"""                                                                                  
    # Setup mock comments                                                                                                          
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "[ develop_issue ]"                                                                                            
                                                                                                                                   
    # Test with trigger in last comment                                                                                            
    mock_get_comments.return_value = [comment1, comment2]                                                                          
    assert has_develop_issue_trigger(MagicMock()) is True                                                                          
                                                                                                                                   
    # Test with trigger not in last comment                                                                                        
    mock_get_comments.return_value = [comment2, comment1]                                                                          
    assert has_develop_issue_trigger(MagicMock()) is False                                                                         
                                                                                                                                   
    # Test with no comments                                                                                                        
    mock_get_comments.return_value = []                                                                                            
    assert has_develop_issue_trigger(MagicMock()) is False                                                                         
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_pull_request_trigger(mock_get_comments):                                                                              
    """Test detection of pull request trigger"""                                                                                   
    # Setup mock comments                                                                                                          
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "Created pull request"                                                                                         
                                                                                                                                   
    # Test with trigger in last comment                                                                                            
    mock_get_comments.return_value = [comment1, comment2]                                                                          
    assert has_pull_request_trigger(MagicMock()) is True                                                                           
                                                                                                                                   
    # Test with trigger not in last comment                                                                                        
    mock_get_comments.return_value = [comment2, comment1]                                                                          
    assert has_pull_request_trigger(MagicMock()) is False                                                                          
                                                                                                                                   
    # Test with no comments                                                                                                        
    mock_get_comments.return_value = []                                                                                            
    assert has_pull_request_trigger(MagicMock()) is False                                                                          
                                                                                                                                   
                                                                                                                                   
@patch('src.triggers.get_issue_comments')                                                                                          
def test_has_pr_creation_comment(mock_get_comments):                                                                               
    """Test detection of PR creation comment"""                                                                                    
    # Setup mock comments                                                                                                          
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Normal comment"                                                                                               
    comment2 = MagicMock()                                                                                                         
    comment2.body = "Created pull request https://github.com/test/repo/pull/1"                                                     
                                                                                                                                   
    # Test with PR creation comment                                                                                                
    mock_get_comments.return_value = [comment1, comment2]                                                                          
    has_comment, comment_body = has_pr_creation_comment(MagicMock())                                                               
    assert has_comment is True                                                                                                     
    assert comment_body == "Created pull request https://github.com/test/repo/pull/1"                                              
                                                                                                                                   
    # Test without PR creation comment                                                                                             
    mock_get_comments.return_value = [comment1]                                                                                    
    has_comment, comment_body = has_pr_creation_comment(MagicMock())                                                               
    assert has_comment is False                                                                                                    
    assert comment_body is None                                                                                                    
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_bot_tools.py                                                                                                            

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the bot_tools module                                                                                                     
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.bot_tools import (                                                                                                        
    get_local_repo_path,                                                                                                           
    search_for_pattern,                                                                                                            
    search_for_file,                                                                                                               
    estimate_tokens,                                                                                                               
    readfile,                                                                                                                      
    readlines                                                                                                                      
)                                                                                                                                  
                                                                                                                                   
                                                                                                                                   
def test_get_local_repo_path():                                                                                                    
    """Test getting local repository path"""                                                                                       
    # Test with existing repo                                                                                                      
    with patch('os.path.exists', return_value=True):                                                                               
        path = get_local_repo_path("owner/repo")                                                                                   
        assert "owner/repo" in path                                                                                                
        assert path.endswith("owner/repo")                                                                                         
                                                                                                                                   
    # Test with non-existing repo                                                                                                  
    with patch('os.path.exists', return_value=False):                                                                              
        result = get_local_repo_path("nonexistent/repo")                                                                           
        assert "not found" in result                                                                                               
                                                                                                                                   
                                                                                                                                   
@patch('os.popen')                                                                                                                 
def test_search_for_pattern(mock_popen):                                                                                           
    """Test searching for pattern in files"""                                                                                      
    # Setup mock                                                                                                                   
    mock_popen.return_value.read.return_value = "/path/to/file1.py\n/path/to/file2.py"                                             
                                                                                                                                   
    # Call function                                                                                                                
    result = search_for_pattern("/search/dir", "pattern")                                                                          
                                                                                                                                   
    # Verify                                                                                                                       
    mock_popen.assert_called_with("grep -irl pattern /search/dir --include='*.py'")                                                
    assert result == "/path/to/file1.py\n/path/to/file2.py"                                                                        
                                                                                                                                   
                                                                                                                                   
@patch('os.popen')                                                                                                                 
def test_search_for_file(mock_popen):                                                                                              
    """Test searching for file by name"""                                                                                          
    # Setup mock                                                                                                                   
    mock_popen.return_value.read.return_value = "/path/to/file.py"                                                                 
                                                                                                                                   
    # Call function                                                                                                                
    result = search_for_file("/search/dir", "file.py")                                                                             
                                                                                                                                   
    # Verify                                                                                                                       
    mock_popen.assert_called_with("find /search/dir -iname '*file.py*'")                                                           
    assert result == "/path/to/file.py"                                                                                            
                                                                                                                                   
    # Test file not found                                                                                                          
    mock_popen.return_value.read.return_value = ""                                                                                 
    result = search_for_file("/search/dir", "nonexistent.py")                                                                      
    assert result == "File not found"                                                                                              
                                                                                                                                   
                                                                                                                                   
def test_estimate_tokens():                                                                                                        
    """Test token estimation"""                                                                                                    
    # Test with normal text                                                                                                        
    text = "This is a test string with multiple words."                                                                            
    assert estimate_tokens(text) == 8                                                                                              
                                                                                                                                   
    # Test with empty text                                                                                                         
    assert estimate_tokens("") == 0                                                                                                
                                                                                                                                   
    # Test with None                                                                                                               
    assert estimate_tokens(None) == 0                                                                                              
                                                                                                                                   
                                                                                                                                   
@patch('builtins.open')                                                                                                            
def test_readfile(mock_open):                                                                                                      
    """Test reading file with line numbers"""                                                                                      
    # Setup mock                                                                                                                   
    mock_file = MagicMock()                                                                                                        
    mock_file.__enter__.return_value.readlines.return_value = ["Line 1\n", "Line 2\n", "Line 3\n"]                                 
    mock_open.return_value = mock_file                                                                                             
                                                                                                                                   
    # Call function                                                                                                                
    result = readfile("/path/to/file.py")                                                                                          
                                                                                                                                   
    # Verify                                                                                                                       
    mock_open.assert_called_with("/path/to/file.py", 'r')                                                                          
    assert "0000: Line 1" in result                                                                                                
    assert "0001: Line 2" in result                                                                                                
    assert "0002: Line 3" in result                                                                                                
                                                                                                                                   
    # Test file not found                                                                                                          
    mock_open.side_effect = FileNotFoundError()                                                                                    
    result = readfile("/nonexistent/file.py")                                                                                      
    assert "File not found" in result                                                                                              
                                                                                                                                   
    # Test other error                                                                                                             
    mock_open.side_effect = Exception("Test error")                                                                                
    result = readfile("/error/file.py")                                                                                            
    assert "Error reading file" in result                                                                                          
                                                                                                                                   
                                                                                                                                   
@patch('builtins.open')                                                                                                            
def test_readlines(mock_open):                                                                                                     
    """Test reading specific lines from file"""                                                                                    
    # Setup mock                                                                                                                   
    mock_file = MagicMock()                                                                                                        
    mock_file.__enter__.return_value.readlines.return_value = [                                                                    
        "Line 1\n", "Line 2\n", "Line 3\n", "Line 4\n", "Line 5\n"                                                                 
    ]                                                                                                                              
    mock_open.return_value = mock_file                                                                                             
                                                                                                                                   
    # Call function                                                                                                                
    result = readlines("/path/to/file.py", 1, 4)                                                                                   
                                                                                                                                   
    # Verify                                                                                                                       
    mock_open.assert_called_with("/path/to/file.py", 'r')                                                                          
    assert "0001: Line 2" in result                                                                                                
    assert "0002: Line 3" in result                                                                                                
    assert "0003: Line 4" in result                                                                                                
    assert "0000: Line 1" not in result                                                                                            
    assert "0004: Line 5" not in result                                                                                            
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_response_agent.py                                                                                                       

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Tests for the response_agent module                                                                                                
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.response_agent import (                                                                                                   
    clean_response,                                                                                                                
    check_not_empty,                                                                                                               
    check_triggers,                                                                                                                
    response_selector,                                                                                                             
    extract_urls_from_issue,                                                                                                       
    scrape_text_from_url,                                                                                                          
    summarize_text,                                                                                                                
    get_tracked_repos                                                                                                              
)                                                                                                                                  
                                                                                                                                   
                                                                                                                                   
def test_clean_response():                                                                                                         
    """Test cleaning response text"""                                                                                              
    # Test removing                                                                                                       
    response = "This is a response. "                                                                                     
    cleaned = clean_response(response)                                                                                             
    assert "" not in cleaned                                                                                              
    assert cleaned == "This is a response."                                                                                        
                                                                                                                                   
    # Test handling model signatures                                                                                               
    response = "Response\n\n---\n*This response was automatically generated by blech_bot using model gpt-4*"                       
    cleaned = clean_response(response)                                                                                             
    assert cleaned == response                                                                                                     
                                                                                                                                   
    # Test handling basic signatures                                                                                               
    response = "Response\n\n---\n*This response was automatically generated by blech_bot*"                                         
    cleaned = clean_response(response)                                                                                             
    assert cleaned == response                                                                                                     
                                                                                                                                   
                                                                                                                                   
def test_check_not_empty():                                                                                                        
    """Test checking if response is not empty"""                                                                                   
    assert check_not_empty("This is a response") is True                                                                           
    assert check_not_empty("") is False                                                                                            
    assert check_not_empty("") is False                                                                                   
    assert check_not_empty("") is False                                                                                   
    assert check_not_empty("This is a response. ") is True                                                                
                                                                                                                                   
                                                                                                                                   
@patch('src.response_agent.triggers')                                                                                              
def test_check_triggers(mock_triggers):                                                                                            
    """Test checking for response triggers"""                                                                                      
    issue = MagicMock()                                                                                                            
                                                                                                                                   
    # Test generate_edit_command trigger                                                                                           
    mock_triggers.has_generate_edit_command_trigger.return_value = True                                                            
    mock_triggers.has_user_feedback.return_value = False                                                                           
    mock_triggers.has_bot_response.return_value = False                                                                            
    assert check_triggers(issue) == "generate_edit_command"                                                                        
                                                                                                                                   
    # Test user feedback trigger                                                                                                   
    mock_triggers.has_generate_edit_command_trigger.return_value = False                                                           
    mock_triggers.has_user_feedback.return_value = True                                                                            
    mock_triggers.has_bot_response.return_value = True                                                                             
    assert check_triggers(issue) == "feedback"                                                                                     
                                                                                                                                   
    # Test new response trigger                                                                                                    
    mock_triggers.has_generate_edit_command_trigger.return_value = False                                                           
    mock_triggers.has_user_feedback.return_value = False                                                                           
    mock_triggers.has_bot_response.return_value = False                                                                            
    assert check_triggers(issue) == "new_response"                                                                                 
                                                                                                                                   
    # Test no trigger                                                                                                              
    mock_triggers.has_generate_edit_command_trigger.return_value = False                                                           
    mock_triggers.has_user_feedback.return_value = False                                                                           
    mock_triggers.has_bot_response.return_value = True                                                                             
    assert check_triggers(issue) is None                                                                                           
                                                                                                                                   
                                                                                                                                   
def test_response_selector():                                                                                                      
    """Test selecting response function based on trigger"""                                                                        
    # Test feedback trigger                                                                                                        
    func = response_selector("feedback")                                                                                           
    assert func.__name__ == "generate_feedback_response"                                                                           
                                                                                                                                   
    # Test generate_edit_command trigger                                                                                           
    func = response_selector("generate_edit_command")                                                                              
    assert func.__name__ == "generate_edit_command_response"                                                                       
                                                                                                                                   
    # Test new_response trigger                                                                                                    
    func = response_selector("new_response")                                                                                       
    assert func.__name__ == "generate_new_response"                                                                                
                                                                                                                                   
    # Test invalid trigger                                                                                                         
    assert response_selector("invalid") is None                                                                                    
                                                                                                                                   
                                                                                                                                   
@patch('src.response_agent.get_issue_comments')                                                                                    
def test_extract_urls_from_issue(mock_get_comments):                                                                               
    """Test extracting URLs from issue and comments"""                                                                             
    # Setup mock                                                                                                                   
    issue = MagicMock()                                                                                                            
    issue.body = "Issue with URL: https://example.com"                                                                             
                                                                                                                                   
    comment1 = MagicMock()                                                                                                         
    comment1.body = "Comment with URL: https://github.com"                                                                         
    comment2 = MagicMock()                                                                                                         
    comment2.body = "Another comment with same URL: https://github.com"                                                            
                                                                                                                                   
    mock_get_comments.return_value = [comment1, comment2]                                                                          
                                                                                                                                   
    # Call function                                                                                                                
    urls = extract_urls_from_issue(issue)                                                                                          
                                                                                                                                   
    # Verify                                                                                                                       
    assert len(urls) == 2                                                                                                          
    assert "https://example.com" in urls                                                                                           
    assert "https://github.com" in urls                                                                                            
                                                                                                                                   
                                                                                                                                   
@patch('src.response_agent.requests.get')                                                                                          
def test_scrape_text_from_url(mock_get):                                                                                           
    """Test scraping text content from URL"""                                                                                      
    # Setup mock for HTML response                                                                                                 
    mock_response = MagicMock()                                                                                                    
    mock_response.text = "<html><body><p>Test content</p></body></html>"                                                           
    mock_response.headers = {"Content-Type": "text/html"}                                                                          
    mock_get.return_value = mock_response                                                                                          
                                                                                                                                   
    # Call function                                                                                                                
    result = scrape_text_from_url("https://example.com")                                                                           
                                                                                                                                   
    # Verify                                                                                                                       
    assert "Test content" in result                                                                                                
                                                                                                                                   
    # Test non-text content                                                                                                        
    mock_response.headers = {"Content-Type": "application/pdf"}                                                                    
    result = scrape_text_from_url("https://example.com/file.pdf")                                                                  
    assert "Non-text content detected" in result                                                                                   
                                                                                                                                   
    # Test request exception                                                                                                       
    mock_get.side_effect = Exception("Connection error")                                                                           
    result = scrape_text_from_url("https://example.com")                                                                           
    assert "Error fetching URL" in result                                                                                          
                                                                                                                                   
                                                                                                                                   
def test_summarize_text():                                                                                                         
    """Test summarizing text to maximum length"""                                                                                  
    # Test text under max length                                                                                                   
    short_text = "This is a short text."                                                                                           
    assert summarize_text(short_text, 100) == short_text                                                                           
                                                                                                                                   
    # Test text over max length                                                                                                    
    long_text = "This is a very long text that exceeds the maximum length."                                                        
    summary = summarize_text(long_text, 20)                                                                                        
    assert len(summary) > 20  # Account for ellipsis and message                                                                   
    assert "..." in summary                                                                                                        
    assert "[Text truncated" in summary                                                                                            
                                                                                                                                   
                                                                                                                                   
@patch('builtins.open')                                                                                                            
def test_get_tracked_repos(mock_open):                                                                                             
    """Test getting tracked repositories"""                                                                                        
    # Setup mock                                                                                                                   
    mock_file = MagicMock()                                                                                                        
    mock_file.__enter__.return_value.readlines.return_value = [                                                                    
        "owner1/repo1\n", "owner2/repo2\n"                                                                                         
    ]                                                                                                                              
    mock_open.return_value = mock_file                                                                                             
                                                                                                                                   
    # Call function                                                                                                                
    repos = get_tracked_repos()                                                                                                    
                                                                                                                                   
    # Verify                                                                                                                       
    assert len(repos) == 2                                                                                                         
    assert "owner1/repo1" in repos                                                                                                 
    assert "owner2/repo2" in repos                                                                                                 
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/init.py                                                                                                                      

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
# This file is intentionally empty to make the directory a Python package                                                          
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/conftest.py                                                                                                                  

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Pytest configuration file with fixtures                                                                                            
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock                                                                                                
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
                                                                                                                                   
@pytest.fixture                                                                                                                    
def mock_issue():                                                                                                                  
    """Create a mock GitHub issue"""                                                                                               
    issue = MagicMock()                                                                                                            
    issue.number = 123                                                                                                             
    issue.title = "Test Issue"                                                                                                     
    issue.body = "This is a test issue"                                                                                            
    issue.state = "open"                                                                                                           
    issue.html_url = "https://github.com/test/repo/issues/123"                                                                     
                                                                                                                                   
    # Add labels                                                                                                                   
    label = MagicMock()                                                                                                            
    label.name = "bug"                                                                                                             
    issue.labels = [label]                                                                                                         
                                                                                                                                   
    return issue                                                                                                                   
                                                                                                                                   
                                                                                                                                   
@pytest.fixture                                                                                                                    
def mock_issue_with_label(label_name="bug"):                                                                                       
    """Create a mock GitHub issue with specific label"""                                                                           
    def _create_issue(label_name):                                                                                                 
        issue = MagicMock()                                                                                                        
        issue.number = 123                                                                                                         
        issue.title = "Test Issue"                                                                                                 
        issue.body = "This is a test issue"                                                                                        
        issue.state = "open"                                                                                                       
                                                                                                                                   
        # Add label                                                                                                                
        label = MagicMock()                                                                                                        
        label.name = label_name                                                                                                    
        issue.labels = [label]                                                                                                     
                                                                                                                                   
        return issue                                                                                                               
                                                                                                                                   
    return _create_issue(label_name)                                                                                               
                                                                                                                                   
                                                                                                                                   
@pytest.fixture                                                                                                                    
def mock_pull_request():                                                                                                           
    """Create a mock GitHub pull request"""                                                                                        
    pr = MagicMock()                                                                                                               
    pr.number = 456                                                                                                                
    pr.title = "Test PR"                                                                                                           
    pr.body = "This is a test pull request"                                                                                        
    pr.state = "open"                                                                                                              
    pr.html_url = "https://github.com/test/repo/pull/456"                                                                          
                                                                                                                                   
    # Add head reference                                                                                                           
    head = MagicMock()                                                                                                             
    head.ref = "feature-branch"                                                                                                    
    pr.head = head                                                                                                                 
                                                                                                                                   
    return pr                                                                                                                      
                                                                                                                                   
                                                                                                                                   
@pytest.fixture                                                                                                                    
def mock_repository():                                                                                                             
    """Create a mock GitHub repository"""                                                                                          
    repo = MagicMock()                                                                                                             
    repo.full_name = "test/repo"                                                                                                   
    repo.name = "repo"                                                                                                             
    repo.clone_url = "https://github.com/test/repo.git"                                                                            
    repo.default_branch = "main"                                                                                                   
                                                                                                                                   
    return repo                                                                                                                    
                                                                                                                                   
                                                                                                                                   
@pytest.fixture                                                                                                                    
def mock_github_client():                                                                                                          
    """Create a mock GitHub client"""                                                                                              
    client = MagicMock()                                                                                                           
    return client                                                                                                                  
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

tests/test_integration.py                                                                                                          

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
"""                                                                                                                                
Integration tests for the GitHub bot                                                                                               
"""                                                                                                                                
import os                                                                                                                          
import sys                                                                                                                         
import pytest                                                                                                                      
from unittest.mock import MagicMock, patch                                                                                         
import tempfile                                                                                                                    
import shutil                                                                                                                      
                                                                                                                                   
# Add src directory to path                                                                                                        
src_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))                                                              
sys.path.append(src_dir)                                                                                                           
                                                                                                                                   
from src.response_agent import process_issue, process_repository                                                                   
from src.git_utils import get_github_client, get_repository                                                                        
                                                                                                                                   
                                                                                                                                   
@pytest.mark.integration                                                                                                           
@patch('src.git_utils.get_github_client')                                                                                          
@patch('src.git_utils.get_repository')                                                                                             
@patch('src.response_agent.write_issue_response')                                                                                  
def test_process_issue_with_blech_bot_tag(mock_write_response, mock_get_repo, mock_get_client, mock_issue_with_label):             
    """Test processing an issue with blech_bot tag"""                                                                              
    # Setup mocks                                                                                                                  
    issue = mock_issue_with_label("blech_bot")                                                                                     
                                                                                                                                   
    # Mock triggers                                                                                                                
    with patch('src.triggers.has_bot_response', return_value=False), \                                                             
         patch('src.triggers.has_pr_creation_comment', return_value=(False, None)), \                                              
         patch('src.triggers.has_develop_issue_trigger', return_value=False), \                                                    
         patch('src.response_agent.generate_new_response', return_value=("Test response", [])):                                    
                                                                                                                                   
        # Call function                                                                                                            
        success, error = process_issue(issue, "test/repo")                                                                         
                                                                                                                                   
        # Verify                                                                                                                   
        assert success is True                                                                                                     
        assert error is None                                                                                                       
        mock_write_response.assert_called_once()                                                                                   
                                                                                                                                   
                                                                                                                                   
@pytest.mark.integration                                                                                                           
@patch('src.git_utils.get_github_client')                                                                                          
@patch('src.git_utils.get_repository')                                                                                             
def test_process_issue_without_blech_bot_tag(mock_get_repo, mock_get_client, mock_issue):                                          
    """Test processing an issue without blech_bot tag"""                                                                           
    # Call function                                                                                                                
    success, error = process_issue(mock_issue, "test/repo")                                                                        
                                                                                                                                   
    # Verify                                                                                                                       
    assert success is False                                                                                                        
    assert "does not have blech_bot label" in error                                                                                
                                                                                                                                   
                                                                                                                                   
@pytest.mark.integration                                                                                                           
@patch('src.git_utils.get_github_client')                                                                                          
@patch('src.git_utils.get_repository')                                                                                             
@patch('src.response_agent.bot_tools.get_local_repo_path')                                                                         
@patch('src.branch_handler.checkout_branch')                                                                                       
@patch('src.response_agent.update_repository')                                                                                     
def test_process_repository(mock_update, mock_checkout, mock_get_path, mock_get_repo, mock_get_client,                             
                           mock_repository, mock_issue_with_label):                                                                
    """Test processing a repository"""                                                                                             
    # Setup mocks                                                                                                                  
    client = MagicMock()                                                                                                           
    mock_get_client.return_value = client                                                                                          
                                                                                                                                   
    repo = mock_repository                                                                                                         
    mock_get_repo.return_value = repo                                                                                              
                                                                                                                                   
    # Create a temporary directory for the repo                                                                                    
    temp_dir = tempfile.mkdtemp()                                                                                                  
    mock_get_path.return_value = temp_dir                                                                                          
                                                                                                                                   
    # Mock repository having one issue with blech_bot tag                                                                          
    issue = mock_issue_with_label("blech_bot")                                                                                     
    repo.get_issues.return_value = [issue]                                                                                         
                                                                                                                                   
    # Mock process_issue to avoid actual processing                                                                                
    with patch('src.response_agent.process_issue', return_value=(True, None)):                                                     
        try:                                                                                                                       
            # Call function                                                                                                        
            process_repository("test/repo")                                                                                        
                                                                                                                                   
            # Verify                                                                                                               
            mock_get_client.assert_called_once()                                                                                   
            mock_get_repo.assert_called_with(client, "test/repo")                                                                  
            mock_get_path.assert_called_with("test/repo")                                                                          
            mock_checkout.assert_called_once()                                                                                     
            mock_update.assert_called_once()                                                                                       
        finally:                                                                                                                   
            # Clean up                                                                                                             
            shutil.rmtree(temp_dir)                                                                                                
                                                                                                                                   
                                                                                                                                   
@pytest.mark.integration                                                                                                           
@patch('src.git_utils.get_github_client')                                                                                          
def test_real_github_client(mock_get_client):                                                                                      
    """Test creating a real GitHub client with environment variables"""                                                            
    # Setup environment variable                                                                                                   
    os.environ['GITHUB_TOKEN'] = 'test-token'                                                                                      
                                                                                                                                   
    # Mock the Github class                                                                                                        
    mock_github = MagicMock()                                                                                                      
    mock_get_client.return_value = mock_github                                                                                     
                                                                                                                                   
    # Call function                                                                                                                
    client = get_github_client()                                                                                                   
                                                                                                                                   
    # Verify                                                                                                                       
    assert client == mock_github                                                                                                   
    mock_get_client.assert_called_once()                                                                                           
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

Now let's create a requirements-dev.txt file for the test dependencies:                                                            

requirements-dev.txt                                                                                                               

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
# Development dependencies                                                                                                         
pytest==7.4.0                                                                                                                      
pytest-cov==4.1.0                                                                                                                  
pytest-mock==3.11.1                                                                                                                
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

Let's also create a basic test runner script:                                                                                      

run_tests.sh                                                                                                                       

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
#!/bin/bash                                                                                                                        
                                                                                                                                   
# Run tests with coverage                                                                                                          
python -m pytest tests/ -v --cov=src --cov-report=term-missing                                                                     
                                                                                                                                   
# To run specific test files:                                                                                                      
# python -m pytest tests/test_agents.py -v                                                                                         
                                                                                                                                   
# To run integration tests only:                                                                                                   
# python -m pytest tests/test_integration.py -v -m integration                                                                     
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

Here are the shell commands to set up and run the tests:                                                                           

                                                                                                                                   
mkdir -p tests                                                                                                                     
chmod +x run_tests.sh                                                                                                              
pip install -r requirements-dev.txt                                                                                                
./run_tests.sh                                                                                                                     
                                                                                                                                   

Tokens: 23k sent, 8.2k received. Cost: $0.19 message, $0.19 session.

tests/test_agents.py

tests/test_git_utils.py

tests/test_branch_handler.py

tests/test_triggers.py

tests/test_bot_tools.py

tests/test_response_agent.py

tests/__init__.py

tests/conftest.py

tests/test_integration.py

requirements-dev.txt

run_tests.sh
Applied edit to tests/test_git_utils.py
Applied edit to tests/test_integration.py
Applied edit to requirements-dev.txt
Applied edit to tests/test_bot_tools.py
Applied edit to tests/conftest.py
Applied edit to run_tests.sh
Applied edit to tests/test_agents.py
Applied edit to tests/test_branch_handler.py
Applied edit to tests/__init__.py
Applied edit to tests/test_triggers.py
Applied edit to tests/test_response_agent.py
Commit 6d57cf5 feat: Add comprehensive test suite for GitHub bot functionality

mkdir -p tests                     
chmod +x run_tests.sh              
pip install -r requirements-dev.txt
./run_tests.sh                     
Summarization failed for model anthropic/claude-3-5-haiku-20241022: cannot schedule new futures after shutdown
Summarization failed for model anthropic/claude-3-7-sonnet-20250219: cannot schedule new futures after shutdown
summarizer unexpectedly failed for all models

@abuzarmahmood
Copy link
Owner Author

Add GitHub actions workflow yml for testing

@abuzarmahmood
Copy link
Owner Author

Applied changes based on comment:

View Aider Output
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
The --sonnet flag is deprecated and will be removed in a future version. Please use --model sonnet instead.
Aider v0.80.1
Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, infinite output
Weak model: anthropic/claude-3-5-haiku-20241022
Git repo: .git with 24 files
Repo-map: using 4096 tokens, auto refresh


requirements.txt
I'll create a GitHub Actions workflow file for automating tests for the GitHub bot. This will help ensure code quality and catch   
issues early in the development process.                                                                                           

Let's create a new file in the .github/workflows directory:                                                                        

.github/workflows/test.yml                                                                                                         

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
name: Run Tests                                                                                                                    
                                                                                                                                   
on:                                                                                                                                
  push:                                                                                                                            
    branches: [ main ]                                                                                                             
  pull_request:                                                                                                                    
    branches: [ main ]                                                                                                             
                                                                                                                                   
jobs:                                                                                                                              
  test:                                                                                                                            
    runs-on: ubuntu-latest                                                                                                         
                                                                                                                                   
    steps:                                                                                                                         
    - uses: actions/checkout@v3                                                                                                    
                                                                                                                                   
    - name: Set up Python                                                                                                          
      uses: actions/setup-python@v4                                                                                                
      with:                                                                                                                        
        python-version: '3.10'                                                                                                     
                                                                                                                                   
    - name: Install dependencies                                                                                                   
      run: |                                                                                                                       
        python -m pip install --upgrade pip                                                                                        
        pip install -r requirements.txt                                                                                            
        pip install -r requirements-dev.txt                                                                                        
                                                                                                                                   
    - name: Run tests                                                                                                              
      run: |                                                                                                                       
        pytest tests/ -v                                                                                                           
      env:                                                                                                                         
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}                                                                                  
        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}                                                                              
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

This workflow will:                                                                                                                

 1 Run on pushes to the main branch and on pull requests                                                                           
 2 Set up a Python 3.10 environment                                                                                                
 3 Install both regular and development dependencies                                                                               
 4 Run the pytest test suite with verbose output                                                                                   
 5 Provide necessary environment variables for GitHub API and OpenAI API access                                                    

To create the directory structure and the file, you can run:                                                                       

                                                                                                                                   
mkdir -p .github/workflows                                                                                                         
                                                                                                                                   

Tokens: 6.3k sent, 324 received. Cost: $0.02 message, $0.02 session.

requirements-dev.txt
I'll create the GitHub Actions workflow file using the proper SEARCH/REPLACE format. The requirements-dev.txt file you've added is 
sufficient for this task.                                                                                                          

.github/workflows/test.yml                                                                                                         

                                                                                                                                   
<<<<<<< SEARCH                                                                                                                     
=======                                                                                                                            
name: Run Tests                                                                                                                    
                                                                                                                                   
on:                                                                                                                                
  push:                                                                                                                            
    branches: [ main ]                                                                                                             
  pull_request:                                                                                                                    
    branches: [ main ]                                                                                                             
                                                                                                                                   
jobs:                                                                                                                              
  test:                                                                                                                            
    runs-on: ubuntu-latest                                                                                                         
                                                                                                                                   
    steps:                                                                                                                         
    - uses: actions/checkout@v3                                                                                                    
                                                                                                                                   
    - name: Set up Python                                                                                                          
      uses: actions/setup-python@v4                                                                                                
      with:                                                                                                                        
        python-version: '3.10'                                                                                                     
                                                                                                                                   
    - name: Install dependencies                                                                                                   
      run: |                                                                                                                       
        python -m pip install --upgrade pip                                                                                        
        pip install -r requirements.txt                                                                                            
        pip install -r requirements-dev.txt                                                                                        
                                                                                                                                   
    - name: Run tests                                                                                                              
      run: |                                                                                                                       
        pytest tests/ -v                                                                                                           
      env:                                                                                                                         
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}                                                                                  
        OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}                                                                              
>>>>>>> REPLACE                                                                                                                    
                                                                                                                                   

To create the directory structure and the file, you can run:                                                                       

                                                                                                                                   
mkdir -p .github/workflows                                                                                                         
                                                                                                                                   

Tokens: 6.7k sent, 243 received. Cost: $0.02 message, $0.05 session.

.github/workflows/test.yml
Applied edit to .github/workflows/test.yml
Commit b3f295e ci: Add GitHub Actions workflow for automated testing

mkdir -p .github/workflows


This response was automatically generated by blech_bot using model gpt-4o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write tests for GitHub_bot functionality which works on "abuzarmahmood/test_repo"

1 participant