Files
ewoooc/tests/test_code_review_pipeline_security.py

173 lines
6.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import logging
def test_verify_internal_token_requires_env_by_default(monkeypatch):
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "INTERNAL_TOKEN", "")
monkeypatch.setattr(module, "ALLOW_INSECURE_WEBHOOK", False)
assert module.verify_internal_token("") is False
assert module.verify_internal_token("anything") is False
def test_verify_internal_token_allows_explicit_dev_override(monkeypatch):
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "INTERNAL_TOKEN", "")
monkeypatch.setattr(module, "ALLOW_INSECURE_WEBHOOK", True)
assert module.verify_internal_token("") is True
def test_code_review_guard_auto_fixes_high_risk_findings(monkeypatch):
"""ADR-020CRITICAL/HIGH 不再走 HITL一律 auto_fix=true。"""
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "AUTO_FIX_ENABLED", True)
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline.state["severity_summary"] = {"critical": 1, "high": 1, "medium": 0, "low": 0}
guarded = pipeline._guard_ea_decision(
{"priority": "critical", "auto_fix": True, "reasoning": "建議修復", "fix_files": ["services/example.py"]},
[
{"severity": "CRITICAL", "file": "services/example.py"},
{"severity": "HIGH", "file": "services/example.py"},
],
)
assert guarded["auto_fix"] is True
assert guarded["human_review_needed"] is False
def test_code_review_error_notification_failure_is_logged(monkeypatch, caplog):
import services.telegram_templates as telegram_templates
import services.code_review_pipeline_service as module
def broken_send(_message):
raise RuntimeError("telegram down")
monkeypatch.setattr(telegram_templates, "_send_telegram_raw", broken_send)
caplog.set_level(logging.WARNING, logger="services.code_review_pipeline_service")
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline._notify_error("boom")
assert "失敗通知發送失敗" in caplog.text
def test_code_review_guard_main_switch_can_disable_auto_fix(monkeypatch):
"""ADR-020主開關 CODE_REVIEW_AUTO_FIX_ENABLED=false 可即時切斷自動修復鏈,但不再回退到 HITL。"""
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "AUTO_FIX_ENABLED", False)
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline.state["severity_summary"] = {"critical": 0, "high": 0, "medium": 1, "low": 0}
guarded = pipeline._guard_ea_decision(
{"priority": "medium", "auto_fix": True, "reasoning": "建議修復", "fix_files": ["services/example.py"]},
[{"severity": "MEDIUM", "file": "services/example.py"}],
)
assert guarded["auto_fix"] is False
# ADR-020即使主開關關掉也不再標記 human_review_needed不存在 HITL 通道)
assert guarded["human_review_needed"] is False
def test_code_review_no_findings_no_auto_fix(monkeypatch):
"""無 finding 時auto_fix=false 但不應標記為 human_review_needed。"""
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "AUTO_FIX_ENABLED", True)
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline.state["severity_summary"] = {"critical": 0, "high": 0, "medium": 0, "low": 0}
guarded = pipeline._guard_ea_decision(
{"priority": "low", "auto_fix": False, "reasoning": "無 finding", "fix_files": []},
[],
)
assert guarded["auto_fix"] is False
assert guarded["human_review_needed"] is False
def test_guard_upgrades_llm_false_to_true_when_findings_exist(monkeypatch):
"""ADR-020 核心保證:即使 LLM EA 回傳 auto_fix=False只要有 finding 且主開關開guard 必升級為 true。"""
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "AUTO_FIX_ENABLED", True)
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline.state["severity_summary"] = {"critical": 0, "high": 0, "medium": 1, "low": 0}
guarded = pipeline._guard_ea_decision(
{"priority": "medium", "auto_fix": False, "reasoning": "LLM 保守判斷", "fix_files": ["services/example.py"]},
[{"severity": "MEDIUM", "file": "services/example.py"}],
)
# ADR-020 不允許 LLM 把決策降級為 HITL
assert guarded["auto_fix"] is True
assert guarded["human_review_needed"] is False
def test_guard_upgrades_llm_human_review_true_to_false(monkeypatch):
"""ADR-020即使 LLM 回 human_review_needed=trueguard 也應強制改為 false。"""
import services.code_review_pipeline_service as module
monkeypatch.setattr(module, "AUTO_FIX_ENABLED", True)
pipeline = module.CodeReviewPipeline("abcdef123456", ["services/example.py"])
pipeline.state["severity_summary"] = {"critical": 1, "high": 0, "medium": 0, "low": 0}
guarded = pipeline._guard_ea_decision(
{
"priority": "critical",
"auto_fix": False,
"human_review_needed": True,
"reasoning": "LLM 想走人工審查",
"fix_files": ["services/example.py"],
},
[{"severity": "CRITICAL", "file": "services/example.py"}],
)
assert guarded["auto_fix"] is True
assert guarded["human_review_needed"] is False
def test_complete_notification_marks_non_whitelisted_aider_files(monkeypatch):
"""tests/docs/config 等 finding 不應在完成通知中宣稱 AiderHeal 會自動修復。"""
import services.telegram_templates as telegram_templates
import services.code_review_pipeline_service as module
messages = []
monkeypatch.setattr(telegram_templates, "_send_telegram_raw", messages.append)
pipeline = module.CodeReviewPipeline(
"abcdef123456",
["tests/test_market_intel_skeleton.py"],
)
pipeline.state["severity_summary"] = {
"critical": 0,
"high": 1,
"medium": 0,
"low": 0,
}
pipeline._notify_complete(
[
{
"severity": "HIGH",
"description": "疑似硬編碼敏感字串",
"file": "tests/test_market_intel_skeleton.py",
}
],
"",
{
"priority": "high",
"auto_fix": True,
"fix_files": ["tests/test_market_intel_skeleton.py"],
},
)
assert messages
assert "不在自動修復白名單" in messages[0]
assert "已觸發自動修復" not in messages[0]