Refactor file type checking for better consistency
Fix tests
This commit is contained in:
123
src/files.rs
123
src/files.rs
@@ -12,6 +12,7 @@ use anyhow::{Context, anyhow};
|
||||
|
||||
use crate::data::{Claims, FilesRequest, FilterMode, MediaType, PhotosResponse, SortType};
|
||||
use crate::database::ExifDao;
|
||||
use crate::file_types;
|
||||
use crate::geo::{gps_bounding_box, haversine_distance};
|
||||
use crate::memories::extract_date_from_filename;
|
||||
use crate::{AppState, create_thumbnails};
|
||||
@@ -652,49 +653,22 @@ pub fn list_files_recursive(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
}
|
||||
|
||||
pub fn is_image_or_video(path: &Path) -> bool {
|
||||
let extension = path
|
||||
.extension()
|
||||
.and_then(|p| p.to_str())
|
||||
.map_or(String::from(""), |p| p.to_lowercase());
|
||||
|
||||
extension == "png"
|
||||
|| extension == "jpg"
|
||||
|| extension == "jpeg"
|
||||
|| extension == "mp4"
|
||||
|| extension == "mov"
|
||||
|| extension == "nef"
|
||||
|| extension == "webp"
|
||||
|| extension == "tiff"
|
||||
|| extension == "tif"
|
||||
|| extension == "heif"
|
||||
|| extension == "heic"
|
||||
|| extension == "avif"
|
||||
file_types::is_media_file(path)
|
||||
}
|
||||
|
||||
/// Check if a file matches the media type filter
|
||||
fn matches_media_type(path: &Path, media_type: &MediaType) -> bool {
|
||||
let result = match media_type {
|
||||
MediaType::All => file_types::is_image_file(path) || file_types::is_video_file(path),
|
||||
MediaType::Photo => file_types::is_image_file(path),
|
||||
MediaType::Video => file_types::is_video_file(path),
|
||||
};
|
||||
|
||||
let extension = path
|
||||
.extension()
|
||||
.and_then(|p| p.to_str())
|
||||
.map_or(String::from(""), |p| p.to_lowercase());
|
||||
|
||||
let result = match media_type {
|
||||
MediaType::All => true,
|
||||
MediaType::Photo => {
|
||||
extension == "png"
|
||||
|| extension == "jpg"
|
||||
|| extension == "jpeg"
|
||||
|| extension == "nef"
|
||||
|| extension == "webp"
|
||||
|| extension == "tiff"
|
||||
|| extension == "tif"
|
||||
|| extension == "heif"
|
||||
|| extension == "heic"
|
||||
|| extension == "avif"
|
||||
}
|
||||
MediaType::Video => extension == "mp4" || extension == "mov",
|
||||
};
|
||||
|
||||
debug!(
|
||||
"Media type check: path={:?}, extension='{}', type={:?}, match={}",
|
||||
path, extension, media_type, result
|
||||
@@ -873,6 +847,7 @@ mod tests {
|
||||
|
||||
struct FakeFileSystem {
|
||||
files: HashMap<String, Vec<String>>,
|
||||
base_path: String,
|
||||
err: bool,
|
||||
}
|
||||
|
||||
@@ -880,12 +855,19 @@ mod tests {
|
||||
fn with_error() -> FakeFileSystem {
|
||||
FakeFileSystem {
|
||||
files: HashMap::new(),
|
||||
base_path: String::new(),
|
||||
err: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn new(files: HashMap<String, Vec<String>>) -> FakeFileSystem {
|
||||
FakeFileSystem { files, err: false }
|
||||
// Use temp dir as base path for consistency
|
||||
let base_path = env::temp_dir();
|
||||
FakeFileSystem {
|
||||
files,
|
||||
base_path: base_path.to_str().unwrap().to_string(),
|
||||
err: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -894,7 +876,11 @@ mod tests {
|
||||
if self.err {
|
||||
Err(anyhow!("Error for test"))
|
||||
} else if let Some(files) = self.files.get(path) {
|
||||
Ok(files.iter().map(PathBuf::from).collect::<Vec<PathBuf>>())
|
||||
// Prepend base_path to all returned files
|
||||
Ok(files
|
||||
.iter()
|
||||
.map(|f| PathBuf::from(&self.base_path).join(f))
|
||||
.collect::<Vec<PathBuf>>())
|
||||
} else {
|
||||
Ok(Vec::new())
|
||||
}
|
||||
@@ -1043,22 +1029,36 @@ mod tests {
|
||||
|
||||
let request: Query<FilesRequest> = Query::from_query("path=").unwrap();
|
||||
|
||||
let mut temp_photo = env::temp_dir();
|
||||
let mut tmp = temp_photo.clone();
|
||||
// Create a dedicated test directory to avoid interference from other files in system temp
|
||||
let mut test_base = env::temp_dir();
|
||||
test_base.push("image_api_test_list_photos");
|
||||
fs::create_dir_all(&test_base).unwrap();
|
||||
|
||||
tmp.push("test-dir");
|
||||
fs::create_dir_all(tmp).unwrap();
|
||||
let mut test_dir = test_base.clone();
|
||||
test_dir.push("test-dir");
|
||||
fs::create_dir_all(&test_dir).unwrap();
|
||||
|
||||
temp_photo.push("photo.jpg");
|
||||
let mut photo_path = test_base.clone();
|
||||
photo_path.push("photo.jpg");
|
||||
File::create(&photo_path).unwrap();
|
||||
|
||||
File::create(temp_photo.clone()).unwrap();
|
||||
// Create AppState with the same base_path as RealFileSystem
|
||||
use actix::Actor;
|
||||
let test_state = AppState::new(
|
||||
std::sync::Arc::new(crate::video::actors::StreamActor {}.start()),
|
||||
test_base.to_str().unwrap().to_string(),
|
||||
test_base.join("thumbnails").to_str().unwrap().to_string(),
|
||||
test_base.join("videos").to_str().unwrap().to_string(),
|
||||
test_base.join("gifs").to_str().unwrap().to_string(),
|
||||
Vec::new(),
|
||||
);
|
||||
|
||||
let response: HttpResponse = list_photos(
|
||||
claims,
|
||||
TestRequest::default().to_http_request(),
|
||||
request,
|
||||
Data::new(AppState::test_state()),
|
||||
Data::new(RealFileSystem::new(String::from("/tmp"))),
|
||||
Data::new(test_state),
|
||||
Data::new(RealFileSystem::new(test_base.to_str().unwrap().to_string())),
|
||||
Data::new(Mutex::new(SqliteTagDao::default())),
|
||||
Data::new(Mutex::new(
|
||||
Box::new(MockExifDao) as Box<dyn crate::database::ExifDao>
|
||||
@@ -1082,6 +1082,9 @@ mod tests {
|
||||
.collect::<Vec<&String>>()
|
||||
.is_empty()
|
||||
);
|
||||
|
||||
// Cleanup
|
||||
let _ = fs::remove_dir_all(test_base);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
@@ -1095,12 +1098,13 @@ mod tests {
|
||||
|
||||
let request: Query<FilesRequest> = Query::from_query("path=..").unwrap();
|
||||
|
||||
let temp_dir = env::temp_dir();
|
||||
let response = list_photos(
|
||||
claims,
|
||||
TestRequest::default().to_http_request(),
|
||||
request,
|
||||
Data::new(AppState::test_state()),
|
||||
Data::new(RealFileSystem::new(String::from("./"))),
|
||||
Data::new(RealFileSystem::new(temp_dir.to_str().unwrap().to_string())),
|
||||
Data::new(Mutex::new(SqliteTagDao::default())),
|
||||
Data::new(Mutex::new(
|
||||
Box::new(MockExifDao) as Box<dyn crate::database::ExifDao>
|
||||
@@ -1120,7 +1124,8 @@ mod tests {
|
||||
exp: 12345,
|
||||
};
|
||||
|
||||
let request: Query<FilesRequest> = Query::from_query("path=&tag_ids=1,3").unwrap();
|
||||
let request: Query<FilesRequest> =
|
||||
Query::from_query("path=&tag_ids=1,3&recursive=true").unwrap();
|
||||
|
||||
let mut tag_dao = SqliteTagDao::new(in_memory_db_connection());
|
||||
|
||||
@@ -1141,22 +1146,12 @@ mod tests {
|
||||
.tag_file(&opentelemetry::Context::current(), "test.jpg", tag3.id)
|
||||
.unwrap();
|
||||
|
||||
let mut files = HashMap::new();
|
||||
files.insert(
|
||||
String::from(""),
|
||||
vec![
|
||||
String::from("file1.txt"),
|
||||
String::from("test.jpg"),
|
||||
String::from("some-other.jpg"),
|
||||
],
|
||||
);
|
||||
|
||||
let response: HttpResponse = list_photos(
|
||||
claims,
|
||||
TestRequest::default().to_http_request(),
|
||||
request,
|
||||
Data::new(AppState::test_state()),
|
||||
Data::new(FakeFileSystem::new(files)),
|
||||
Data::new(FakeFileSystem::new(HashMap::new())),
|
||||
Data::new(Mutex::new(tag_dao)),
|
||||
Data::new(Mutex::new(
|
||||
Box::new(MockExifDao) as Box<dyn crate::database::ExifDao>
|
||||
@@ -1208,18 +1203,8 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut files = HashMap::new();
|
||||
files.insert(
|
||||
String::from(""),
|
||||
vec![
|
||||
String::from("file1.txt"),
|
||||
String::from("test.jpg"),
|
||||
String::from("some-other.jpg"),
|
||||
],
|
||||
);
|
||||
|
||||
let request: Query<FilesRequest> = Query::from_query(&format!(
|
||||
"path=&tag_ids={},{}&tag_filter_mode=All",
|
||||
"path=&tag_ids={},{}&tag_filter_mode=All&recursive=true",
|
||||
tag1.id, tag3.id
|
||||
))
|
||||
.unwrap();
|
||||
@@ -1229,7 +1214,7 @@ mod tests {
|
||||
TestRequest::default().to_http_request(),
|
||||
request,
|
||||
Data::new(AppState::test_state()),
|
||||
Data::new(FakeFileSystem::new(files)),
|
||||
Data::new(FakeFileSystem::new(HashMap::new())),
|
||||
Data::new(Mutex::new(tag_dao)),
|
||||
Data::new(Mutex::new(
|
||||
Box::new(MockExifDao) as Box<dyn crate::database::ExifDao>
|
||||
|
||||
Reference in New Issue
Block a user