| ... | ... | @@ -917,3 +917,81 @@ fn remote_restore_rebases_unsent_work_but_never_replays_an_uncertain_attempt() { |
| 917 | 917 | assert_eq!(cache.status(published).unwrap(), Some(receipt)); |
| 918 | 918 | } |
| 919 | 919 | } |
| 920 | |
| 921 | #[test] |
| 922 | fn restore_conflicts_keep_dependent_work_and_reject_stale_review() { |
| 923 | let directory = tempfile::tempdir().unwrap(); |
| 924 | let path = directory.path().join("cache.sqlite"); |
| 925 | let source = onestore::create_section("restore.one", "Original", "Fixture").unwrap(); |
| 926 | let (space, object, _) = text(&source); |
| 927 | let cache = Replica::create(&path, &source).unwrap(); |
| 928 | let mut server = Server::new(&source); |
| 929 | let published = save(&cache, object, 0..0, "Published ").unwrap(); |
| 930 | let (_, receipt) = cache.sync_once(&mut server).unwrap().unwrap(); |
| 931 | let head = save(&cache, object, 0..9, "Revised").unwrap(); |
| 932 | server.visible.clone_from(&source); |
| 933 | server.durable.clone_from(&source); |
| 934 | let conflict = EditStatus::Conflict(ConflictKind::ContentChanged); |
| 935 | assert_eq!( |
| 936 | cache.sync_once(&mut server).unwrap(), |
| 937 | Some((head, conflict)) |
| 938 | ); |
| 939 | let end = u32::try_from(text(&cache.snapshot().unwrap()).2.encode_utf16().count()).unwrap(); |
| 940 | let dependent = save(&cache, object, end..end, " Later").unwrap(); |
| 941 | assert_ne!(head, dependent); |
| 942 | let local = cache.snapshot().unwrap(); |
| 943 | let pending = cache.pending().unwrap(); |
| 944 | assert_eq!(pending.len(), 2); |
| 945 | cache |
| 946 | .export_recovery(directory.path().join("conflicted.sqlite")) |
| 947 | .unwrap(); |
| 948 | drop(cache); |
| 949 | let cache = Replica::open(&path).unwrap(); |
| 950 | assert_eq!(cache.status(head).unwrap(), Some(conflict)); |
| 951 | assert_eq!(cache.pending().unwrap(), pending); |
| 952 | assert_eq!(cache.snapshot().unwrap(), local); |
| 953 | let reviewed = edited(&source, object, 0..0, "Revised "); |
| 954 | let changed = onestore::replace_text(&source, space, object, 8..8, " Remote").unwrap(); |
| 955 | server.visible.clone_from(&changed); |
| 956 | server.durable.clone_from(&changed); |
| 957 | assert_eq!( |
| 958 | cache.sync_once(&mut server).unwrap(), |
| 959 | Some((head, conflict)) |
| 960 | ); |
| 961 | assert!( |
| 962 | matches!(cache.review_page(head, &local, &source, &reviewed), |
| 963 | Err(Error::Io(error)) if error.kind() == io::ErrorKind::ResourceBusy) |
| 964 | ); |
| 965 | assert_eq!(cache.pending().unwrap(), pending); |
| 966 | assert_eq!(server.publications, 1); |
| 967 | let reviewed = edited(&changed, object, 0..0, "Revised "); |
| 968 | cache |
| 969 | .review_page(head, &local, &changed, &reviewed) |
| 970 | .unwrap(); |
| 971 | assert_eq!(cache.pending().unwrap()[1], pending[1]); |
| 972 | drop(cache); |
| 973 | let cache = Replica::open(&path).unwrap(); |
| 974 | assert!(matches!(cache.sync_once(&mut server).unwrap(), |
| 975 | Some((actual, EditStatus::Published { .. })) if actual == head)); |
| 976 | assert_eq!( |
| 977 | cache.sync_once(&mut server).unwrap(), |
| 978 | Some((dependent, conflict)) |
| 979 | ); |
| 980 | assert_eq!(server.publications, 2); |
| 981 | let dependent_local = cache.snapshot().unwrap(); |
| 982 | let current = cache.remote_snapshot().unwrap(); |
| 983 | let reviewed = edited(&current, object, 16..16, " Later"); |
| 984 | cache |
| 985 | .review_page(dependent, &dependent_local, &current, &reviewed) |
| 986 | .unwrap(); |
| 987 | drop(cache); |
| 988 | let cache = Replica::open(&path).unwrap(); |
| 989 | assert!(matches!(cache.sync_once(&mut server).unwrap(), |
| 990 | Some((actual, EditStatus::Published { .. })) if actual == dependent)); |
| 991 | assert_eq!(text(&server.durable).2, "Revised Original Later Remote"); |
| 992 | assert_eq!(cache.status(published).unwrap(), Some(receipt)); |
| 993 | let archive = notebook::Recovery::open(directory.path().join("conflicted.sqlite")).unwrap(); |
| 994 | assert_eq!(archive.snapshot().unwrap(), local); |
| 995 | assert_eq!(archive.pending().unwrap(), pending); |
| 996 | assert_eq!(archive.status(head).unwrap(), Some(conflict)); |
| 997 | } |