use std::path::PathBuf;
use podbox::config::Config;
use podbox::labels;
fn load_config(name: &str) -> Config {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures")
.join(name);
let content = std::fs::read_to_string(path).unwrap();
Config::parse(&content).unwrap()
}
#[test]
fn source_prebuilt_when_image_ref_set() {
let config = load_config("prebuilt.toml");
assert!(config.image.source().is_prebuilt());
match config.image.source() {
podbox::config::ImageSource::Prebuilt { ref_str } => {
assert_eq!(ref_str, "ghcr.io/bethropolis/podbox:cachy-latest");
}
_ => panic!("expected Prebuilt"),
}
}
#[test]
fn source_build_when_image_ref_not_set() {
let config = load_config("full.toml");
assert!(config.image.source().is_build());
match config.image.source() {
podbox::config::ImageSource::Build { base } => {
assert_eq!(base, "fedora:41");
}
_ => panic!("expected Build"),
}
}
#[test]
fn source_prebuilt_uses_image_ref_directly() {
let config = load_config("prebuilt.toml");
assert_eq!(
config.image.image_ref.as_deref(),
Some("ghcr.io/bethropolis/podbox:cachy-latest")
);
}
#[test]
fn source_build_has_no_image_ref() {
let config = load_config("full.toml");
assert!(config.image.image_ref.is_none());
}
#[test]
fn containerfile_prebuilt_generates_minimal() {
let config = load_config("prebuilt.toml");
let cf = podbox::codegen::containerfile::generate(&config, "podbox-guest").unwrap();
assert!(cf.starts_with("FROM cachy-latest\n"));
assert!(!cf.contains("COPY podbox-guest"));
assert!(cf.contains(r#"ENTRYPOINT ["/usr/local/bin/podbox-guest", "--entry"]"#));
assert!(cf.contains(r#"CMD ["/usr/bin/fish"]"#));
assert!(cf.contains("ENV PODBOX_CONTAINER=prebuilt"));
assert!(!cf.contains("dnf install"));
assert!(!cf.contains("RUN "));
}
#[test]
fn containerfile_custom_has_packages() {
let config = load_config("full.toml");
let cf = podbox::codegen::containerfile::generate(&config, "podbox-guest").unwrap();
assert!(!cf.starts_with("FROM ghcr.io"));
assert!(cf.contains("dnf install -y"));
assert!(cf.contains("RUN "));
assert!(cf.contains("COPY podbox-guest /usr/local/bin/podbox-guest"));
}
#[test]
fn label_apply_defaults_prebuilt() {
let mut config = load_config("prebuilt.toml");
let labels = std::collections::HashMap::from([
("podbox.schema".to_string(), "1".to_string()),
("podbox.xdg_dirs.documents".to_string(), "true".to_string()),
("podbox.integration.gpu".to_string(), "true".to_string()),
("podbox.default_shell".to_string(), "/bin/fish".to_string()),
]);
labels::apply_defaults(&mut config, &labels);
assert_eq!(config.integration.gpu, podbox::config::GpuMode::Enabled);
assert!(config.integration.xdg_dirs.documents.is_enabled());
}
#[test]
fn label_apply_defaults_empty_does_not_override() {
let mut config = load_config("prebuilt.toml");
let labels = std::collections::HashMap::from([("podbox.schema".to_string(), "1".to_string())]);
labels::apply_defaults(&mut config, &labels);
assert_eq!(config.container.shell, "/usr/bin/fish");
assert_eq!(config.integration.gpu, podbox::config::GpuMode::Auto);
}
#[test]
fn label_apply_defaults_schema_mismatch_returns_early() {
let mut config = load_config("prebuilt.toml");
let labels =
std::collections::HashMap::from([("podbox.protocol_version".to_string(), "2".to_string())]);
labels::apply_defaults(&mut config, &labels);
assert!(config.image.source().is_prebuilt());
}
#[test]
fn quadlet_prebuilt_uses_registry_image() {
use podbox::codegen::quadlet;
use podbox::env::HostEnv;
use podbox::xdg::ResolvedXdgDirs;
let config = load_config("prebuilt.toml");
let env = HostEnv {
uid: 1000,
username: "testuser".into(),
xdg_runtime_dir: PathBuf::from("/run/user/1000"),
wayland_display: None,
wayland_socket: None,
pipewire_socket: None,
pulse_dir: None,
dbus_socket: None,
gpu_has_dri: false,
gpu_has_nvidia: false,
gpu_has_nvidia_uvm: false,
host_has_localtime: false,
host_has_timezone_file: false,
host_has_local_share_themes: false,
host_has_local_share_icons: false,
host_has_local_share_fonts: false,
host_shell: None,
host_locale: None,
gpg_agent_socket: None,
gpg_home: None,
ssh_agent_socket: None,
};
let xdg = ResolvedXdgDirs {
documents: None,
downloads: None,
pictures: None,
music: None,
videos: None,
desktop: None,
projects: None,
};
let q = quadlet::generate_container(&config, &env, &xdg);
assert!(q.contains("Image=ghcr.io/bethropolis/podbox:cachy-latest"));
assert!(!q.contains("Image=prebuilt.build"));
}
#[test]
fn quadlet_custom_uses_build_ref() {
use podbox::codegen::quadlet;
use podbox::env::HostEnv;
use podbox::xdg::ResolvedXdgDir;
use podbox::xdg::ResolvedXdgDirs;
let cfg = load_config("full.toml");
let env = HostEnv {
uid: 1000,
username: "testuser".into(),
xdg_runtime_dir: PathBuf::from("/run/user/1000"),
wayland_display: Some("wayland-0".into()),
wayland_socket: Some(PathBuf::from("/run/user/1000/wayland-0")),
pipewire_socket: Some(PathBuf::from("/run/user/1000/pipewire-0")),
pulse_dir: Some(PathBuf::from("/run/user/1000/pulse")),
dbus_socket: Some(PathBuf::from("/run/user/1000/bus")),
gpu_has_dri: false,
gpu_has_nvidia: false,
gpu_has_nvidia_uvm: false,
host_has_localtime: false,
host_has_timezone_file: false,
host_has_local_share_themes: false,
host_has_local_share_icons: false,
host_has_local_share_fonts: false,
host_shell: None,
host_locale: None,
gpg_agent_socket: None,
gpg_home: None,
ssh_agent_socket: None,
};
let xdg = ResolvedXdgDirs {
documents: Some(ResolvedXdgDir {
path: PathBuf::from("/home/user/Documents"),
read_write: false,
}),
downloads: Some(ResolvedXdgDir {
path: PathBuf::from("/home/user/Downloads"),
read_write: false,
}),
pictures: None,
music: None,
videos: None,
desktop: None,
projects: None,
};
let q = quadlet::generate_container(&cfg, &env, &xdg);
assert!(q.contains("Image=localhost/podbox-myenv:latest"));
assert!(!q.contains("Image=ghcr.io"));
}
#[test]
fn quadlet_has_environment_home() {
use podbox::codegen::quadlet;
let config = load_config("full.toml");
let env = podbox::env::HostEnv {
uid: 1000,
username: "testuser".into(),
xdg_runtime_dir: PathBuf::from("/run/user/1000"),
wayland_display: Some("wayland-0".into()),
wayland_socket: Some(PathBuf::from("/run/user/1000/wayland-0")),
pipewire_socket: Some(PathBuf::from("/run/user/1000/pipewire-0")),
pulse_dir: Some(PathBuf::from("/run/user/1000/pulse")),
dbus_socket: Some(PathBuf::from("/run/user/1000/bus")),
gpu_has_dri: false,
gpu_has_nvidia: false,
gpu_has_nvidia_uvm: false,
host_has_localtime: false,
host_has_timezone_file: false,
host_has_local_share_themes: false,
host_has_local_share_icons: false,
host_has_local_share_fonts: false,
host_shell: None,
host_locale: None,
gpg_agent_socket: None,
gpg_home: None,
ssh_agent_socket: None,
};
let xdg = podbox::xdg::ResolvedXdgDirs {
documents: None,
downloads: None,
pictures: None,
music: None,
videos: None,
desktop: None,
projects: None,
};
let q = quadlet::generate_container(&config, &env, &xdg);
assert!(q.contains("Environment=HOME=/home/%u"));
}
#[test]
fn profile_cachy_parses() {
let profile = podbox::profiles::find("cachy").expect("cachy profile exists");
let cfg = Config::parse(&profile.toml).unwrap();
assert_eq!(cfg.image.base, "cachy-latest");
assert!(cfg.image.source().is_prebuilt());
assert_eq!(cfg.container.shell, "/usr/bin/fish");
}
#[test]
fn profile_fedora_parses() {
let profile = podbox::profiles::find("fedora").expect("fedora profile exists");
let cfg = Config::parse(&profile.toml).unwrap();
assert_eq!(cfg.image.base, "fedora-latest");
assert!(cfg.image.source().is_prebuilt());
}
#[test]
fn profile_dev_parses() {
let profile = podbox::profiles::find("dev").expect("dev profile exists");
let cfg = Config::parse(&profile.toml).unwrap();
assert_eq!(cfg.image.base, "dev-latest");
assert!(cfg.integration.wayland);
assert_eq!(cfg.integration.gpu, podbox::config::GpuMode::Enabled);
}
#[test]
fn profile_ubuntu_parses() {
let profile = podbox::profiles::find("ubuntu").expect("ubuntu profile exists");
let cfg = Config::parse(&profile.toml).unwrap();
assert_eq!(cfg.image.base, "ubuntu-latest");
assert!(cfg.image.source().is_prebuilt());
assert_eq!(cfg.container.shell, "/usr/bin/fish");
}
#[test]
fn profile_unknown_returns_none() {
assert!(podbox::profiles::find("nonexistent").is_none());
}
#[test]
fn profile_list_contains_all() {
let names = podbox::profiles::list_names();
assert!(names.iter().any(|n| n == "cachy"));
assert!(names.iter().any(|n| n == "fedora"));
assert!(names.iter().any(|n| n == "ubuntu"));
assert!(names.iter().any(|n| n == "dev"));
}