This commit is contained in:
@@ -25,4 +25,32 @@ def test_summary_includes_untracked_files(tmp_path) -> None:
|
||||
summary = workspace.summary()
|
||||
|
||||
assert summary.files == ("new.php",)
|
||||
assert summary.added_lines == 1
|
||||
assert summary.added_lines == 1
|
||||
|
||||
|
||||
def test_discard_changes_restores_clean_disposable_workspace(tmp_path) -> None:
|
||||
workspace = GitWorkspace(settings(workspace_root=tmp_path), 3)
|
||||
workspace.path.mkdir()
|
||||
subprocess.run(["git", "init"], cwd=workspace.path, check=True, capture_output=True)
|
||||
subprocess.run(
|
||||
["git", "config", "user.email", "test@example.invalid"],
|
||||
cwd=workspace.path,
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(
|
||||
["git", "config", "user.name", "Test"],
|
||||
cwd=workspace.path,
|
||||
check=True,
|
||||
)
|
||||
tracked = workspace.path / "tracked.php"
|
||||
tracked.write_text("<?php\nreturn [];\n")
|
||||
subprocess.run(["git", "add", "."], cwd=workspace.path, check=True)
|
||||
subprocess.run(["git", "commit", "-m", "base"], cwd=workspace.path, check=True, capture_output=True)
|
||||
tracked.write_text("<?php\ninvalid\n")
|
||||
untracked = workspace.path / "extra.php"
|
||||
untracked.write_text("<?php\n")
|
||||
|
||||
workspace.discard_changes()
|
||||
|
||||
assert tracked.read_text() == "<?php\nreturn [];\n"
|
||||
assert not untracked.exists()
|
||||
@@ -176,3 +176,27 @@ def test_unresolved_placeholder_task_guides_real_answer_path() -> None:
|
||||
assert "exact token map" in task
|
||||
assert "HTTP-backed AIService test" in task
|
||||
assert "local database-result fallback" in task
|
||||
|
||||
|
||||
def test_cross_database_report_guides_staged_source_routing() -> None:
|
||||
report = FailureReport(
|
||||
id=56,
|
||||
chat_message_id=1,
|
||||
source="user_feedback",
|
||||
category="incorrect_answer",
|
||||
user_feedback="Wrong hours",
|
||||
feedback_type="wrong_result",
|
||||
expected_behavior="Join cockpit_config.time_registration to customer manager and ERP positions",
|
||||
prompt="Hours in April",
|
||||
response="0 hours",
|
||||
sql_query="SELECT SUM(hours) FROM LX_AUFGABE",
|
||||
error_message=None,
|
||||
context={"database_type": "erp"},
|
||||
)
|
||||
|
||||
task = build_task(report)
|
||||
|
||||
assert "tables from multiple databases" in task
|
||||
assert "staged-query workflows" in task
|
||||
assert "Do not put an impossible cross-connection join" in task
|
||||
assert "preserving tenant isolation" in task
|
||||
|
||||
@@ -105,6 +105,52 @@ def test_long_stage_emits_heartbeat(caplog) -> None:
|
||||
assert "Report 7 agent attempt 1 finished" in caplog.text
|
||||
|
||||
|
||||
def test_php_syntax_failure_discards_attempt_before_full_validation() -> None:
|
||||
report = FailureReport(
|
||||
id=56,
|
||||
chat_message_id=1,
|
||||
source="user_feedback",
|
||||
category="incorrect_answer",
|
||||
user_feedback="Wrong hours",
|
||||
feedback_type="wrong_result",
|
||||
expected_behavior="Use time registration",
|
||||
prompt="Hours in April",
|
||||
response="0 hours",
|
||||
sql_query="SELECT 0",
|
||||
error_message=None,
|
||||
context={},
|
||||
)
|
||||
config = settings(mode="pr", dry_run=False, gitea_token="token")
|
||||
worker = AutomationWorker(config)
|
||||
worker.reports = Mock()
|
||||
worker.reports.claim_next.return_value = report
|
||||
worker.agent = Mock()
|
||||
worker.agent.run.side_effect = ["broken PHP", "fixed PHP"]
|
||||
worker.gitea = Mock()
|
||||
worker._run_tests = Mock(return_value=[])
|
||||
workspace = Mock()
|
||||
workspace.path = Path("/tmp/nonexistent-workspace")
|
||||
workspace.branch = "ai/failure-56"
|
||||
workspace.summary.return_value = ChangeSummary(
|
||||
("config/erp_semantics.php", "tests/Unit/FixTest.php"), 20, 2
|
||||
)
|
||||
workspace.run_args.side_effect = [
|
||||
Mock(returncode=255, stdout="Parse error", stderr="unexpected token"),
|
||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||
Mock(returncode=0, stdout="No syntax errors", stderr=""),
|
||||
]
|
||||
workspace.commit.return_value = "commit-id"
|
||||
|
||||
with patch("lai_automation.worker.GitWorkspace", return_value=workspace):
|
||||
assert worker.run_once()
|
||||
|
||||
assert worker.agent.run.call_count == 2
|
||||
assert "unexpected token" in worker.agent.run.call_args_list[1].args[1]
|
||||
assert "clean repository" in worker.agent.run.call_args_list[1].args[1]
|
||||
workspace.discard_changes.assert_called_once()
|
||||
worker._run_tests.assert_called_once()
|
||||
|
||||
|
||||
def test_failed_validation_gets_one_correction_before_pr() -> None:
|
||||
report = FailureReport(
|
||||
id=13,
|
||||
@@ -134,6 +180,7 @@ def test_failed_validation_gets_one_correction_before_pr() -> None:
|
||||
workspace.summary.return_value = ChangeSummary(
|
||||
("app/Services/Fix.php", "tests/Feature/FixTest.php"), 10, 1
|
||||
)
|
||||
workspace.run_args.return_value = Mock(returncode=0, stdout="No syntax errors", stderr="")
|
||||
workspace.commit.return_value = "commit-id"
|
||||
|
||||
with patch("lai_automation.worker.GitWorkspace", return_value=workspace):
|
||||
@@ -177,6 +224,7 @@ def test_no_change_response_gets_one_correction() -> None:
|
||||
ChangeSummary(("app/Services/Fix.php", "tests/Feature/FixTest.php"), 10, 1),
|
||||
ChangeSummary(("app/Services/Fix.php", "tests/Feature/FixTest.php"), 10, 1),
|
||||
]
|
||||
workspace.run_args.return_value = Mock(returncode=0, stdout="No syntax errors", stderr="")
|
||||
workspace.commit.return_value = "commit-id"
|
||||
|
||||
with patch("lai_automation.worker.GitWorkspace", return_value=workspace):
|
||||
@@ -219,6 +267,7 @@ def test_test_only_change_gets_correction_before_validation() -> None:
|
||||
ChangeSummary(("app/Services/Fix.php", "tests/Unit/FixTest.php"), 15, 1),
|
||||
ChangeSummary(("app/Services/Fix.php", "tests/Unit/FixTest.php"), 15, 1),
|
||||
]
|
||||
workspace.run_args.return_value = Mock(returncode=0, stdout="No syntax errors", stderr="")
|
||||
workspace.commit.return_value = "commit-id"
|
||||
|
||||
with patch("lai_automation.worker.GitWorkspace", return_value=workspace):
|
||||
|
||||
Reference in New Issue
Block a user