use starbase_archive::Archiver;
use starbase_archive::codecs::Gz;
use starbase_archive::tar::TarPacker;
use starbase_sandbox::create_empty_sandbox;
use starbase_utils::fs;
use std::path::Path;
use warpgate::{WarpgateLoaderError, extract_file_name_from_url, move_or_unpack_file};
const WASM_MAGIC: &[u8] = b"\0asm\x01\x00\x00\x00";
fn pack_tar_gz(source_root: &Path, archive_path: &Path, files: &[(&str, &[u8])]) {
for (rel, contents) in files {
let target = source_root.join(rel);
fs::write_file(&target, contents).unwrap();
}
let mut archiver = Archiver::new(source_root, archive_path);
for (rel, _) in files {
archiver.add_source_file(rel, None);
}
archiver
.pack(|path| Ok(TarPacker::new(Gz::new(fs::create_file(path).unwrap()))))
.unwrap();
}
mod extract_file_name_from_url {
use super::*;
#[test]
fn returns_last_path_segment_for_valid_url() {
assert_eq!(
extract_file_name_from_url("https://example.com/path/file.tar.gz"),
"file.tar.gz"
);
assert_eq!(
extract_file_name_from_url("https://example.com/plugin.wasm"),
"plugin.wasm"
);
}
#[test]
fn falls_back_to_rightmost_slash_for_non_url() {
assert_eq!(
extract_file_name_from_url("not a url/file.wasm"),
"file.wasm"
);
}
#[test]
fn returns_unknown_when_no_segments_or_slashes() {
assert_eq!(extract_file_name_from_url(""), "unknown");
assert_eq!(extract_file_name_from_url("just-a-string"), "unknown");
}
}
mod move_or_unpack_file {
use super::*;
#[test]
fn unpacks_archive_and_prefers_release_dir() {
let sandbox = create_empty_sandbox();
let source_root = sandbox.path().join("src");
let archive_path = sandbox.path().join("plugin.tar.gz");
let mut dest_path = sandbox.path().join("plugin.wasm");
pack_tar_gz(
&source_root,
&archive_path,
&[
("debug/plugin.wasm", b"not this one"),
("release/plugin.wasm", WASM_MAGIC),
],
);
move_or_unpack_file(&archive_path, &mut dest_path, &["wasm".into()]).unwrap();
assert!(dest_path.exists());
let bytes = fs::read_file_bytes(&dest_path).unwrap();
assert_eq!(bytes, WASM_MAGIC);
}
#[test]
fn unpacks_archive_with_no_release_dir() {
let sandbox = create_empty_sandbox();
let source_root = sandbox.path().join("src");
let archive_path = sandbox.path().join("plugin.tar.gz");
let mut dest_path = sandbox.path().join("plugin.wasm");
pack_tar_gz(&source_root, &archive_path, &[("plugin.wasm", WASM_MAGIC)]);
move_or_unpack_file(&archive_path, &mut dest_path, &["wasm".into()]).unwrap();
let bytes = fs::read_file_bytes(&dest_path).unwrap();
assert_eq!(bytes, WASM_MAGIC);
}
#[test]
fn errors_when_archive_contains_no_wasm() {
let sandbox = create_empty_sandbox();
let source_root = sandbox.path().join("src");
let archive_path = sandbox.path().join("plugin.tar.gz");
let mut dest_path = sandbox.path().join("plugin.wasm");
pack_tar_gz(
&source_root,
&archive_path,
&[("README.md", b"no wasm here")],
);
let err = move_or_unpack_file(&archive_path, &mut dest_path, &["wasm".into()]).unwrap_err();
assert!(
matches!(err, WarpgateLoaderError::NoWasmFound { .. }),
"expected NoWasmFound, got: {err:?}"
);
assert!(!dest_path.exists());
}
#[test]
fn renames_plain_wasm_file() {
let sandbox = create_empty_sandbox();
let temp_path = sandbox.path().join("temp.wasm");
let mut dest_path = sandbox.path().join("plugin.wasm");
fs::write_file(&temp_path, WASM_MAGIC).unwrap();
move_or_unpack_file(&temp_path, &mut dest_path, &["wasm".into()]).unwrap();
assert!(dest_path.exists());
assert!(!temp_path.exists());
let bytes = fs::read_file_bytes(&dest_path).unwrap();
assert_eq!(bytes, WASM_MAGIC);
}
#[test]
fn errors_on_unsupported_extension() {
let sandbox = create_empty_sandbox();
let temp_path = sandbox.path().join("temp.wasm");
let mut dest_path = sandbox.path().join("plugin.exe");
fs::write_file(&temp_path, b"not a plugin").unwrap();
let err = move_or_unpack_file(&temp_path, &mut dest_path, &["wasm".into()]).unwrap_err();
assert!(
matches!(
err,
WarpgateLoaderError::UnsupportedDownloadExtension { ref ext, .. } if ext == "exe"
),
"expected UnsupportedDownloadExtension(exe), got: {err:?}"
);
assert!(!dest_path.exists());
}
#[test]
fn errors_on_missing_extension() {
let sandbox = create_empty_sandbox();
let temp_path = sandbox.path().join("temp.wasm");
let mut dest_path = sandbox.path().join("plugin");
fs::write_file(&temp_path, b"unknown").unwrap();
let err = move_or_unpack_file(&temp_path, &mut dest_path, &["wasm".into()]).unwrap_err();
assert!(
matches!(err, WarpgateLoaderError::UnknownDownloadType { .. }),
"expected UnknownDownloadType, got: {err:?}"
);
assert!(!dest_path.exists());
}
#[test]
fn unpacks_non_wasm_archive_and_updates_dest_extension() {
let sandbox = create_empty_sandbox();
let source_root = sandbox.path().join("src");
let archive_path = sandbox.path().join("plugin.tar.gz");
let mut dest_path = sandbox.path().join("plugin.wasm");
pack_tar_gz(
&source_root,
&archive_path,
&[("plugin.toml", b"[plugin]\nname = \"test\"\n")],
);
move_or_unpack_file(
&archive_path,
&mut dest_path,
&["wasm".into(), "toml".into()],
)
.unwrap();
assert_eq!(dest_path.extension().and_then(|e| e.to_str()), Some("toml"));
assert!(dest_path.exists());
let bytes = fs::read_file_bytes(&dest_path).unwrap();
assert!(bytes.starts_with(b"[plugin]"));
}
#[test]
fn prefers_first_extension_when_archive_contains_multiple() {
let sandbox = create_empty_sandbox();
let source_root = sandbox.path().join("src");
let archive_path = sandbox.path().join("plugin.tar.gz");
let mut dest_path = sandbox.path().join("plugin.wasm");
pack_tar_gz(
&source_root,
&archive_path,
&[
("plugin.toml", b"[plugin]\nname = \"test\"\n"),
("plugin.wasm", WASM_MAGIC),
],
);
move_or_unpack_file(
&archive_path,
&mut dest_path,
&["wasm".into(), "toml".into()],
)
.unwrap();
assert_eq!(dest_path.extension().and_then(|e| e.to_str()), Some("wasm"));
let bytes = fs::read_file_bytes(&dest_path).unwrap();
assert_eq!(bytes, WASM_MAGIC);
}
}