use super::*;
#[test]
fn list_files_returns_sorted_direct_child_files_and_rejects_non_directory() {
let (temp, runtime) = runtime();
fs::create_dir_all(temp.path().join("dir/sub")).unwrap();
fs::write(temp.path().join("dir/b.txt"), "").unwrap();
fs::write(temp.path().join("dir/a.txt"), "").unwrap();
let result = runtime.dispatch("list_files", json!({"path":"dir"}));
assert!(result.success, "{}", result.content);
assert_eq!(result.content, "a.txt\nb.txt");
assert_eq!(result.metadata["path"], "dir");
assert_eq!(result.metadata["files"], 2);
assert_eq!(result.metadata["truncated"], false);
let file_result = runtime.dispatch("list_files", json!({"path":"dir/a.txt"}));
assert!(!file_result.success);
assert!(
file_result.content.contains("must be a directory"),
"{}",
file_result.content
);
}
#[test]
fn list_files_rejects_path_escape() {
let (_temp, runtime) = runtime();
let result = runtime.dispatch("list_files", json!({"path":"../"}));
assert!(!result.success);
}
#[test]
fn list_files_caps_output_and_marks_truncated() {
let (temp, runtime) = runtime();
fs::create_dir_all(temp.path().join("dir")).unwrap();
for index in 0..1001 {
fs::write(temp.path().join("dir").join(format!("{index:04}.txt")), "").unwrap();
}
let result = runtime.dispatch("list_files", json!({"path":"dir"}));
assert!(result.success, "{}", result.content);
assert_eq!(result.metadata["files"], 1000);
assert_eq!(result.metadata["truncated"], true);
let lines = result.content.lines().collect::<Vec<_>>();
assert_eq!(lines.len(), 1000);
assert!(lines.windows(2).all(|pair| pair[0] <= pair[1]));
}