Files
markbase/tests/api_logic_test.rs
Warren 8371aef693 fix: resolve clippy warnings and test errors
- 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
2026-05-16 16:13:37 +08:00

248 lines
7.2 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// API測試 - 使用整合測試方式
// 因handler函數未公開使用FileTree直接測試API邏輯
use markbase::filetree::node::NodeType;
use markbase::filetree::{mode, FileTree};
use rusqlite::Connection;
use uuid::Uuid;
fn temp_db() -> (Connection, String) {
let user_id = format!("test_api_{}", Uuid::new_v4());
let conn = FileTree::init_user_db(&user_id).unwrap();
(conn, user_id)
}
#[test]
fn test_api_logic_create_folder() {
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
let folder = FileTree::new_folder("API_Test_Folder", None);
tree.insert_node(&conn, &folder).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(loaded.nodes.len(), 1);
}
#[test]
fn test_api_logic_create_file() {
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
let (file_node, register_sql) = FileTree::new_file_node(
"test_api.mp4",
"api_test_uuid",
None,
"test_api.mp4",
Some(1024),
Some("video/mp4"),
None,
None,
);
if let Some(sql) = register_sql {
conn.execute_batch(&sql).unwrap();
}
tree.insert_node(&conn, &file_node).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(loaded.nodes.len(), 1);
assert_eq!(loaded.nodes[0].node_type, NodeType::File);
}
#[test]
fn test_api_logic_get_tree_with_mode() {
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
let folder = FileTree::new_folder("Root", None);
tree.insert_node(&conn, &folder).unwrap();
//測試不同顯示模式
let tree_mode = mode::get_mode("tree").unwrap();
let tree_rendered = tree_mode.render(&tree);
assert!(tree_rendered["nodes"].is_array());
let list_mode = mode::get_mode("list").unwrap();
let list_rendered = list_mode.render(&tree);
assert!(list_rendered["nodes"].is_array());
let grid_sm_mode = mode::get_mode("grid_sm").unwrap();
let grid_sm_rendered = grid_sm_mode.render(&tree);
assert!(grid_sm_rendered["nodes"].is_array());
}
#[test]
fn test_api_logic_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_via_API".to_string();
folder.icon = Some("🎬".to_string());
tree.update_node(&conn, &folder.node_id, &folder).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(loaded.nodes[0].label, "Updated_via_API");
assert_eq!(loaded.nodes[0].icon, Some("🎬".to_string()));
}
#[test]
fn test_api_logic_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();
assert_eq!(tree.nodes.len(), 1);
tree.delete_node(&conn, &node_id).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(loaded.nodes.len(), 0);
}
#[test]
fn test_api_logic_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);
//模擬delete_all_nodes API邏輯
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);
}
#[test]
fn test_api_logic_move_node() {
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
let parent = FileTree::new_folder("Parent", None);
let child = FileTree::new_folder("Child", Some(parent.node_id.clone()));
tree.insert_node(&conn, &parent).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_node = loaded
.nodes
.iter()
.find(|n| n.node_id == child.node_id)
.unwrap();
assert!(moved_node.parent_id.is_none());
}
#[test]
fn test_api_logic_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();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(
loaded.nodes[0].aliases.get("zh_tw").map(|s| s.as_str()),
Some("影片")
);
assert_eq!(
loaded.nodes[0].aliases.get("en_us").map(|s| s.as_str()),
Some("Videos")
);
}
#[test]
fn test_api_logic_nested_structure() {
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
let root = FileTree::new_folder("Root", None);
let level1 = FileTree::new_folder("Level1", Some(root.node_id.clone()));
let level2 = FileTree::new_folder("Level2", Some(level1.node_id.clone()));
tree.insert_node(&conn, &root).unwrap();
tree.insert_node(&conn, &level1).unwrap();
tree.insert_node(&conn, &level2).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert_eq!(loaded.nodes.len(), 3);
}
#[test]
fn test_api_logic_get_modes() {
let modes = mode::list_modes();
assert_eq!(modes.len(), 4);
let names: Vec<&str> = modes.iter().map(|m| m.name()).collect();
assert!(names.contains(&"tree"));
assert!(names.contains(&"list"));
assert!(names.contains(&"grid_sm"));
assert!(names.contains(&"grid_lg"));
}
#[test]
fn test_api_logic_file_info() {
let (conn, _user_id) = temp_db();
let file_uuid = "test_file_uuid_123";
FileTree::add_location(&conn, file_uuid, "/path/to/file.mp4", Some("origin")).unwrap();
let location: String = conn
.query_row(
"SELECT location FROM file_locations WHERE file_uuid = ?1",
[file_uuid],
|row| row.get(0),
)
.unwrap();
assert_eq!(location, "/path/to/file.mp4");
}
#[test]
fn test_api_logic_restore_scenario() {
//模擬restore_tree API邏輯
let (conn, user_id) = temp_db();
let mut tree = FileTree::load(&conn, &user_id).unwrap();
//建立基本結構
let home = FileTree::new_folder("Home", None);
let movies = FileTree::new_folder("Movies", Some(home.node_id.clone()));
tree.insert_node(&conn, &home).unwrap();
tree.insert_node(&conn, &movies).unwrap();
let loaded = FileTree::load(&conn, &user_id).unwrap();
assert!(loaded.nodes.iter().any(|n| n.label == "Home"));
assert!(loaded.nodes.iter().any(|n| n.label == "Movies"));
}