//! Project flow integration tests. //! //! Tests the project lifecycle: create, list, set active, switch, delete. //! Uses in-memory DB — no Iced window required. use bds_core::db::Database; use bds_core::engine::project; use tempfile::TempDir; fn setup() -> (Database, TempDir) { let db = Database::open_in_memory().unwrap(); db.migrate().unwrap(); let dir = TempDir::new().unwrap(); (db, dir) } #[test] fn create_and_activate_default_project() { let (db, dir) = setup(); let data_path = dir.path().join("my-blog"); let p = project::create_project(db.conn(), "My Blog", Some(data_path.to_str().unwrap())).unwrap(); assert_eq!(p.name, "My Blog"); assert_eq!(p.slug, "my-blog"); assert!(!p.is_active); // Activate it project::set_active_project(db.conn(), &p.id).unwrap(); let active = project::get_active_project(db.conn()).unwrap().unwrap(); assert_eq!(active.id, p.id); } #[test] fn switch_between_projects() { let (db, dir) = setup(); let p1_path = dir.path().join("blog-a"); let p2_path = dir.path().join("blog-b"); let p1 = project::create_project(db.conn(), "Blog A", Some(p1_path.to_str().unwrap())).unwrap(); let p2 = project::create_project(db.conn(), "Blog B", Some(p2_path.to_str().unwrap())).unwrap(); project::set_active_project(db.conn(), &p1.id).unwrap(); let active = project::get_active_project(db.conn()).unwrap().unwrap(); assert_eq!(active.id, p1.id); // Switch project::set_active_project(db.conn(), &p2.id).unwrap(); let active = project::get_active_project(db.conn()).unwrap().unwrap(); assert_eq!(active.id, p2.id); } #[test] fn delete_inactive_project() { let (db, dir) = setup(); let p1_path = dir.path().join("keep"); let p2_path = dir.path().join("remove"); let p1 = project::create_project(db.conn(), "Keep", Some(p1_path.to_str().unwrap())).unwrap(); let p2 = project::create_project(db.conn(), "Remove", Some(p2_path.to_str().unwrap())).unwrap(); project::set_active_project(db.conn(), &p1.id).unwrap(); project::delete_project(db.conn(), &p2.id, Some(&p2_path)).unwrap(); let list = project::list_projects(db.conn()).unwrap(); assert_eq!(list.len(), 1); assert_eq!(list[0].name, "Keep"); } #[test] fn cannot_delete_active_project() { let (db, dir) = setup(); let p_path = dir.path().join("active"); let p = project::create_project(db.conn(), "Active", Some(p_path.to_str().unwrap())).unwrap(); project::set_active_project(db.conn(), &p.id).unwrap(); let result = project::delete_project(db.conn(), &p.id, None); assert!(result.is_err()); } #[test] fn project_directory_structure_created() { let (db, dir) = setup(); let p_path = dir.path().join("structured"); project::create_project(db.conn(), "Structured", Some(p_path.to_str().unwrap())).unwrap(); assert!(p_path.join("posts").is_dir()); assert!(p_path.join("media").is_dir()); assert!(p_path.join("meta").is_dir()); assert!(p_path.join("thumbnails").is_dir()); assert!(p_path.join("templates").is_dir()); assert!(p_path.join("scripts").is_dir()); } #[test] fn default_meta_files_written() { let (db, dir) = setup(); let p_path = dir.path().join("meta-test"); project::create_project(db.conn(), "Meta Test", Some(p_path.to_str().unwrap())).unwrap(); let project_json: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(p_path.join("meta/project.json")).unwrap()) .unwrap(); assert_eq!(project_json["name"], "Meta Test"); assert_eq!(project_json["maxPostsPerPage"], 50); let categories: Vec = serde_json::from_str( &std::fs::read_to_string(p_path.join("meta/categories.json")).unwrap(), ) .unwrap(); assert_eq!(categories, vec!["article", "aside", "page", "picture"]); let tags: Vec = serde_json::from_str(&std::fs::read_to_string(p_path.join("meta/tags.json")).unwrap()) .unwrap(); assert!(tags.is_empty()); }