use chrono::Utc;
use serde_json::Value;
use std::collections::HashMap;
use crate::{
manager::{PostArchiverManager, UpdateFileMeta},
tests::helpers,
FileMetaId, PostId,
};
fn create_test_post(manager: &PostArchiverManager) -> PostId {
let now = Utc::now();
helpers::add_post(
manager,
"Test Post".into(),
None,
None,
Some(now),
Some(now),
)
}
fn create_test_extra() -> HashMap<String, Value> {
let mut extra = HashMap::new();
extra.insert("width".into(), Value::Number(1920.into()));
extra.insert("height".into(), Value::Number(1080.into()));
extra.insert("description".into(), Value::String("Test image".into()));
extra
}
#[test]
fn test_add_file_meta() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let extra = create_test_extra();
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"test_image.jpg".into(),
"image/jpeg".into(),
extra.clone(),
);
assert!(file_meta_id.raw() > 0);
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.id, file_meta_id);
assert_eq!(fm.post, post_id);
assert_eq!(fm.filename, "test_image.jpg");
assert_eq!(fm.mime, "image/jpeg");
assert_eq!(fm.extra, extra);
}
#[test]
fn test_get_file_meta() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let extra = create_test_extra();
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"get_test.png".into(),
"image/png".into(),
extra.clone(),
);
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.id, file_meta_id);
assert_eq!(fm.post, post_id);
assert_eq!(fm.filename, "get_test.png");
assert_eq!(fm.mime, "image/png");
assert_eq!(fm.extra, extra);
}
#[test]
fn test_find_file_meta() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"findme.gif".into(),
"image/gif".into(),
HashMap::new(),
);
let found_id = helpers::find_file_meta(&manager, post_id, "findme.gif");
assert_eq!(found_id, Some(file_meta_id));
let not_found = helpers::find_file_meta(&manager, post_id, "nonexistent.txt");
assert_eq!(not_found, None);
let other_post_id = create_test_post(&manager);
let not_found = helpers::find_file_meta(&manager, other_post_id, "findme.gif");
assert_eq!(not_found, None);
}
#[test]
fn test_remove_file_meta() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"to_delete.txt".into(),
"text/plain".into(),
HashMap::new(),
);
let _ = helpers::get_file_meta(&manager, file_meta_id);
manager.bind(file_meta_id).delete().unwrap();
let found = helpers::find_file_meta(&manager, post_id, "to_delete.txt");
assert_eq!(found, None);
}
#[test]
fn test_set_file_meta_mime() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"mime_test.file".into(),
"application/octet-stream".into(),
HashMap::new(),
);
manager
.bind(file_meta_id)
.update(UpdateFileMeta::default().mime("text/plain".into()))
.unwrap();
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.mime, "text/plain");
}
#[test]
fn test_set_file_meta_extra() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"extra_test.json".into(),
"application/json".into(),
HashMap::new(),
);
let mut new_extra = HashMap::new();
new_extra.insert("size".into(), Value::Number(12345.into()));
new_extra.insert("compressed".into(), Value::Bool(true));
new_extra.insert("algorithm".into(), Value::String("gzip".into()));
manager
.bind(file_meta_id)
.update(UpdateFileMeta::default().extra(new_extra.clone()))
.unwrap();
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.extra, new_extra);
}
#[test]
fn test_multiple_files_same_post() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file1 = helpers::add_file_meta(
&manager,
post_id,
"file1.jpg".into(),
"image/jpeg".into(),
HashMap::new(),
);
let file2 = helpers::add_file_meta(
&manager,
post_id,
"file2.png".into(),
"image/png".into(),
HashMap::new(),
);
let found1 = helpers::find_file_meta(&manager, post_id, "file1.jpg");
let found2 = helpers::find_file_meta(&manager, post_id, "file2.png");
assert_eq!(found1, Some(file1));
assert_eq!(found2, Some(file2));
let meta1 = helpers::get_file_meta(&manager, file1);
let meta2 = helpers::get_file_meta(&manager, file2);
assert_eq!(meta1.filename, "file1.jpg");
assert_eq!(meta2.filename, "file2.png");
assert_eq!(meta1.post, post_id);
assert_eq!(meta2.post, post_id);
}
#[test]
fn test_same_filename_different_posts() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post1_id = create_test_post(&manager);
let post2_id = create_test_post(&manager);
let filename = "shared_name.txt".to_string();
let file1 = helpers::add_file_meta(
&manager,
post1_id,
filename.clone(),
"text/plain".into(),
HashMap::new(),
);
let file2 = helpers::add_file_meta(
&manager,
post2_id,
filename.clone(),
"text/plain".into(),
HashMap::new(),
);
let found1 = helpers::find_file_meta(&manager, post1_id, &filename);
let found2 = helpers::find_file_meta(&manager, post2_id, &filename);
assert_eq!(found1, Some(file1));
assert_eq!(found2, Some(file2));
assert_ne!(file1, file2);
}
#[test]
fn test_complex_extra_metadata() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let mut extra = HashMap::new();
extra.insert("simple_string".into(), Value::String("test".into()));
extra.insert("number".into(), Value::Number(42.into()));
extra.insert("boolean".into(), Value::Bool(true));
extra.insert("null_value".into(), Value::Null);
let mut nested = HashMap::new();
nested.insert("inner_key".into(), Value::String("inner_value".into()));
nested.insert("inner_number".into(), Value::Number(123.into()));
extra.insert(
"nested_object".into(),
Value::Object(nested.into_iter().collect()),
);
let array = vec![
Value::String("item1".into()),
Value::Number(456.into()),
Value::Bool(false),
];
extra.insert("array".into(), Value::Array(array));
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"complex.json".into(),
"application/json".into(),
extra.clone(),
);
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.extra, extra);
}
#[test]
fn test_empty_extra_metadata() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"empty_extra.txt".into(),
"text/plain".into(),
HashMap::new(),
);
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert!(fm.extra.is_empty());
}
#[test]
fn test_update_extra_metadata_multiple_times() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
"update_test.txt".into(),
"text/plain".into(),
HashMap::new(),
);
let mut extra1 = HashMap::new();
extra1.insert("version".into(), Value::Number(1.into()));
manager
.bind(file_meta_id)
.update(UpdateFileMeta::default().extra(extra1.clone()))
.unwrap();
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.extra, extra1);
let mut extra2 = HashMap::new();
extra2.insert("version".into(), Value::Number(2.into()));
extra2.insert("author".into(), Value::String("test_user".into()));
manager
.bind(file_meta_id)
.update(UpdateFileMeta::default().extra(extra2.clone()))
.unwrap();
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.extra, extra2);
}
#[test]
fn test_update_nonexistent_file_meta() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let fake_id = FileMetaId::new(99999);
let mime_result = manager
.bind(fake_id)
.update(UpdateFileMeta::default().mime("text/plain".into()));
assert!(mime_result.is_ok());
let extra_result = manager
.bind(fake_id)
.update(UpdateFileMeta::default().extra(HashMap::new()));
assert!(extra_result.is_ok());
}
#[test]
fn test_special_characters_in_filename() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let special_filename =
"test file with spaces & symbols!@#$%^&()_+-=[]{}|;':\",./<>?.txt".to_string();
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
special_filename.clone(),
"text/plain".into(),
HashMap::new(),
);
let found_id = helpers::find_file_meta(&manager, post_id, &special_filename);
assert_eq!(found_id, Some(file_meta_id));
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.filename, special_filename);
}
#[test]
fn test_unicode_filename() {
let manager = PostArchiverManager::open_in_memory().unwrap();
let post_id = create_test_post(&manager);
let unicode_filename = "测试文件_тест_ファイル_🎉.txt".to_string();
let file_meta_id = helpers::add_file_meta(
&manager,
post_id,
unicode_filename.clone(),
"text/plain".into(),
HashMap::new(),
);
let found_id = helpers::find_file_meta(&manager, post_id, &unicode_filename);
assert_eq!(found_id, Some(file_meta_id));
let fm = helpers::get_file_meta(&manager, file_meta_id);
assert_eq!(fm.filename, unicode_filename);
}