//! `pic plan` journey: a freshly-pulled manifest must diff to all-no-op //! (pull→plan is idempotent), and editing a script source must surface //! as an update. use tempfile::TempDir; use crate::common; #[ignore = "needs DATABASE_URL pointing at a running Postgres"] #[test] fn plan_roundtrips_then_detects_change() { let Some(fx) = common::fixture_or_skip() else { return; }; let env = common::admin_env(fx); let (script_id, guard) = common::deploy_fixture(&env, "plan", "hello.rhai"); let app = guard.slug().to_string(); common::pic_as(&env) .args([ "routes", "create", "--script", &script_id, "--path", "/p", "--method", "GET", ]) .assert() .success(); // Pull the live state, then plan it back — must be a clean no-op. let dir = TempDir::new().expect("tempdir"); common::pic_as(&env) .args(["pull", &app, "--dir"]) .arg(dir.path()) .assert() .success(); let manifest = dir.path().join("picloud.toml"); let out = common::pic_as(&env) .args(["plan", "--file"]) .arg(&manifest) .output() .expect("plan"); assert!( out.status.success(), "plan failed: {}", String::from_utf8_lossy(&out.stderr) ); let stdout = String::from_utf8(out.stdout).unwrap(); let hello = stdout .lines() .find(|l| l.contains("hello")) .unwrap_or_else(|| panic!("no hello row in plan:\n{stdout}")); assert!( hello.contains("noop"), "expected hello no-op, got:\n{stdout}" ); assert!( !stdout.contains("create") && !stdout.contains("delete"), "fresh pull should diff clean, got:\n{stdout}" ); // Edit the script source on disk → plan must report an update. std::fs::write( dir.path().join("scripts/hello.rhai"), "let body = #{ ok: false }; body", ) .expect("rewrite source"); let out = common::pic_as(&env) .args(["plan", "--file"]) .arg(&manifest) .output() .expect("plan after edit"); let stdout = String::from_utf8(out.stdout).unwrap(); let hello = stdout .lines() .find(|l| l.contains("hello")) .unwrap_or_else(|| panic!("no hello row in plan:\n{stdout}")); assert!( hello.contains("update"), "expected hello update after source edit, got:\n{stdout}" ); drop(guard); }