from dataclasses import replace from test_config import settings from lai_automation.git import ChangeSummary from lai_automation.models import FailureReport from lai_automation.policy import evaluate_changes, evaluate_report_scope def test_policy_accepts_small_application_change() -> None: result = evaluate_changes( ChangeSummary(("app/Services/Example.php", "tests/Feature/ExampleTest.php"), 40, 5), settings(), ) assert result.allowed def test_policy_rejects_secrets_and_vendor_paths() -> None: result = evaluate_changes( ChangeSummary((".env", "vendor/foo.php", ".aider.tags.cache.v4/cache.db"), 3, 0), settings(), ) assert not result.allowed assert len(result.errors) == 3 def test_policy_rejects_test_only_repair() -> None: result = evaluate_changes( ChangeSummary(("tests/Unit/ExampleTest.php",), 20, 2), settings(), ) assert not result.allowed assert "production behavior was not fixed" in result.errors[0] def test_direct_main_blocks_validator_and_migrations() -> None: config = replace( settings(), mode="direct-main", dry_run=False, allow_direct_main=True, gitea_token="token", ) result = evaluate_changes( ChangeSummary(("app/Services/SQLValidatorService.php", "database/migrations/new.php"), 10, 2), config, ) assert not result.allowed def test_policy_rejects_symlinks(tmp_path) -> None: (tmp_path / "link.php").symlink_to("/etc/passwd") result = evaluate_changes(ChangeSummary(("link.php",), 1, 0), settings(), tmp_path) assert not result.allowed def test_cross_database_report_requires_application_orchestration() -> None: report = FailureReport( id=56, chat_message_id=1, source="user_feedback", category="incorrect_answer", user_feedback="Use cockpit_config.time_registration", feedback_type="wrong_result", expected_behavior="Join cockpit_config manager_id and FK_AuftragPos", prompt="Hours in April", response="0 hours", sql_query="SELECT 0", error_message=None, context={}, ) rejected = evaluate_report_scope( report, ChangeSummary(("config/erp_semantics.php", "tests/Unit/FixTest.php"), 20, 2), ) accepted = evaluate_report_scope( report, ChangeSummary(("app/Http/Controllers/ChatController.php", "tests/Unit/FixTest.php"), 20, 2), ) assert not rejected.allowed assert "staged orchestration" in rejected.errors[0] assert accepted.allowed