from __future__ import annotations import pytest from yuxi.channels.adapters.msteams.analysis.researchers import ( WebResearchAgent, CodeFeatureAgent, CodeIssueAgent, ) from yuxi.channels.adapters.msteams.analysis.reporter import ( AnalysisReporter, FixImplementer, ) from yuxi.channels.adapters.msteams.analysis.graph import AnalysisGraph from yuxi.channels.adapters.msteams.analysis.state import AnalysisState class TestWebResearchAgent: @pytest.fixture def agent(self): return WebResearchAgent() @pytest.mark.asyncio async def test_research_returns_non_empty_result(self, agent): result = await agent.research("", {}) assert result assert len(result) > 100 @pytest.mark.asyncio async def test_result_contains_bot_framework_section(self, agent): result = await agent.research("", {}) assert "Bot Framework" in result @pytest.mark.asyncio async def test_result_contains_best_practices(self, agent): result = await agent.research("", {}) assert "最佳实践" in result @pytest.mark.asyncio async def test_result_contains_similar_adapters(self, agent): result = await agent.research("", {}) assert "同类适配器" in result @pytest.mark.asyncio async def test_result_contains_api_standards(self, agent): result = await agent.research("", {}) assert "API 标准" in result class TestCodeFeatureAgent: @pytest.fixture def agent(self): return CodeFeatureAgent() @pytest.mark.asyncio async def test_research_returns_non_empty_result(self, agent): result = await agent.research("", {}) assert result assert len(result) > 100 @pytest.mark.asyncio async def test_result_contains_architecture(self, agent): result = await agent.research("", {}) assert "架构" in result @pytest.mark.asyncio async def test_result_contains_data_flow(self, agent): result = await agent.research("", {}) assert "数据流" in result @pytest.mark.asyncio async def test_result_contains_interface_analysis(self, agent): result = await agent.research("", {}) assert "接口" in result @pytest.mark.asyncio async def test_result_contains_module_interactions(self, agent): result = await agent.research("", {}) assert "模块" in result class TestCodeIssueAgent: @pytest.fixture def agent(self): return CodeIssueAgent() @pytest.mark.asyncio async def test_research_returns_non_empty_result(self, agent): result = await agent.research("", {}) assert result assert len(result) > 100 @pytest.mark.asyncio async def test_result_contains_critical_bugs(self, agent): result = await agent.research("", {}) assert "BUG-001" in result or "关键 Bug" in result @pytest.mark.asyncio async def test_result_contains_error_handling(self, agent): result = await agent.research("", {}) assert "错误处理" in result @pytest.mark.asyncio async def test_result_contains_security_issues(self, agent): result = await agent.research("", {}) assert "安全" in result @pytest.mark.asyncio async def test_result_contains_performance_issues(self, agent): result = await agent.research("", {}) assert "性能" in result @pytest.mark.asyncio async def test_result_contains_code_quality(self, agent): result = await agent.research("", {}) assert "代码质量" in result class TestAnalysisReporter: @pytest.fixture def reporter(self): return AnalysisReporter() @pytest.mark.asyncio async def test_generate_deficiency_report_non_empty(self, reporter): report = await reporter.generate_deficiency_report("web", "feature", "issue") assert report assert len(report) > 100 @pytest.mark.asyncio async def test_report_contains_executive_summary(self, reporter): report = await reporter.generate_deficiency_report("web", "feature", "issue") assert "执行摘要" in report @pytest.mark.asyncio async def test_report_contains_missing_features(self, reporter): report = await reporter.generate_deficiency_report("web", "feature", "issue") assert "缺失的核心功能" in report @pytest.mark.asyncio async def test_report_contains_gap_analysis(self, reporter): report = await reporter.generate_deficiency_report("web", "feature", "issue") assert "与行业标准的差距" in report @pytest.mark.asyncio async def test_report_contains_fix_priority(self, reporter): report = await reporter.generate_deficiency_report("web", "feature", "issue") assert "P0" in report @pytest.mark.asyncio async def test_generate_fix_plan_non_empty(self, reporter): plan = await reporter.generate_fix_plan("report", "issue") assert plan assert len(plan) > 100 @pytest.mark.asyncio async def test_fix_plan_contains_specific_fixes(self, reporter): plan = await reporter.generate_fix_plan("report", "issue") assert "FIX-001" in plan assert "FIX-002" in plan assert "FIX-003" in plan class TestFixImplementer: @pytest.fixture def fixer(self): return FixImplementer() @pytest.mark.asyncio async def test_implement_returns_fix_list(self, fixer): results = await fixer.implement("plan", {}) assert isinstance(results, list) assert len(results) >= 5 @pytest.mark.asyncio async def test_each_fix_has_required_fields(self, fixer): results = await fixer.implement("plan", {}) for item in results: assert "fix_id" in item assert "file" in item assert "description" in item assert "status" in item @pytest.mark.asyncio async def test_all_fixes_pending(self, fixer): results = await fixer.implement("plan", {}) for item in results: assert item["status"] == "pending_implementation" class TestAnalysisGraph: @pytest.fixture def graph(self): return AnalysisGraph() @pytest.fixture def sample_module_files(self): return { "adapter.py": "fake adapter content", "send.py": "fake send content", } @pytest.mark.asyncio async def test_run_completes_successfully(self, graph, sample_module_files): state = await graph.run("/fake/path", sample_module_files) assert isinstance(state, dict) assert "web_research_result" in state assert "code_feature_result" in state assert "code_issue_result" in state assert "deficiency_report" in state assert "fix_plan" in state assert "fix_results" in state @pytest.mark.asyncio async def test_run_and_get_report_returns_string(self, graph, sample_module_files): report = await graph.run_and_get_report("/fake/path", sample_module_files) assert isinstance(report, str) assert len(report) > 500 @pytest.mark.asyncio async def test_run_and_get_report_contains_all_sections(self, graph, sample_module_files): report = await graph.run_and_get_report("/fake/path", sample_module_files) assert "Bot Framework" in report assert "架构" in report assert "BUG-001" in report or "关键 Bug" in report assert "缺失的核心功能" in report assert "FIX-001" in report class TestAnalysisState: def test_state_creation_empty(self): state: AnalysisState = {} assert isinstance(state, dict) def test_state_with_module_path(self): state: AnalysisState = {"module_path": "/test/path"} assert state["module_path"] == "/test/path" def test_state_with_all_fields(self): state: AnalysisState = { "module_path": "/test", "module_files": {"a.py": "content"}, "web_research_result": "web", "code_feature_result": "feature", "code_issue_result": "issue", "deficiency_report": "report", "fix_plan": "plan", "fix_results": [{"id": "1"}], "error": "some error", } assert state["module_path"] == "/test" assert state["fix_results"] == [{"id": "1"}] assert state["error"] == "some error"