Files

175 lines
5.2 KiB
Python

import contextlib
import io
import tempfile
import unittest
from pathlib import Path
from ampg.cli import main
def _write_config(root: Path) -> Path:
source = root / "site"
source.mkdir()
(source / "index.html").write_text("<h1>Hello</h1>", encoding="utf-8")
config_path = root / "gateway.toml"
config_path.write_text(
"""
[[site]]
id = "example"
domain = "example.test"
[site.source]
kind = "static-html"
path = "./site"
[site.outputs]
root = "./out"
plan_root = "./plan"
[site.protocols.i2p]
enabled = true
renderer = "privacy-html"
daemon = "i2pd"
daemon_policy = "auto"
i2p_url = "ready.b32.i2p"
""",
encoding="utf-8",
)
return config_path
def _run_cli(args: list[str]) -> tuple[int, str, str]:
stdout = io.StringIO()
stderr = io.StringIO()
with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):
status = main(args)
return status, stdout.getvalue(), stderr.getvalue()
class ApprovalsTest(unittest.TestCase):
def test_approval_cli_can_move_apply_preflight_to_ready(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp).resolve()
config_path = _write_config(root)
output = root / "out/i2p"
output.mkdir(parents=True)
(output / ".ampg-output").write_text("generated by AMPG\n", encoding="utf-8")
status, output_text, _ = _run_cli(
[
"--config",
str(config_path),
"apply",
"--dry-run",
"--write-artifacts",
"--platform",
"android-termux",
]
)
self.assertEqual(0, status)
self.assertIn("AMPG_APPLY_PREFLIGHT status=review", output_text)
status, output_text, _ = _run_cli(
[
"--config",
str(config_path),
"approvals",
"approve",
"--all",
"--platform",
"android-termux",
]
)
self.assertEqual(0, status)
self.assertIn("AMPG_APPROVAL_SUMMARY mode=approve candidates=6", output_text)
self.assertIn("written=6", output_text)
self.assertTrue((root / ".ampg/state/approvals.json").exists())
status, output_text, _ = _run_cli(
[
"--config",
str(config_path),
"apply",
"--dry-run",
"--write-artifacts",
"--platform",
"android-termux",
]
)
self.assertEqual(0, status)
self.assertIn("AMPG_APPLY_PREFLIGHT status=ready", output_text)
self.assertNotIn("AMPG_APPLY_PREFLIGHT_ITEM", output_text)
def test_approval_cli_reports_stale_artifact_after_edit(self):
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp).resolve()
config_path = _write_config(root)
output = root / "out/i2p"
output.mkdir(parents=True)
(output / ".ampg-output").write_text("generated by AMPG\n", encoding="utf-8")
_run_cli(
[
"--config",
str(config_path),
"apply",
"--dry-run",
"--write-artifacts",
"--platform",
"android-termux",
]
)
_run_cli(
[
"--config",
str(config_path),
"approvals",
"approve",
"--kind",
"daemon-config",
"--platform",
"android-termux",
]
)
artifact = root / "plan/example/i2p/managed/android-termux/i2pd-tunnels.conf"
artifact.write_text(artifact.read_text(encoding="utf-8") + "# edited\n", encoding="utf-8")
status, output_text, _ = _run_cli(
[
"--config",
str(config_path),
"approvals",
"list",
"--kind",
"daemon-config",
"--platform",
"android-termux",
]
)
self.assertEqual(0, status)
self.assertIn("status=stale", output_text)
self.assertIn("artifact differs from current generator output", output_text)
def test_approval_cli_requires_explicit_scope(self):
with tempfile.TemporaryDirectory() as tmp:
config_path = _write_config(Path(tmp))
status, _, error_text = _run_cli(
[
"--config",
str(config_path),
"approvals",
"approve",
"--platform",
"android-termux",
]
)
self.assertEqual(1, status)
self.assertIn("pass --all or --kind", error_text)
if __name__ == "__main__":
unittest.main()