- Implement FromStr trait for NodeType instead of custom from_str method - Fix redundant_closure warning in server.rs:455 - Add #[allow(clippy::too_many_arguments)] for new_file_node - Fix unused variables in tests (_user_id, _conn) - Remove unused imports (NodeType, serde_json::json) - Replace len() > 0 with !is_empty() for clarity - Replace == false with negation operator - Format code with cargo fmt
252 lines
7.5 KiB
Rust
252 lines
7.5 KiB
Rust
use markbase::filetree::{node::NodeType, FileTree};
|
|
use rusqlite::Connection;
|
|
use uuid::Uuid;
|
|
|
|
fn temp_db() -> (Connection, String) {
|
|
let user_id = format!("test_{}", Uuid::new_v4());
|
|
let conn = FileTree::init_user_db(&user_id).unwrap();
|
|
(conn, user_id)
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_create_folder_node() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let label = "TestFolder";
|
|
let node_type = NodeType::Folder;
|
|
|
|
let folder = FileTree::new_folder(label, None);
|
|
let node_id = folder.node_id.clone();
|
|
tree.insert_node(&conn, &folder).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
|
|
|
assert!(found.is_some());
|
|
let found_node = found.unwrap();
|
|
assert_eq!(found_node.label, label);
|
|
assert_eq!(found_node.node_type, node_type);
|
|
assert!(found_node.parent_id.is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_create_file_node() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let parent = FileTree::new_folder("Parent", None);
|
|
tree.insert_node(&conn, &parent).unwrap();
|
|
|
|
let (file_node, register_sql) = FileTree::new_file_node(
|
|
"test.mp4",
|
|
"abc123def456",
|
|
Some("sha256hash"),
|
|
"test.mp4",
|
|
Some(1024000),
|
|
Some("video/mp4"),
|
|
None,
|
|
Some(parent.node_id.clone()),
|
|
);
|
|
|
|
if let Some(sql) = register_sql {
|
|
conn.execute_batch(&sql).unwrap();
|
|
}
|
|
|
|
let node_id = file_node.node_id.clone();
|
|
tree.insert_node(&conn, &file_node).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
|
|
|
assert!(found.is_some());
|
|
let found_node = found.unwrap();
|
|
assert_eq!(found_node.label, "test.mp4");
|
|
assert_eq!(found_node.node_type, NodeType::File);
|
|
assert_eq!(found_node.parent_id, Some(parent.node_id.clone()));
|
|
assert_eq!(found_node.file_size, Some(1024000));
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_update_node() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let mut folder = FileTree::new_folder("Original", None);
|
|
tree.insert_node(&conn, &folder).unwrap();
|
|
|
|
folder.label = "Updated".to_string();
|
|
folder.icon = Some("📁".to_string());
|
|
folder.color = Some("#ff0000".to_string());
|
|
|
|
tree.update_node(&conn, &folder.node_id, &folder).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let found = loaded.nodes.iter().find(|n| n.node_id == folder.node_id);
|
|
|
|
assert!(found.is_some());
|
|
let found_node = found.unwrap();
|
|
assert_eq!(found_node.label, "Updated");
|
|
assert_eq!(found_node.icon, Some("📁".to_string()));
|
|
assert_eq!(found_node.color, Some("#ff0000".to_string()));
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_delete_node() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let folder = FileTree::new_folder("ToDelete", None);
|
|
let node_id = folder.node_id.clone();
|
|
tree.insert_node(&conn, &folder).unwrap();
|
|
|
|
tree.delete_node(&conn, &node_id).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let found = loaded.nodes.iter().find(|n| n.node_id == node_id);
|
|
|
|
assert!(found.is_none(), "deleted node should not be found");
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_move_node() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let root = FileTree::new_folder("Root", None);
|
|
let child = FileTree::new_folder("Child", Some(root.node_id.clone()));
|
|
|
|
tree.insert_node(&conn, &root).unwrap();
|
|
tree.insert_node(&conn, &child).unwrap();
|
|
|
|
tree.move_node(&conn, &child.node_id, None).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let moved = loaded.nodes.iter().find(|n| n.node_id == child.node_id);
|
|
|
|
assert!(moved.is_some());
|
|
assert!(
|
|
moved.unwrap().parent_id.is_none(),
|
|
"moved node should have no parent"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_update_alias() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let folder = FileTree::new_folder("Videos", None);
|
|
tree.insert_node(&conn, &folder).unwrap();
|
|
|
|
tree.update_node_alias(&conn, &folder.node_id, "zh_tw", "影片")
|
|
.unwrap();
|
|
tree.update_node_alias(&conn, &folder.node_id, "en_us", "Videos")
|
|
.unwrap();
|
|
tree.update_node_alias(&conn, &folder.node_id, "ja_jp", "動画")
|
|
.unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
let found = loaded.nodes.iter().find(|n| n.node_id == folder.node_id);
|
|
|
|
assert!(found.is_some());
|
|
let found_node = found.unwrap();
|
|
assert_eq!(
|
|
found_node.aliases.get("zh_tw").map(|s| s.as_str()),
|
|
Some("影片")
|
|
);
|
|
assert_eq!(
|
|
found_node.aliases.get("en_us").map(|s| s.as_str()),
|
|
Some("Videos")
|
|
);
|
|
assert_eq!(
|
|
found_node.aliases.get("ja_jp").map(|s| s.as_str()),
|
|
Some("動画")
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_get_tree() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let root = FileTree::new_folder("Root", None);
|
|
let child1 = FileTree::new_folder("Child1", Some(root.node_id.clone()));
|
|
let child2 = FileTree::new_folder("Child2", Some(root.node_id.clone()));
|
|
|
|
tree.insert_node(&conn, &root).unwrap();
|
|
tree.insert_node(&conn, &child1).unwrap();
|
|
tree.insert_node(&conn, &child2).unwrap();
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
assert_eq!(loaded.nodes.len(), 3);
|
|
assert_eq!(loaded.user_id, user_id);
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_build_tree_structure() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
let root = FileTree::new_folder("Root", None);
|
|
let child1 = FileTree::new_folder("Child1", Some(root.node_id.clone()));
|
|
let child2 = FileTree::new_folder("Child2", Some(root.node_id.clone()));
|
|
let grandchild = FileTree::new_folder("Grandchild", Some(child1.node_id.clone()));
|
|
|
|
tree.insert_node(&conn, &root).unwrap();
|
|
tree.insert_node(&conn, &child1).unwrap();
|
|
tree.insert_node(&conn, &child2).unwrap();
|
|
tree.insert_node(&conn, &grandchild).unwrap();
|
|
|
|
let roots = tree.build_tree();
|
|
|
|
assert_eq!(roots.len(), 1);
|
|
assert_eq!(roots[0].label, "Root");
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_add_location() {
|
|
let (_conn, user_id) = temp_db();
|
|
let conn = FileTree::open_user_db(&user_id).unwrap();
|
|
|
|
let file_uuid = "abc123def456";
|
|
let location = "/path/to/file.mp4";
|
|
|
|
FileTree::add_location(&conn, file_uuid, location, Some("origin")).unwrap();
|
|
|
|
let result: String = conn
|
|
.query_row(
|
|
"SELECT location FROM file_locations WHERE file_uuid = ?1",
|
|
[file_uuid],
|
|
|row| row.get(0),
|
|
)
|
|
.unwrap();
|
|
|
|
assert_eq!(result, location);
|
|
}
|
|
|
|
#[test]
|
|
fn test_api_delete_all_nodes() {
|
|
let (conn, user_id) = temp_db();
|
|
let mut tree = FileTree::load(&conn, &user_id).unwrap();
|
|
|
|
for i in 1..=5 {
|
|
let folder = FileTree::new_folder(&format!("Folder{}", i), None);
|
|
tree.insert_node(&conn, &folder).unwrap();
|
|
}
|
|
|
|
let loaded = FileTree::load(&conn, &user_id).unwrap();
|
|
assert_eq!(loaded.nodes.len(), 5);
|
|
|
|
for node in &loaded.nodes {
|
|
conn.execute(
|
|
"DELETE FROM file_nodes WHERE node_id = ?1",
|
|
rusqlite::params![node.node_id],
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
let after_delete = FileTree::load(&conn, &user_id).unwrap();
|
|
assert_eq!(after_delete.nodes.len(), 0);
|
|
}
|