From ae388fbc0c0dbefeac3480c3aeda97e29c6fbcb7 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 19 Sep 2026 15:55:03 +0000 Subject: [PATCH] test(desktop): cover URI encoding of remote paths with spaces (#171) URI-level regression tests assert that path segments are percent-encoded on the wire (no raw spaces) and decode back to the original names. Authored By: TDvorak Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../crates/cloudreve-api/src/models/uri.rs | 26 +++++++++++++++++++ .../crates/cloudreve-sync/src/drive/utils.rs | 26 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/desktop/crates/cloudreve-api/src/models/uri.rs b/desktop/crates/cloudreve-api/src/models/uri.rs index db2bca66..fdbec085 100644 --- a/desktop/crates/cloudreve-api/src/models/uri.rs +++ b/desktop/crates/cloudreve-api/src/models/uri.rs @@ -499,3 +499,29 @@ pub fn new_my_uri(uid: Option<&str>) -> Result { None => CrUri::new("cloudreve://my"), } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn join_encodes_spaces_and_special_chars() { + let mut uri = CrUri::new("cloudreve://my").unwrap(); + uri.join(&["dir with spaces", "file name.txt"]); + + let s = uri.to_string(); + assert!( + s.contains("dir%20with%20spaces/file%20name.txt"), + "uri: {s}" + ); + assert!(!s.contains(' ')); + assert_eq!(uri.elements(), vec!["dir with spaces", "file name.txt"]); + } + + #[test] + fn encoded_uri_roundtrips_spaces() { + let uri = CrUri::new("cloudreve://my/a%20b/c%20d.txt").unwrap(); + assert_eq!(uri.path(), "/a b/c d.txt"); + assert!(uri.to_string().contains("a%20b/c%20d.txt")); + } +} diff --git a/desktop/crates/cloudreve-sync/src/drive/utils.rs b/desktop/crates/cloudreve-sync/src/drive/utils.rs index b0cf6fa7..787a680b 100644 --- a/desktop/crates/cloudreve-sync/src/drive/utils.rs +++ b/desktop/crates/cloudreve-sync/src/drive/utils.rs @@ -124,3 +124,29 @@ pub fn notify_shell_change(path: &PathBuf, event: SHCNE_ID) -> Result<()> { pub fn notify_shell_change(_path: &PathBuf, _event: u32) -> Result<()> { Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn local_path_to_cr_uri_encodes_spaces() { + let uri = local_path_to_cr_uri( + PathBuf::from("/sync/dir with spaces/file name.txt"), + PathBuf::from("/sync"), + "cloudreve://my".to_string(), + ) + .unwrap(); + + // The wire URI must carry percent-encoded segments, never raw spaces. + assert!( + uri.to_string() + .contains("dir%20with%20spaces/file%20name.txt"), + "uri: {}", + uri.to_string() + ); + assert!(!uri.to_string().contains(' ')); + // The decoded path round-trips to the original names. + assert_eq!(uri.path(), "/dir with spaces/file name.txt"); + } +}