diff --git a/crates/ui-egui/src/control.rs b/crates/ui-egui/src/control.rs index cc5ed91cb6..a840ae19e2 100644 --- a/crates/ui-egui/src/control.rs +++ b/crates/ui-egui/src/control.rs @@ -1088,13 +1088,14 @@ fn leave_out_unreadable_pref_steps(command: &str, params: &mut serde_json::Map) { use vectorcraft_engine::file_access::is_path_key; + let shown = |p: &str| p.trim().is_empty() || readable_value(p); params.retain(|key, v| { !unreadable_path_like(key) && match v.as_str() { - Some(p) => !unreadable_path_like(p) && !(is_path_key(key) && !readable_value(p)), + Some(p) => !unreadable_path_like(p) && !(is_path_key(key) && !shown(p)), None => true, } }); @@ -1102,7 +1103,7 @@ fn leave_out_unreadable_params(params: &mut serde_json::Map) { if let Value::Array(paths) = v && is_path_key(key) { - paths.retain(|p| p.as_str().is_none_or(readable_value)); + paths.retain(|p| p.as_str().is_none_or(shown)); } leave_out_unreadable_values(v); } diff --git a/crates/ui-egui/src/control/tests.rs b/crates/ui-egui/src/control/tests.rs index 4d43339a85..009998a8fd 100644 --- a/crates/ui-egui/src/control/tests.rs +++ b/crates/ui-egui/src/control/tests.rs @@ -311,6 +311,24 @@ fn a_spaced_absolute_path_outside_the_read_root_is_left_out() { assert_eq!(params, json!({"keep": inside, "list": []})); } +/// Under a read root, an empty or blank value names no path, so a recorded step keeps it under a path +/// param and in a path param's list, a folder preference reset in a `prefs.set` step's `values` +/// included; a path outside the root is still left out. +#[test] +fn an_empty_path_param_stays_under_a_read_root() { + let base = crate::tests_folder::Folder::new("unreadable-empty"); + std::fs::create_dir_all(base.join("in")).unwrap(); + let roots = vectorcraft_engine::file_access::AutomationRoots::new(&[&base.join("in")], &[]).unwrap(); + let mut params = json!({ + "values": {"fontsFolder": "", "templatesFolder": " ", "recoveryFolder": "/outside/root/x"}, + "path": "", "destinationFolder": " ", "files": ["", "/outside/root/y"], + }); + vectorcraft_engine::file_access::confine(roots.as_ref(), || { + super::leave_out_unreadable_step("prefs.set", params.as_object_mut().unwrap()); + }); + assert_eq!(params, json!({"values": {"fontsFolder": "", "templatesFolder": " "}, "path": "", "destinationFolder": " ", "files": [""]})); +} + /// Without a read root, a `file:` URL that names another host may be read, and a recorded step keeps /// it. #[test]