From 92a76613e5ebd1e3250512aeebb5c083fcc43d13 Mon Sep 17 00:00:00 2001 From: peterrabbit <pierre.jarriges@tutanota.com> Date: Sun, 4 Sep 2022 17:35:13 +0200 Subject: [PATCH] test static files manager --- src/static_files.rs | 184 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 168 insertions(+), 16 deletions(-) diff --git a/src/static_files.rs b/src/static_files.rs index a8364f2..0f07ddd 100644 --- a/src/static_files.rs +++ b/src/static_files.rs @@ -7,6 +7,15 @@ pub struct StaticFilesManager { pub index: Vec<String>, } +const STATIC_ASSETS_DIRECTORIES: [&'static str; 6] = [ + "images", + "sounds", + "videos", + "docs", + "source_code", + "default", +]; + impl StaticFilesManager { pub fn new(app_state: &AppState) -> Result<Self, String> { match Self::create_dir_if_missing(&app_state.config.storage_dir) { @@ -18,12 +27,27 @@ impl StaticFilesManager { } } + #[cfg(test)] + pub fn testing_new(test_dir: &PathBuf) -> Result<Self, String> { + match Self::create_dir_if_missing(test_dir) { + Ok(dir) => Ok(StaticFilesManager { + index: Vec::new(), + dir, + }), + Err(msg) => Err(msg), + } + } + fn create_dir_if_missing(app_dir: &PathBuf) -> Result<PathBuf, String> { let static_dir = app_dir.join("static"); if !static_dir.exists() { match std::fs::create_dir_all(&static_dir) { Ok(_) => { + if let Err(err) = Self::create_assets_directories_structure(&static_dir) { + return Err(format!("{}", err)); + }; + if let Err(err) = Self::copy_default_files(&static_dir) { return Err(format!("{}", err)); } @@ -35,19 +59,22 @@ impl StaticFilesManager { Ok(static_dir) } + fn create_assets_directories_structure(root: &PathBuf) -> Result<(), std::io::Error> { + for d in STATIC_ASSETS_DIRECTORIES { + std::fs::create_dir(root.join(d))?; + } + + Ok(()) + } + fn copy_default_files(static_dir: &PathBuf) -> Result<(), String> { let local_default_static = std::env::current_dir().unwrap().join("default_static"); let default_static = static_dir.join("default"); - match std::fs::create_dir_all(&default_static) { + let mut cpy_options = fs_extra::dir::CopyOptions::new(); + cpy_options.content_only = true; + match fs_extra::dir::copy(local_default_static, default_static, &cpy_options) { Err(err) => Err(format!("{}", err)), - Ok(_) => { - let mut cpy_options = fs_extra::dir::CopyOptions::new(); - cpy_options.content_only = true; - match fs_extra::dir::copy(local_default_static, default_static, &cpy_options) { - Err(err) => Err(format!("{}", err)), - Ok(_) => Ok(()), - } - } + Ok(_) => Ok(()), } } @@ -57,20 +84,44 @@ impl StaticFilesManager { if entry.path().is_dir() { self.rec_read_dir(&entry.path(), strip_from); } else { - self._push_path(&entry.path(), strip_from); + self.push_path(&entry.path().strip_prefix(strip_from).unwrap()); } } } } - fn _push_path(&mut self, path: &Path, strip_from: &Path) { - let push_path = path.strip_prefix(strip_from).unwrap(); - self.index - .push(format!("/{}", push_path.to_str().unwrap().to_owned())); + fn validate_path(&self, path: &Path) -> bool { + self.dir.join(self.clean_relative_path(path)).exists() + } + + fn clean_relative_path(&self, path: &Path) -> PathBuf { + match path.starts_with("/") { + true => path.strip_prefix("/").unwrap().to_path_buf(), + false => path.to_path_buf(), + } + } + + fn push_path(&mut self, path: &Path) -> Vec<PathBuf> { + if self.validate_path(path) { + self.index + .push(format!("/{}", path.to_str().unwrap().to_owned())); + vec![path.to_path_buf()] + } else { + println!( + "[WARNING] Error building static file index. The file {:?} doesn't exist and will be removed from the index.", + self.dir.join(self.clean_relative_path(path)), + ); + Vec::new() + } } - pub fn add_pathes(&mut self, pathes: &Vec<String>) { - self.index.extend(pathes.iter().map(|p| p.to_owned())); + pub fn add_pathes(&mut self, pathes: &Vec<String>) -> Vec<PathBuf> { + let mut added: Vec<PathBuf> = Vec::new(); + for pth in pathes.iter() { + let p = self.push_path(Path::new(pth)); + added.extend(p.iter().map(|pb| pb.clone())); + } + added } pub fn build(&mut self) -> Self { @@ -79,3 +130,104 @@ impl StaticFilesManager { self.clone() } } + +#[cfg(test)] +mod test_static_files_manager { + use super::*; + + fn create_test_dir() -> PathBuf { + let pth = PathBuf::from("./test"); + let _ = std::fs::create_dir(&pth); + pth + } + + fn remove_test_dir(pth: &PathBuf) { + let _ = std::fs::remove_dir_all(pth); + } + + #[test] + fn test_directory_structure() { + let test_dir = create_test_dir(); + let _manager = StaticFilesManager::testing_new(&test_dir).unwrap(); + + for d in STATIC_ASSETS_DIRECTORIES { + let p = test_dir.join("static").join(d); + let exists = p.exists(); + assert!( + exists, + "{} doesn't exist\n{:?}", + p.display(), + remove_test_dir(&test_dir) + ); + } + + remove_test_dir(&test_dir); + } + + #[test] + fn test_indexation() { + let test_dir = create_test_dir(); + let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap(); + let file_pth = test_dir.join("static").join("docs").join("testing.txt"); + std::fs::File::create(&file_pth).unwrap(); + manager = manager.build(); + + assert!( + manager.index.contains(&"/docs/testing.txt".to_string()), + "Index doesn't contain path /docs/testing.txt\n{:?}", + remove_test_dir(&test_dir) + ); + + remove_test_dir(&test_dir); + } + + #[test] + fn test_push_path() { + let test_dir = create_test_dir(); + let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap().build(); + let file_pth = test_dir.join("static").join("docs").join("testing.txt"); + std::fs::File::create(&file_pth).unwrap(); + let indexed_path = Path::new("docs/testing.txt"); + let added = manager.push_path(&indexed_path); + + assert_eq!( + added, + vec![PathBuf::from("docs/testing.txt")], + "Path was not added\n{:?}", + remove_test_dir(&test_dir) + ); + + assert!( + manager.index.contains(&"/docs/testing.txt".to_string()), + "Index doesn't contain path /docs/testing.txt\n{:?}", + remove_test_dir(&test_dir) + ); + + remove_test_dir(&test_dir); + } + + #[test] + fn test_push_unexisting_path() { + let test_dir = create_test_dir(); + let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap().build(); + let indexed_path = Path::new("images/unexisting.png"); + let added = manager.push_path(&indexed_path); + + assert_eq!( + added.len(), + 0, + "No path should have been added\n{:?}", + remove_test_dir(&test_dir) + ); + + assert!( + !manager + .index + .contains(&"/images/unexisting.png".to_string()), + "Index shouldn't container unexisting path\n{:?}", + remove_test_dir(&test_dir) + ); + + remove_test_dir(&test_dir); + } +} -- GitLab