From 58b0c70709fda247c597a2e04588b3ed20596c65 Mon Sep 17 00:00:00 2001 From: slhx agent Date: Thu, 11 Jun 2026 23:39:34 +0200 Subject: [PATCH] test(workout): prove skipped exercise recovery Cover skip-and-undo as a recoverable workout mistake so the product recovery surface is guarded alongside invalid input, edit-last-set, host failures, and replay failures. req: examples/001 req: local/001 req: local/004 --- examples/workout/src/lib.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/examples/workout/src/lib.rs b/examples/workout/src/lib.rs index 4971e66..2d10856 100644 --- a/examples/workout/src/lib.rs +++ b/examples/workout/src/lib.rs @@ -1137,6 +1137,39 @@ mod tests { assert_eq!(app.with_workout(|state| state.plan[0].kg), 24.0); } + #[test] + fn skipped_exercise_recovers_through_undo() { + // req: examples/001 req: local/001 req: local/004 + let app = AppState::demo(); + + let skipped = run(|()| skip_exercise(app.clone()), ()); + assert!(contains_payload_text(&skipped, "skipped Goblet squat")); + assert!(contains_payload_text(&skipped, "Next: Push-up set 1/2")); + assert_eq!( + app.with_workout(|state| ( + state.events.len(), + state.projection.current_exercise, + state.projection.phase.clone(), + )), + (1, 1, WorkoutPhase::Ready) + ); + + let undone = run(|()| undo_last_action(app.clone()), ()); + assert!(contains_payload_text( + &undone, + "Undid: skipped Goblet squat" + )); + assert!(contains_payload_text(&undone, "Next: Goblet squat set 1/3")); + assert_eq!( + app.with_workout(|state| ( + state.events.len(), + state.projection.current_exercise, + state.projection.phase.clone(), + )), + (0, 0, WorkoutPhase::Ready) + ); + } + #[test] fn undo_recovers_last_session_action() { // req: examples/001 req: local/001 req: local/004