from unittest.mock import AsyncMock, patch import pytest from app.agents import repo_analysis_agent, bug_detection_agent from app.models.issue import IssueReport, Bug, Warning, Suggestion from app.models.repository import RepositoryRequest @pytest.mark.asyncio async def test_repo_analysis_agent_returns_metadata(tmp_path): with patch( "app.agents.repo_analysis_agent.call_llm_for_json", new=AsyncMock(return_value={}), ): result = await repo_analysis_agent.run( "https://github.com/test/repo", str(tmp_path) ) assert result.name == "repo" assert result.url == "https://github.com/test/repo" @pytest.mark.asyncio async def test_bug_detection_agent_returns_report(): with ( patch( "app.agents.bug_detection_agent.run_full_analysis", return_value={"ruff": {"issues": []}, "bandit": {"issues": []}}, ), patch( "app.agents.bug_detection_agent.run_tests", return_value={"passed": 0, "failed": 0, "errors": 0}, ), patch("app.agents.bug_detection_agent.get_python_files", return_value=[]), patch( "app.agents.bug_detection_agent.call_llm_for_json", new=AsyncMock(return_value={}), ), ): result = await bug_detection_agent.run("/tmp/fake") assert result.total_critical == 0 def test_issue_report_totals_computed_automatically(): report = IssueReport( critical=[Bug(description="null ptr", file="main.py")], warnings=[Warning(description="unused var", file="utils.py")], suggestions=[Suggestion(description="use walrus operator", file="utils.py")], ) assert report.total_critical == 1 assert report.total_warnings == 1 assert report.total_suggestions == 1 def test_issue_report_totals_empty(): report = IssueReport() assert report.total_critical == 0 assert report.total_warnings == 0 assert report.total_suggestions == 0 def test_repository_request_rejects_invalid_url(): with pytest.raises(Exception): RepositoryRequest(github_url="http://not-github.com/owner/repo") def test_repository_request_rejects_bare_domain(): with pytest.raises(Exception): RepositoryRequest(github_url="https://github.com") def test_repository_request_accepts_valid_url(): req = RepositoryRequest(github_url="https://github.com/owner/repo") assert req.github_url == "https://github.com/owner/repo" @pytest.mark.asyncio async def test_code_review_agent_no_source_files(): from app.agents import code_review_agent from app.models.repository import RepositoryMetadata metadata = RepositoryMetadata( url="https://github.com/test/repo", name="repo", local_path="/tmp/fake", ) with patch("app.tools.file_scanner.get_python_files", return_value=[]): result = await code_review_agent.run("/tmp/fake", metadata) assert result.overall_score == 0.0 assert "No source files" in result.summary @pytest.mark.asyncio async def test_test_generation_agent_no_source(): from app.agents import test_generation_agent with patch("app.agents.test_generation_agent.get_python_files", return_value=[]): result = await test_generation_agent.run("/tmp/fake") assert result.total_tests_generated == 0 assert "No source files" in result.test_code @pytest.mark.asyncio async def test_test_generation_agent_with_source(tmp_path): from app.agents import test_generation_agent # Use a subdirectory without "test_" in the path so the agent doesn't skip it src_dir = tmp_path / "src" src_dir.mkdir() src = src_dir / "sample.py" src.write_text("def add(a, b):\n return a + b\n") with patch( "app.agents.test_generation_agent.call_llm_routed", new=AsyncMock(return_value="def test_add():\n assert add(1, 2) == 3\n"), ): result = await test_generation_agent.run(str(src_dir)) assert result.total_tests_generated >= 1 @pytest.mark.asyncio async def test_report_generator_agent_returns_report(): from app.agents import report_generator_agent from app.models.repository import RepositoryMetadata from app.models.issue import IssueReport from app.models.review import ReviewSuggestions, GeneratedTests metadata = RepositoryMetadata( url="https://github.com/t/r", name="r", local_path="/tmp" ) issues = IssueReport() tests = GeneratedTests(test_code="", total_tests_generated=0) review = ReviewSuggestions(overall_score=7.0, summary="ok") with patch( "app.agents.report_generator_agent.call_llm_routed", new=AsyncMock(return_value="# Engineering Report\nAll looks good."), ): result = await report_generator_agent.run(metadata, issues, tests, review) assert "Engineering Report" in result.full_report assert result.repository.name == "r"