use assert_cmd::Command;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
const MANIFEST: &str = r#"
version = 1
canonical = "json-schema-2020-12"
authoring = "zod"
[[contracts]]
name = "user"
source = "contracts/user.zod.ts"
emit = ["zod", "sql"]
[[mappings]]
glob = "app/api/**/*.ts"
contracts = ["user"]
require = "boundary-validation"
[gates]
suppression_comments = "deny"
protected_paths = ["pushkin.toml"]
[db]
direction = "contract"
provider = "supabase"
rls_tests = "required"
"#;
fn repo() -> Option<tempfile::TempDir> {
let dir = tempfile::tempdir().ok()?;
fs::write(dir.path().join("pushkin.toml"), MANIFEST).ok()?;
fs::create_dir_all(dir.path().join("generated")).ok()?;
fs::write(
dir.path().join("generated/user.gen.sql"),
"CREATE TABLE users (id uuid PRIMARY KEY, name text NOT NULL);\n",
)
.ok()?;
Some(dir)
}
fn fake_atlas(bin: &Path) -> Option<()> {
let argv_log = bin.join("atlas.argv");
let script = format!(
"#!/bin/sh\necho \"$@\" > '{}'\necho 'Schemas are synced.'\nexit 0\n",
argv_log.display()
);
let path = bin.join("atlas");
fs::write(&path, script).ok()?;
fs::set_permissions(&path, fs::Permissions::from_mode(0o755)).ok()?;
Some(())
}
fn run_drift(dir: &Path, bin: &Path, dev_url: Option<&str>) -> Option<String> {
let mut cmd = Command::cargo_bin("pushkin").ok()?;
cmd.args(["db", "drift"])
.current_dir(dir)
.env("PATH", format!("{}:/usr/bin:/bin", bin.display()))
.env("DATABASE_URL", "postgres://localhost:5432/app");
match dev_url {
Some(url) => cmd.env("PUSHKIN_ATLAS_DEV_URL", url),
None => cmd.env_remove("PUSHKIN_ATLAS_DEV_URL"),
};
cmd.output().ok()?;
fs::read_to_string(bin.join("atlas.argv")).ok()
}
#[test]
fn dev_url_env_forwarded_to_atlas() {
let dir = repo().unwrap();
let bin = tempfile::tempdir().unwrap();
fake_atlas(bin.path()).unwrap();
let argv = run_drift(
dir.path(),
bin.path(),
Some("postgres://localhost:5432/dev?sslmode=disable"),
)
.unwrap();
assert!(
argv.contains("--dev-url") && argv.contains("postgres://localhost:5432/dev"),
"PUSHKIN_ATLAS_DEV_URL must be forwarded as --dev-url: {argv}"
);
}
#[test]
fn no_dev_url_env_means_no_flag() {
let dir = repo().unwrap();
let bin = tempfile::tempdir().unwrap();
fake_atlas(bin.path()).unwrap();
let argv = run_drift(dir.path(), bin.path(), None).unwrap();
assert!(
!argv.contains("--dev-url"),
"without the env var the flag must be absent (Atlas names the need): {argv}"
);
}