Reject stale Scenario actions before shared reveal boundaries
This commit is contained in:
@@ -1386,9 +1386,20 @@ impl App {
|
||||
|| current.visit != captured.visit
|
||||
|| (!matches!(event, behavior::scenario::CanvasEvent::Restored(..))
|
||||
&& current.revision != captured.revision)
|
||||
|| (!matches!(
|
||||
event,
|
||||
behavior::scenario::CanvasEvent::FormShown(..)
|
||||
| behavior::scenario::CanvasEvent::Viewport(..)
|
||||
| behavior::scenario::CanvasEvent::Restored(..)
|
||||
| behavior::scenario::CanvasEvent::Scrolled(..)
|
||||
| behavior::scenario::CanvasEvent::Camera(..)
|
||||
) && current.epoch != captured.epoch)
|
||||
}) {
|
||||
return Task::none();
|
||||
}
|
||||
// Passive layout/form reports retain their existing epoch rules;
|
||||
// camera input uses its separate lifetime below. All other actions
|
||||
// must match the exact context before shared reveal reconciliation.
|
||||
if let behavior::scenario::CanvasEvent::Camera(_, lifetime, _) = event
|
||||
&& *lifetime != self.camera_epoch
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ fn exercise(via_guide: bool) {
|
||||
}
|
||||
assert_destination(&app, target);
|
||||
let camera = app.camera_boundary();
|
||||
// The prior saved canvas cannot regain focus after either owner route.
|
||||
// The prior saved canvas cannot open its outline after either owner route.
|
||||
let _ = app.update(Message::ScenarioCanvas(CanvasEvent::Shelf(
|
||||
held,
|
||||
crate::behavior::scenario::Shelf::Selection,
|
||||
|
||||
@@ -50,6 +50,7 @@ fn stale_text_and_scenario_messages_do_not_retire_a_new_saved_spacing_gesture()
|
||||
context,
|
||||
Size::new(900., 600.),
|
||||
)));
|
||||
let context = app.scenario_context().unwrap();
|
||||
let (event, start, _) = begin(&mut app, Target::Lane(lane));
|
||||
move_to(&mut app, event, start + Vector::new(24., 0.));
|
||||
let accepted = app.document.snapshot();
|
||||
@@ -314,6 +315,63 @@ fn stale_finish_cannot_remove_new_same_view_deferred_reveal() {
|
||||
assert!(!app.document.can_undo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stale_active_actions_cannot_remove_new_same_visit_deferred_reveal() {
|
||||
let (mut app, lane, message) = setup();
|
||||
let old = app.scenario_context().unwrap();
|
||||
let behavior::scenario_layout::Representation::Saved { diagram } = old.representation else {
|
||||
unreachable!()
|
||||
};
|
||||
let accepted = app.document.snapshot();
|
||||
let source = app.source_workspace.bundle();
|
||||
let _ = app.update(Message::RevealInDiagram(diagram, message));
|
||||
let current = app.scenario_context().unwrap();
|
||||
assert_eq!(current.visit, old.visit);
|
||||
assert_eq!(current.representation, old.representation);
|
||||
assert_eq!(current.revision, old.revision);
|
||||
assert_ne!(current.epoch, old.epoch);
|
||||
let pending = app.pending_diagram_reveal.clone();
|
||||
assert!(pending.is_some());
|
||||
let focus = app.diagram_navigation_focus.as_ref().unwrap();
|
||||
let focus = (focus.context, focus.usage.clone(), focus.selected);
|
||||
let camera = app.camera_boundary();
|
||||
for event in [
|
||||
CanvasEvent::Representation(old, old.representation),
|
||||
CanvasEvent::Shelf(old, behavior::scenario::Shelf::Selection),
|
||||
CanvasEvent::Select(old, lane),
|
||||
CanvasEvent::Zoom(old, Some(1.)),
|
||||
] {
|
||||
let _ = app.update(Message::ScenarioCanvas(event));
|
||||
assert_eq!(app.scenario_context(), Some(current));
|
||||
assert_eq!(app.pending_diagram_reveal, pending);
|
||||
assert_eq!(app.pending_scenario_reveal_visit, Some(current.visit));
|
||||
let actual = app.diagram_navigation_focus.as_ref().unwrap();
|
||||
assert_eq!(
|
||||
(actual.context, actual.usage.clone(), actual.selected),
|
||||
focus
|
||||
);
|
||||
assert!(app.camera_boundary() == camera);
|
||||
assert_eq!(app.selected, message);
|
||||
assert_eq!(app.document.bundle(), &accepted.bundle);
|
||||
assert_eq!(app.project(), &accepted.decoded.project);
|
||||
assert_eq!(app.source_workspace.bundle(), source);
|
||||
assert!(!app.document.can_undo() && !app.document.can_redo());
|
||||
}
|
||||
let _ = app.update(Message::ScenarioCanvas(CanvasEvent::Viewport(
|
||||
current,
|
||||
Size::new(800., 500.),
|
||||
)));
|
||||
assert!(app.pending_diagram_reveal.is_none());
|
||||
assert!(app.pending_scenario_reveal_visit.is_none());
|
||||
assert!(
|
||||
app.diagram_focus(crate::diagram_usage::Surface::Saved(diagram))
|
||||
.is_some()
|
||||
);
|
||||
assert_eq!(app.selected, message);
|
||||
assert_eq!(app.document.bundle(), &accepted.bundle);
|
||||
assert!(!app.document.can_undo() && !app.document.can_redo());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modal_open_cancels_preview_and_captured_begin_stays_retired_after_close() {
|
||||
let (mut app, lane, _) = setup();
|
||||
|
||||
Reference in New Issue
Block a user