1use notebook::session::{Change, Notebook};
2use std::io::Write;
3
4/// One client watches a notebook while another changes it on disk; changes follow file
5/// identity, and an unreachable notebook keeps the last catalog.
6#[test]
7fn external_structure_changes_are_reported_by_identity() {
8 let temporary = tempfile::tempdir().unwrap();
9 let root = temporary.path().join("notebook");
10 std::fs::create_dir(&root).unwrap();
11 let first = onestore::create_section("First.one", "First page", "Author").unwrap();
12 std::fs::File::create_new(root.join("First.one"))
13 .unwrap()
14 .write_all(&first)
15 .unwrap();
16 let first_id = onestore::Store::parse(&first).unwrap().header.file_id;
17 std::fs::write(
18 root.join("Open Notebook.onetoc2"),
19 onestore::create_table_of_contents("Open Notebook.onetoc2", &[("First.one", first_id)])
20 .unwrap(),
21 )
22 .unwrap();
23 let mut watcher = Notebook::open(&root, temporary.path().join("watcher")).unwrap();
24 let mut other = Notebook::open(&root, temporary.path().join("other")).unwrap();
25 assert_eq!(watcher.refresh().unwrap(), []);
26
27 other
28 .create_section(
29 "",
30 "Second",
31 &onestore::PageCreation::new(None, Some(""), "Author").unwrap(),
32 )
33 .unwrap();
34 other.create_group("", "Group").unwrap();
35 other
36 .create_section(
37 "Group",
38 "Inner",
39 &onestore::PageCreation::new(None, Some(""), "Author").unwrap(),
40 )
41 .unwrap();
42 assert_eq!(
43 watcher.refresh().unwrap(),
44 [
45 Change::Added("Second.one".into()),
46 Change::Added("Group".into()),
47 Change::Added("Group/Inner.one".into()),
48 ]
49 );
50
51 other.rename("Second.one", "Renamed").unwrap();
52 assert_eq!(
53 watcher.refresh().unwrap(),
54 [Change::Moved {
55 from: "Second.one".into(),
56 to: "Renamed.one".into()
57 }]
58 );
59
60 other.reorder("", &["Renamed.one", "First.one"]).unwrap();
61 assert_eq!(watcher.refresh().unwrap(), [Change::Reordered("".into())]);
62
63 other.delete("First.one").unwrap();
64 assert_eq!(
65 watcher.refresh().unwrap(),
66 [
67 Change::Moved {
68 from: "First.one".into(),
69 to: "OneNote_RecycleBin/First.one".into()
70 },
71 Change::Added("OneNote_RecycleBin".into()),
72 ]
73 );
74 std::fs::remove_dir_all(root.join("OneNote_RecycleBin")).unwrap();
75 assert_eq!(
76 watcher.refresh().unwrap(),
77 [
78 Change::Removed("OneNote_RecycleBin".into()),
79 Change::Removed("OneNote_RecycleBin/First.one".into()),
80 ]
81 );
82
83 let away = temporary.path().join("away");
84 std::fs::rename(&root, &away).unwrap();
85 assert!(watcher.refresh().is_err());
86 assert_eq!(watcher.catalog().sections.len(), 1);
87 std::fs::rename(&away, &root).unwrap();
88 assert_eq!(watcher.refresh().unwrap(), []);
89 assert_eq!(watcher.refresh().unwrap(), []);
90}