//! `Session::refresh_paths`: files rewritten behind the session's back (git restore, other //! tools) are re-read; deleted ones are forgotten; dirty buffers keep their text. mod common; use common::temp_vault; use notescraft_engine::Session; #[test] fn rewritten_and_deleted_files_are_reconciled() { let vault = temp_vault("refresh"); assert!(std::fs::write(vault.path().join("a.md"), "# A\n[[b]]\n").is_ok()); assert!(std::fs::write(vault.path().join("b.md"), "# B\n").is_ok()); let Ok(mut session) = Session::open(vault.path()) else { return }; assert!(session.index().note("a.md").is_some()); assert!(std::fs::write(vault.path().join("a.md"), "# A2\nnew words here\n").is_ok()); assert!(std::fs::remove_file(vault.path().join("b.md")).is_ok()); assert!(session.refresh_paths(&["a.md".to_owned(), "b.md".to_owned()]).is_ok()); assert_eq!(session.search("words", 10).map(|hits| hits.len()).ok(), Some(1)); assert!(session.index().note("b.md").is_none(), "removed notes leave the index"); } #[test] fn dirty_buffers_keep_their_text_and_record_a_conflict() { let vault = temp_vault("refresh-dirty"); assert!(std::fs::write(vault.path().join("a.md"), "# A\n").is_ok()); let Ok(mut session) = Session::open(vault.path()) else { return }; assert!(session.open_buffer("a.md").is_ok()); assert!(session.buffer_mut("a.md").is_ok_and(|b| b.edit(0..0, "unsaved ").is_ok())); assert!(std::fs::write(vault.path().join("a.md"), "disk change\n").is_ok()); assert!(session.refresh_paths(&["a.md".to_owned()]).is_ok()); assert_eq!(session.buffer("a.md").map(notescraft_engine::Buffer::text), Some("unsaved # A\n")); assert!(session.conflicts().iter().any(|p| p == "a.md")); } #[test] fn hostile_paths_are_errors_not_panics() { let vault = temp_vault("refresh-hostile"); let Ok(mut session) = Session::open(vault.path()) else { return }; for path in ["../x.md", "/etc/passwd", "", ".obsidian/x", "a\0b"] { let _ = session.refresh_paths(&[path.to_owned()]); } }