open Hito_app open Support let suite = [ ( "web.overview", [ ( "selecting a routine redirects and records the active routine", `Quick, fun () -> (* POST-redirect-GET: selecting a routine answers 303, and the redirected GET is served. The domain effect is what matters: the trainee now has an active routine. *) let c, repo = client_with_repo () in let _ = register c ~username:"lifter" ~password:"heavyduty1" in let trainee = the_trainee repo ~username:"lifter" in Alcotest.(check bool) "no active routine before selection" true (Option.is_none (Lwt_main.run (Test_repo.active_routine repo trainee.Trainee.id))); let token = Option.get (csrf_token (body (get c "/"))) in let selection = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in Alcotest.(check int) "selection redirects" 303 (status selection); Alcotest.(check bool) "a routine is now active" true (Option.is_some (Lwt_main.run (Test_repo.active_routine repo trainee.Trainee.id))); (* The redirected GET is served. *) Alcotest.(check int) "the redirected GET is 200" 200 (status (get c "/")) ); ( "the home preview shows each exercise's current best weight and reps", `Quick, fun () -> (* Give the Day 1 exercise Laterals a prior effort through an import, which feeds the log but never advances the routine cycle. The next workout stays Day 1, and its preview must show Laterals with the recorded best — the record to beat, per the Heavy Duty progress chart. *) let c, repo = client_with_repo () in let _ = register c ~username:"lifter" ~password:"heavyduty1" in let trainee = the_trainee repo ~username:"lifter" in let token = Option.get (csrf_token (body (get c "/"))) in let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in let header = "title,start_time,end_time,description,exercise_title,superset_id,exercise_notes,set_index,set_type,weight_kg,reps,distance_km,duration_seconds,rpe\r\n" in let source = header ^ "Delts,\"01 Jan 2024, 10:00\",\"01 Jan 2024, 11:00\",,Side \ Raise,,,0,failure,14,10,,,\r\n" in let token = Option.get (csrf_token (body (get c "/profile"))) in let _ = post_multipart c "/profile/import" ~file:(Some ("csv", "workouts.csv", source)) ~fields:[ ("dream.csrf", token); ("utc_offset_seconds", "0") ] in let batch = List.hd (Lwt_main.run (Test_repo.import_batches repo trainee.Trainee.id)) in let bid = Workout_import.batch_id_to_string (Workout_import.batch_identity batch) in let wid = Workout_import.workout_id_to_string (Workout_import.workout_identity (List.hd (Workout_import.batch_workouts batch))) in let review = "/profile/import/" ^ bid in let t = Option.get (csrf_token (body (get c review))) in let _ = post c (Printf.sprintf "/profile/import/%s/workouts/%s/map" bid wid) [ ("dream.csrf", t); ("source_name", "Side Raise"); ("exercise_id", "laterals"); ] in let t = Option.get (csrf_token (body (get c review))) in let _ = post c (Printf.sprintf "/profile/import/%s/workouts/%s/promote" bid wid) [ ("dream.csrf", t) ] in let page = body (get c "/") in (* The cycle has not advanced: the next workout is still Day 1. *) Alcotest.(check bool) "the Day 1 preview lists Laterals" true (Option.is_some (index_from ~needle:"Laterals" page 0)); Alcotest.(check bool) "Laterals shows its best load and reps" true (Option.is_some (index_from ~needle:">14<" page 0) && Option.is_some (index_from ~needle:">10<" page 0)) ); ( "the routine page is served once a routine is selected", `Quick, fun () -> let c = client () in let _ = sign_in_new c in let token = Option.get (csrf_token (body (get c "/"))) in let selection = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in Alcotest.(check int) "routine selected" 303 (status selection); Alcotest.(check int) "routine is available" 200 (status (get c "/routine")); Alcotest.(check int) "routine browser is available" 200 (status (get c "/routines")) ); ( "the routine page states the rest between workouts", `Quick, fun () -> let c = client () in let _ = sign_in_new c in let token = Option.get (csrf_token (body (get c "/"))) in let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in let page = body (get c "/routine") in let has needle = Option.is_some (index_from ~needle page 0) in Alcotest.(check bool) "rest between workouts is stated" true (has "Rest 48 hours"); Alcotest.(check bool) "the last rest leads back to the first workout" true (has "Rest 72 hours, then Day 1") ); ( "selecting an unknown routine is not found and selects nothing", `Quick, fun () -> let c, repo = client_with_repo () in let _ = register c ~username:"lifter" ~password:"heavyduty1" in let trainee = the_trainee repo ~username:"lifter" in let token = Option.get (csrf_token (body (get c "/"))) in let response = post c "/routines/no-such-routine/select" [ ("dream.csrf", token) ] in Alcotest.(check int) "responds 404" 404 (status response); (* A missing routine leaves the trainee with no active routine. *) Alcotest.(check bool) "no routine was selected" true (Option.is_none (Lwt_main.run (Test_repo.active_routine repo trainee.Trainee.id))) ); ] ); ]