diff --git a/crates/onestore-offline/tests/sync.rs b/crates/onestore-offline/tests/sync.rs index 29318e9f84a282db881901fade29ba70c6274043..c6f52ae896486d9f64cf93d52ba334f75e2180b5 100644 --- a/crates/onestore-offline/tests/sync.rs +++ b/crates/onestore-offline/tests/sync.rs @@ -2075,6 +2075,57 @@ fn retired_format_attempts_require_the_complete_durable_effect_without_replay() } } +#[test] +fn retired_text_with_equal_plaintext_but_a_different_surviving_run_remains_uncertain() { + use onestore::TextAttribute; + + let directory = tempfile::tempdir().unwrap(); + let path = directory.path().join("repeated.sqlite"); + let plain = onestore::create_section("repeated.one", "aa", "Fixture").unwrap(); + let (space, object, _) = text(&plain); + let source = PreparedEdit::format(&plain, space, object, 0..1, &[TextAttribute::Bold(true)]) + .unwrap() + .as_bytes() + .to_vec(); + let cache = Replica::create(&path, &source).unwrap(); + let id = cache + .edit_text(&source, space, object, 0..1, "") + .unwrap() + .unwrap(); + let local = cache.snapshot().unwrap(); + let mut server = Server::new(&source); + server.fault = Fault::UnknownAfter; + assert!(cache.sync_once(&mut server).is_err()); + let attempt = cache.status(id).unwrap(); + server.visible = onestore::replace_text(&source, space, object, 1..2, "").unwrap(); + assert_eq!(text(&server.visible).2, text(&local).2); + let bold = |bytes: &[u8]| { + let store = Store::parse(bytes).unwrap(); + let index = RevisionIndex::parse(&store).unwrap(); + let document = Document::parse(&index).unwrap(); + let space = &document.spaces[&space]; + space.revisions[&space.contexts[&ExGuid::default()]] + .text_runs(object) + .unwrap() + .into_iter() + .find(|run| !run.text.is_empty()) + .unwrap() + .format + .bold + }; + assert_eq!(bold(&server.visible), Some(true)); + assert_ne!(bold(&server.visible), bold(&local)); + drop(cache); + let cache = Replica::open(&path).unwrap(); + assert_eq!( + cache.sync_once(&mut server).unwrap(), + attempt.map(|state| (id, state)) + ); + assert_eq!(server.publications, 1); + assert_eq!(server.confirmations, 0); + assert_eq!(cache.snapshot().unwrap(), local); +} + #[test] fn uncertain_formatting_keeps_the_original_attempt_and_never_replays() { use onestore::TextAttribute as A;