from unittest.mock import patch, MagicMock from scripts.plan_runner import detect_tool, run_init, run_plan, extract_summary def test_detect_tool_terragrunt(tmp_path): (tmp_path / "terragrunt.hcl").write_text("# tg\n") assert detect_tool(tmp_path) == "terragrunt" def test_detect_tool_tofu(tmp_path): (tmp_path / "main.tf").write_text("# tf\n") assert detect_tool(tmp_path) == "tofu" def test_extract_summary_finds_plan_line(): output = """\ Terraform will perform the following actions: # aws_s3_bucket.x will be created + resource "aws_s3_bucket" "x" { bucket = "y" } Plan: 1 to add, 0 to change, 0 to destroy. """ assert extract_summary(output) == "1 to add, 0 to change, 0 to destroy" def test_extract_summary_no_changes(): output = "No changes. Your infrastructure matches the configuration.\n" assert extract_summary(output) == "no changes" def test_run_init_ok(tmp_path): (tmp_path / "main.tf").write_text("# tf\n") fake = MagicMock(returncode=0, stdout="Initializing...\nok\n", stderr="") with patch("subprocess.run", return_value=fake) as p: result = run_init(tmp_path, "tofu") assert result.ok is True assert "ok" in result.stdout_tail p.assert_called_once() args = p.call_args[0][0] assert args[0] == "tofu" assert "init" in args def test_run_init_failure_records_stderr(tmp_path): (tmp_path / "main.tf").write_text("# tf\n") fake = MagicMock(returncode=1, stdout="", stderr="provider not found\n") with patch("subprocess.run", return_value=fake): result = run_init(tmp_path, "tofu") assert result.ok is False assert "provider not found" in result.stderr_tail def test_run_plan_streams_to_file(tmp_path): out_path = tmp_path / "plan.txt" fake = MagicMock(returncode=0, stdout="Plan: 2 to add, 0 to change, 0 to destroy.\n", stderr="") with patch("subprocess.run", return_value=fake): result = run_plan(tmp_path, "tofu", out_path) assert result.ok is True assert result.exit_code == 0 assert result.summary == "2 to add, 0 to change, 0 to destroy" assert out_path.read_text().endswith("0 to destroy.\n")