46d5c3ec96
Every save of a changed note keeps a snapshot (at most one per 5 minutes, newest 20, under .notescraft/history), engine history.list/history.read, a Versions tab with Compare and Restore. Task 31 marked built (git history existed), task 34 deferred by the owner. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
70 lines
4.1 KiB
Rust
70 lines
4.1 KiB
Rust
//! Saved workspaces: `workspace.save`, `workspace.list`, `workspace.load`, `workspace.delete`.
|
|
|
|
mod common;
|
|
|
|
use common::{temp_config, temp_vault};
|
|
use notescraft_engine::{Registry, Session, register_core};
|
|
use serde_json::json;
|
|
|
|
#[test]
|
|
fn a_layout_is_saved_listed_loaded_replaced_and_deleted() {
|
|
let vault = temp_vault("workspaces");
|
|
let config = temp_config("workspaces");
|
|
let mut registry = Registry::new();
|
|
register_core(&mut registry).expect("register");
|
|
let mut session = Session::open(vault.path()).expect("open");
|
|
session.use_settings_dir(config.path());
|
|
let layout = json!({"tabs": ["a.md", "b.md"], "active": 1});
|
|
registry.run("workspace.save", &mut session, &json!({"name": "Writing", "layout": layout})).expect("save");
|
|
registry.run("workspace.save", &mut session, &json!({"name": "Review", "layout": {"tabs": []}})).expect("save");
|
|
assert_eq!(registry.run("workspace.list", &mut session, &json!({})).expect("list")["workspaces"], json!(["Review", "Writing"]));
|
|
assert_eq!(registry.run("workspace.load", &mut session, &json!({"name": "Writing"})).expect("load")["layout"], layout);
|
|
registry.run("workspace.save", &mut session, &json!({"name": "Writing", "layout": {"tabs": ["c.md"]}})).expect("replace");
|
|
assert_eq!(registry.run("workspace.load", &mut session, &json!({"name": "Writing"})).expect("load")["layout"]["tabs"], json!(["c.md"]));
|
|
registry.run("workspace.delete", &mut session, &json!({"name": "Review"})).expect("delete");
|
|
assert_eq!(registry.run("workspace.list", &mut session, &json!({})).expect("list")["workspaces"], json!(["Writing"]));
|
|
assert!(registry.run("workspace.load", &mut session, &json!({"name": "Review"})).is_err());
|
|
assert!(registry.run("workspace.delete", &mut session, &json!({"name": "Review"})).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn hostile_names_and_oversized_layouts_are_refused() {
|
|
let vault = temp_vault("workspaces-bad");
|
|
let config = temp_config("workspaces-bad");
|
|
let mut registry = Registry::new();
|
|
register_core(&mut registry).expect("register");
|
|
let mut session = Session::open(vault.path()).expect("open");
|
|
session.use_settings_dir(config.path());
|
|
for name in ["", " pad", ".hidden", "../up", "a/b", "a\\b", "x:y", &"n".repeat(65), "tab\tname"] {
|
|
assert!(registry.run("workspace.save", &mut session, &json!({"name": name, "layout": {}})).is_err(), "{name:?}");
|
|
assert!(registry.run("workspace.load", &mut session, &json!({"name": name})).is_err(), "{name:?}");
|
|
}
|
|
let big = json!({"x": "y".repeat(300_000)});
|
|
assert!(registry.run("workspace.save", &mut session, &json!({"name": "big", "layout": big})).is_err());
|
|
assert_eq!(registry.run("workspace.list", &mut session, &json!({})).expect("list")["workspaces"], json!([]));
|
|
}
|
|
|
|
#[test]
|
|
fn saving_a_note_keeps_a_local_snapshot_a_command_lists_and_reads() {
|
|
let vault = temp_vault("snapshots");
|
|
let config = temp_config("snapshots");
|
|
std::fs::write(vault.path().join("n.md"), "first\n").expect("seed");
|
|
let mut registry = Registry::new();
|
|
register_core(&mut registry).expect("register");
|
|
let mut session = Session::open(vault.path()).expect("open");
|
|
session.use_settings_dir(config.path());
|
|
session.open_buffer("n.md").expect("buffer");
|
|
session.buffer_mut("n.md").expect("buffer").edit(0..5, "second").expect("edit");
|
|
session.save_buffer("n.md").expect("save");
|
|
session.buffer_mut("n.md").expect("buffer").edit(0..6, "third").expect("edit");
|
|
session.save_buffer("n.md").expect("save again at once");
|
|
let listed = registry.run("history.list", &mut session, &json!({"path": "n.md"})).expect("list");
|
|
let versions = listed["versions"].as_array().expect("array");
|
|
assert_eq!(versions.len(), 1, "the second save came inside the gap");
|
|
let id = versions[0]["id"].as_u64().expect("id");
|
|
let read = registry.run("history.read", &mut session, &json!({"path": "n.md", "id": id})).expect("read");
|
|
assert_eq!(read["text"], "second\n");
|
|
assert!(registry.run("history.read", &mut session, &json!({"path": "n.md", "id": 1})).is_err());
|
|
assert_eq!(registry.run("history.list", &mut session, &json!({"path": "other.md"})).expect("list")["versions"], json!([]));
|
|
}
|