|
7 | 7 | //! ③ 坐标有限值/zoom 正数校验(NaN/Infinity/0/负值/超界拒绝)。 |
8 | 8 |
|
9 | 9 | use crate::commands_knowledge_canvas::{ |
10 | | - batch_initialize_canvas_positions_inner, get_canvas_viewport_inner, |
11 | | - save_canvas_viewport_inner, update_node_canvas_position_inner, |
| 10 | + batch_initialize_canvas_positions_inner, get_canvas_prefs_inner, get_canvas_viewport_inner, |
| 11 | + save_canvas_prefs_inner, save_canvas_viewport_inner, update_node_canvas_position_inner, |
12 | 12 | }; |
13 | 13 | use crate::commands_knowledge_systems::{ |
14 | 14 | add_knowledge_node_inner, create_knowledge_system_inner, list_knowledge_nodes_inner, |
@@ -229,3 +229,54 @@ fn viewport_rejects_bad_zoom_and_unknown_system() { |
229 | 229 | // 拒绝后无记录 |
230 | 230 | assert_eq!(get_canvas_viewport_inner(&db, sid).expect("读"), None); |
231 | 231 | } |
| 232 | + |
| 233 | +#[test] |
| 234 | +fn canvas_prefs_save_get_roundtrip_and_default_missing() { |
| 235 | + // Arrange |
| 236 | + let db = mem_db(); |
| 237 | + let sid = make_global(&db); |
| 238 | + // Act:从未保存 → None(前端回落默认 smoothstep + radial) |
| 239 | + assert_eq!(get_canvas_prefs_inner(&db, sid).expect("首次读"), None); |
| 240 | + // 保存 → 回读 |
| 241 | + save_canvas_prefs_inner(&db, sid, "bezier", true, "mindmap").expect("保存"); |
| 242 | + let p = get_canvas_prefs_inner(&db, sid).expect("读").expect("有记录"); |
| 243 | + // Assert:camelCase 契约字段与箭头布尔往返 |
| 244 | + assert_eq!(p.edge_style, "bezier"); |
| 245 | + assert!(p.edge_arrows); |
| 246 | + assert_eq!(p.layout_algorithm, "mindmap"); |
| 247 | + // upsert 覆盖 |
| 248 | + save_canvas_prefs_inner(&db, sid, "straight", false, "org").expect("覆盖"); |
| 249 | + let p2 = get_canvas_prefs_inner(&db, sid).expect("读").expect("有"); |
| 250 | + assert_eq!((p2.edge_style.as_str(), p2.edge_arrows, p2.layout_algorithm.as_str()), ("straight", false, "org")); |
| 251 | +} |
| 252 | + |
| 253 | +#[test] |
| 254 | +fn canvas_prefs_rejects_unknown_enum_and_system() { |
| 255 | + // Arrange |
| 256 | + let db = mem_db(); |
| 257 | + let sid = make_global(&db); |
| 258 | + // Act/Assert:非法连线/布局枚举拒绝(白名单前后端同口径) |
| 259 | + assert!(save_canvas_prefs_inner(&db, sid, "curvy", false, "radial").is_err()); |
| 260 | + assert!(save_canvas_prefs_inner(&db, sid, "smoothstep", false, "force").is_err()); |
| 261 | + assert!(save_canvas_prefs_inner(&db, sid, "", false, "").is_err()); |
| 262 | + // 不存在的体系(save/get 都拒绝) |
| 263 | + assert!(save_canvas_prefs_inner(&db, 99999, "straight", false, "radial").is_err()); |
| 264 | + assert!(get_canvas_prefs_inner(&db, 99999).is_err()); |
| 265 | + // 非法 id 拒绝 |
| 266 | + assert!(save_canvas_prefs_inner(&db, 0, "straight", false, "radial").is_err()); |
| 267 | +} |
| 268 | + |
| 269 | +#[test] |
| 270 | +fn canvas_prefs_whitelist_all_valid_values() { |
| 271 | + // Arrange:合法枚举全套逐一试(防白名单漏项——前端枚举同口径) |
| 272 | + let db = mem_db(); |
| 273 | + let sid = make_global(&db); |
| 274 | + for style in ["straight", "bezier", "smoothstep", "step"] { |
| 275 | + for algo in ["radial", "mindmap", "treeRight", "org", "fishbone", "dualRing"] { |
| 276 | + save_canvas_prefs_inner(&db, sid, style, false, algo).expect("合法保存"); |
| 277 | + let p = get_canvas_prefs_inner(&db, sid).expect("读").expect("有"); |
| 278 | + assert_eq!(p.edge_style, style); |
| 279 | + assert_eq!(p.layout_algorithm, algo); |
| 280 | + } |
| 281 | + } |
| 282 | +} |
0 commit comments