1
-
Removed:
open Hito_app
2
-
Removed:
open Support
3
-
Removed:
4
-
Removed:
let suite =
5
-
Removed:
[
6
-
Removed:
( "web.flow",
7
-
Removed:
[
8
-
Removed:
( "the logbook shows the action button group and an empty table state",
9
-
Removed:
`Quick,
10
-
Removed:
fun () ->
11
-
Removed:
let c = client () in
12
-
Removed:
let _ = sign_in_new c in
13
-
Removed:
let page = body (get c "/logbook") in
14
-
Removed:
Alcotest.(check bool)
15
-
Removed:
"Log feedback action" true
16
-
Removed:
(Option.is_some (index_from ~needle:"Log feedback" page 0));
17
-
Removed:
Alcotest.(check bool)
18
-
Removed:
"Edit logbook action" true
19
-
Removed:
(Option.is_some (index_from ~needle:"Edit logbook" page 0));
20
-
Removed:
Alcotest.(check bool)
21
-
Removed:
"the button group is present" true
22
-
Removed:
(Option.is_some
23
-
Removed:
(index_from ~needle:"class=\"button-group\"" page 0));
24
-
Removed:
Alcotest.(check bool)
25
-
Removed:
"empty state when nothing is logged" true
26
-
Removed:
(Option.is_some (index_from ~needle:"Nothing logged yet." page 0))
27
-
Removed:
);
28
-
Removed:
( "a finished workout appears in the logbook table with a progress \
29
-
Removed:
column",
30
-
Removed:
`Quick,
31
-
Removed:
fun () ->
32
-
Removed:
let c = client () in
33
-
Removed:
let _ = sign_in_new c in
34
-
Removed:
let _ = start_day_one c in
35
-
Removed:
record_all_day_one_slots c;
36
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
37
-
Removed:
let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
38
-
Removed:
let page = body (get c "/logbook") in
39
-
Removed:
Alcotest.(check bool)
40
-
Removed:
"the logbook table is present" true
41
-
Removed:
(Option.is_some
42
-
Removed:
(index_from ~needle:"class=\"logbook-table\"" page 0));
43
-
Removed:
Alcotest.(check bool)
44
-
Removed:
"the progressed-exercises column header" true
45
-
Removed:
(Option.is_some
46
-
Removed:
(index_from ~needle:"Exercises progressed" page 0)) );
47
-
Removed:
( "selecting a routine redirects and records the active routine",
48
-
Removed:
`Quick,
49
-
Removed:
fun () ->
50
-
Removed:
(* POST-redirect-GET: selecting a routine answers 303, and the
51
-
Removed:
redirected GET is served. The domain effect is what matters: the
52
-
Removed:
trainee now has an active routine. *)
53
-
Removed:
let c, repo = client_with_repo () in
54
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
55
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
56
-
Removed:
Alcotest.(check bool)
57
-
Removed:
"no active routine before selection" true
58
-
Removed:
(Option.is_none
59
-
Removed:
(Lwt_main.run
60
-
Removed:
(Memory_repo.active_routine repo trainee.Trainee.id)));
61
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
62
-
Removed:
let selection =
63
-
Removed:
post c "/routines/ideal/select" [ ("dream.csrf", token) ]
64
-
Removed:
in
65
-
Removed:
Alcotest.(check int) "selection redirects" 303 (status selection);
66
-
Removed:
Alcotest.(check bool)
67
-
Removed:
"a routine is now active" true
68
-
Removed:
(Option.is_some
69
-
Removed:
(Lwt_main.run
70
-
Removed:
(Memory_repo.active_routine repo trainee.Trainee.id)));
71
-
Removed:
(* The redirected GET is served. *)
72
-
Removed:
Alcotest.(check int)
73
-
Removed:
"the redirected GET is 200" 200
74
-
Removed:
(status (get c "/")) );
75
-
Removed:
( "a signed-in trainee selects a routine and begins a workout",
76
-
Removed:
`Quick,
77
-
Removed:
fun () ->
78
-
Removed:
let c, repo = client_with_repo () in
79
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
80
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
81
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
82
-
Removed:
let selection =
83
-
Removed:
post c "/routines/ideal/select" [ ("dream.csrf", token) ]
84
-
Removed:
in
85
-
Removed:
Alcotest.(check int) "routine selected" 303 (status selection);
86
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
87
-
Removed:
let started =
88
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
89
-
Removed:
in
90
-
Removed:
Alcotest.(check int) "workout started" 303 (status started);
91
-
Removed:
(* The workout is now in progress in the domain, and its view is
92
-
Removed:
served. *)
93
-
Removed:
Alcotest.(check bool)
94
-
Removed:
"a workout is in progress" true
95
-
Removed:
(Option.is_some
96
-
Removed:
(Lwt_main.run
97
-
Removed:
(Memory_repo.in_progress repo trainee.Trainee.id)));
98
-
Removed:
Alcotest.(check int)
99
-
Removed:
"the workout view is served" 200
100
-
Removed:
(status (get c "/workout"));
101
-
Removed:
(* The static workout client asset is served. *)
102
-
Removed:
let asset = get c "/assets/workout-client.js" in
103
-
Removed:
Alcotest.(check int) "serves the workout client" 200 (status asset)
104
-
Removed:
);
105
-
Removed:
( "the routine page is served once a routine is selected",
106
-
Removed:
`Quick,
107
-
Removed:
fun () ->
108
-
Removed:
let c = client () in
109
-
Removed:
let _ = sign_in_new c in
110
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
111
-
Removed:
let selection =
112
-
Removed:
post c "/routines/ideal/select" [ ("dream.csrf", token) ]
113
-
Removed:
in
114
-
Removed:
Alcotest.(check int) "routine selected" 303 (status selection);
115
-
Removed:
Alcotest.(check int)
116
-
Removed:
"routine page served" 200
117
-
Removed:
(status (get c "/routine")) );
118
-
Removed:
( "a recorded slot can be corrected, replacing it rather than adding \
119
-
Removed:
volume",
120
-
Removed:
`Quick,
121
-
Removed:
fun () ->
122
-
Removed:
let c, repo = client_with_repo () in
123
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
124
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
125
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
126
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
127
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
128
-
Removed:
let _ =
129
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
130
-
Removed:
in
131
-
Removed:
(* Slot 1 is the single Laterals set. Record it, then correct it —
132
-
Removed:
one slot at a time, addressed by [?slot=]. *)
133
-
Removed:
let token =
134
-
Removed:
Option.get (csrf_token (body (get c "/workout?slot=1")))
135
-
Removed:
in
136
-
Removed:
let recorded =
137
-
Removed:
post c "/workout/slots/1"
138
-
Removed:
[
139
-
Removed:
("dream.csrf", token);
140
-
Removed:
("load", "12");
141
-
Removed:
("reps", "8");
142
-
Removed:
("extension", "");
143
-
Removed:
]
144
-
Removed:
in
145
-
Removed:
Alcotest.(check int) "recorded" 303 (status recorded);
146
-
Removed:
let filled_after_record () =
147
-
Removed:
match
148
-
Removed:
Lwt_main.run (Memory_repo.in_progress repo trainee.Trainee.id)
149
-
Removed:
with
150
-
Removed:
| Some w -> Evidence.Workout.filled_slots w
151
-
Removed:
| None -> Alcotest.failf "expected a workout in progress"
152
-
Removed:
in
153
-
Removed:
Alcotest.(check int) "one filled slot" 1 (filled_after_record ());
154
-
Removed:
let token =
155
-
Removed:
Option.get (csrf_token (body (get c "/workout?slot=1")))
156
-
Removed:
in
157
-
Removed:
let corrected =
158
-
Removed:
post c "/workout/slots/1/edit"
159
-
Removed:
[
160
-
Removed:
("dream.csrf", token);
161
-
Removed:
("load", "16");
162
-
Removed:
("reps", "6");
163
-
Removed:
("extension", "");
164
-
Removed:
]
165
-
Removed:
in
166
-
Removed:
Alcotest.(check int) "corrected" 303 (status corrected);
167
-
Removed:
(* A correction replaces the slot; it does not add volume. *)
168
-
Removed:
Alcotest.(check int)
169
-
Removed:
"still one filled slot, not two" 1 (filled_after_record ()) );
170
-
Removed:
( "a saved workout's slot can be corrected from the logbook view",
171
-
Removed:
`Quick,
172
-
Removed:
fun () ->
173
-
Removed:
let c, repo = client_with_repo () in
174
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
175
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
176
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
177
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
178
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
179
-
Removed:
let _ =
180
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
181
-
Removed:
in
182
-
Removed:
let token =
183
-
Removed:
Option.get (csrf_token (body (get c "/workout?slot=1")))
184
-
Removed:
in
185
-
Removed:
let _ =
186
-
Removed:
post c "/workout/slots/1"
187
-
Removed:
[
188
-
Removed:
("dream.csrf", token);
189
-
Removed:
("load", "12");
190
-
Removed:
("reps", "8");
191
-
Removed:
("extension", "");
192
-
Removed:
]
193
-
Removed:
in
194
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
195
-
Removed:
let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
196
-
Removed:
(* The one saved workout is w1 for this trainee. Correct its slot
197
-
Removed:
through the logbook path, then confirm the store still has one
198
-
Removed:
filled slot — a correction, not extra volume. *)
199
-
Removed:
let record_page = body (get c "/logbook/w1?slot=1") in
200
-
Removed:
let token = Option.get (csrf_token record_page) in
201
-
Removed:
let corrected =
202
-
Removed:
post c "/logbook/w1/slots/1/edit"
203
-
Removed:
[
204
-
Removed:
("dream.csrf", token);
205
-
Removed:
("load", "20");
206
-
Removed:
("reps", "7");
207
-
Removed:
("extension", "");
208
-
Removed:
]
209
-
Removed:
in
210
-
Removed:
Alcotest.(check int) "corrected" 303 (status corrected);
211
-
Removed:
let record =
212
-
Removed:
Lwt_main.run
213
-
Removed:
(Memory_repo.find repo trainee.Trainee.id
214
-
Removed:
(Repository.workout_id "w1"))
215
-
Removed:
in
216
-
Removed:
Alcotest.(check int)
217
-
Removed:
"still one filled slot" 1
218
-
Removed:
(match record with
219
-
Removed:
| Some r -> Evidence.Workout.filled_slots r.Repository.workout
220
-
Removed:
| None -> Alcotest.failf "expected the saved workout w1") );
221
-
Removed:
( "an invalid workout field is rejected and records nothing",
222
-
Removed:
`Quick,
223
-
Removed:
fun () ->
224
-
Removed:
let c, repo = client_with_repo () in
225
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
226
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
227
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
228
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
229
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
230
-
Removed:
let _ =
231
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
232
-
Removed:
in
233
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
234
-
Removed:
let invalid =
235
-
Removed:
post c "/workout/slots/0"
236
-
Removed:
[
237
-
Removed:
("dream.csrf", token);
238
-
Removed:
("iso_load", "not-a-number");
239
-
Removed:
("iso_reps", "8");
240
-
Removed:
("comp_load", "40");
241
-
Removed:
("comp_reps", "6");
242
-
Removed:
("extension", "");
243
-
Removed:
]
244
-
Removed:
in
245
-
Removed:
Alcotest.(check int) "invalid field redirects" 303 (status invalid);
246
-
Removed:
(* The bad input recorded no slot. *)
247
-
Removed:
Alcotest.(check int)
248
-
Removed:
"no slot was filled" 0
249
-
Removed:
(match
250
-
Removed:
Lwt_main.run (Memory_repo.in_progress repo trainee.Trainee.id)
251
-
Removed:
with
252
-
Removed:
| Some w -> Evidence.Workout.filled_slots w
253
-
Removed:
| None -> Alcotest.failf "expected a workout in progress") );
254
-
Removed:
( "recording a slot advances the count of filled slots",
255
-
Removed:
`Quick,
256
-
Removed:
fun () ->
257
-
Removed:
let c, repo = client_with_repo () in
258
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
259
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
260
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
261
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
262
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
263
-
Removed:
let _ =
264
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
265
-
Removed:
in
266
-
Removed:
let filled () =
267
-
Removed:
match
268
-
Removed:
Lwt_main.run (Memory_repo.in_progress repo trainee.Trainee.id)
269
-
Removed:
with
270
-
Removed:
| Some w -> Evidence.Workout.filled_slots w
271
-
Removed:
| None -> Alcotest.failf "expected a workout in progress"
272
-
Removed:
in
273
-
Removed:
Alcotest.(check int) "nothing recorded yet" 0 (filled ());
274
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
275
-
Removed:
let recorded =
276
-
Removed:
post c "/workout/slots/0"
277
-
Removed:
[
278
-
Removed:
("dream.csrf", token);
279
-
Removed:
("iso_load", "10");
280
-
Removed:
("iso_reps", "8");
281
-
Removed:
("comp_load", "40");
282
-
Removed:
("comp_reps", "6");
283
-
Removed:
("extension", "");
284
-
Removed:
]
285
-
Removed:
in
286
-
Removed:
Alcotest.(check int) "recorded slot 0" 303 (status recorded);
287
-
Removed:
Alcotest.(check int) "one slot filled" 1 (filled ()) );
288
-
Removed:
( "signing out returns the trainee to the sign-in page",
289
-
Removed:
`Quick,
290
-
Removed:
fun () ->
291
-
Removed:
let c = client () in
292
-
Removed:
let _ = sign_in_new c in
293
-
Removed:
let page = body (get c "/") in
294
-
Removed:
let token = Option.get (csrf_token page) in
295
-
Removed:
let out = post c "/logout" [ ("dream.csrf", token) ] in
296
-
Removed:
Alcotest.(check int) "logout redirect" 303 (status out);
297
-
Removed:
let after = get c "/" in
298
-
Removed:
Alcotest.(check int) "overview now redirects" 303 (status after);
299
-
Removed:
Alcotest.(check string) "to /login" "/login" (location after) );
300
-
Removed:
( "cancelling a workout without a CSRF token leaves it in progress",
301
-
Removed:
`Quick,
302
-
Removed:
fun () ->
303
-
Removed:
let c, repo = client_with_repo () in
304
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
305
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
306
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
307
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
308
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
309
-
Removed:
let _ =
310
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
311
-
Removed:
in
312
-
Removed:
let response = post c "/workout/cancel" [ (* no dream.csrf *) ] in
313
-
Removed:
(* Cancelling always navigates away to Home. A forged or missing
314
-
Removed:
token skips the discard, so the workout remains in progress. *)
315
-
Removed:
Alcotest.(check int)
316
-
Removed:
"navigates away without an error page" 303 (status response);
317
-
Removed:
Alcotest.(check bool)
318
-
Removed:
"returns Home" true
319
-
Removed:
(List.mem "/" (Dream.headers response "Location"));
320
-
Removed:
Alcotest.(check bool)
321
-
Removed:
"workout still in progress" true
322
-
Removed:
(Option.is_some
323
-
Removed:
(Lwt_main.run
324
-
Removed:
(Memory_repo.in_progress repo trainee.Trainee.id))) );
325
-
Removed:
( "cancelling after recording a set discards the workout entirely",
326
-
Removed:
`Quick,
327
-
Removed:
fun () ->
328
-
Removed:
let c, repo = client_with_repo () in
329
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
330
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
331
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
332
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
333
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
334
-
Removed:
let _ =
335
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
336
-
Removed:
in
337
-
Removed:
let token =
338
-
Removed:
Option.get (csrf_token (body (get c "/workout?slot=1")))
339
-
Removed:
in
340
-
Removed:
let recorded =
341
-
Removed:
post c "/workout/slots/1"
342
-
Removed:
[
343
-
Removed:
("dream.csrf", token);
344
-
Removed:
("load", "12");
345
-
Removed:
("reps", "8");
346
-
Removed:
("extension", "");
347
-
Removed:
]
348
-
Removed:
in
349
-
Removed:
Alcotest.(check int) "recorded a set" 303 (status recorded);
350
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
351
-
Removed:
let cancelled =
352
-
Removed:
post c "/workout/cancel" [ ("dream.csrf", token) ]
353
-
Removed:
in
354
-
Removed:
Alcotest.(check int) "cancel returns Home" 303 (status cancelled);
355
-
Removed:
Alcotest.(check bool)
356
-
Removed:
"returns Home, not the logbook" true
357
-
Removed:
(List.mem "/" (Dream.headers cancelled "Location"));
358
-
Removed:
(* No current workout, and no record: an abandoned session is not
359
-
Removed:
evidence. *)
360
-
Removed:
Alcotest.(check bool)
361
-
Removed:
"no workout in progress" true
362
-
Removed:
(Option.is_none
363
-
Removed:
(Lwt_main.run
364
-
Removed:
(Memory_repo.in_progress repo trainee.Trainee.id)));
365
-
Removed:
Alcotest.(check int)
366
-
Removed:
"history is empty" 0
367
-
Removed:
(List.length
368
-
Removed:
(Lwt_main.run (Memory_repo.history repo trainee.Trainee.id)));
369
-
Removed:
Alcotest.(check int)
370
-
Removed:
"the discarded workout has no record" 404
371
-
Removed:
(status (get c "/logbook/w1")) );
372
-
Removed:
( "sequential feedback stores only answered factors, never skipped ones",
373
-
Removed:
`Quick,
374
-
Removed:
fun () ->
375
-
Removed:
let c, repo = client_with_repo () in
376
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
377
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
378
-
Removed:
let _ = get c "/logbook?feedback=start" in
379
-
Removed:
let step_action step action extra =
380
-
Removed:
let token = Option.get (csrf_token (body (get c "/logbook"))) in
381
-
Removed:
post c "/feedback"
382
-
Removed:
(("dream.csrf", token)
383
-
Removed:
:: ("step", string_of_int step)
384
-
Removed:
:: ("action", action) :: extra)
385
-
Removed:
in
386
-
Removed:
let first = step_action 0 "next" [ ("choice", "better") ] in
387
-
Removed:
Alcotest.(check int) "first factor redirects" 303 (status first);
388
-
Removed:
let _ = step_action 1 "skip" [] in
389
-
Removed:
let saved = step_action 2 "save" [] in
390
-
Removed:
Alcotest.(check int) "final feedback redirects" 303 (status saved);
391
-
Removed:
let reports =
392
-
Removed:
Lwt_main.run (Memory_repo.feedback repo trainee.Trainee.id)
393
-
Removed:
in
394
-
Removed:
Alcotest.(check int)
395
-
Removed:
"one feedback report stored" 1 (List.length reports);
396
-
Removed:
let signal_list = Feedback.signals (List.hd reports) in
397
-
Removed:
Alcotest.(check (list bool))
398
-
Removed:
"only motivation stored" [ true ]
399
-
Removed:
(List.map
400
-
Removed:
(function
401
-
Removed:
| Feedback.Motivation Feedback.Better_than_usual -> true
402
-
Removed:
| _ -> false)
403
-
Removed:
signal_list) );
404
-
Removed:
( "skipping the entire feedback flow records nothing",
405
-
Removed:
`Quick,
406
-
Removed:
fun () ->
407
-
Removed:
let c, repo = client_with_repo () in
408
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
409
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
410
-
Removed:
let start = body (get c "/logbook?feedback=start") in
411
-
Removed:
let token = Option.get (csrf_token start) in
412
-
Removed:
let skipped = post c "/feedback/cancel" [ ("dream.csrf", token) ] in
413
-
Removed:
Alcotest.(check int) "full-flow skip redirects" 303 (status skipped);
414
-
Removed:
Alcotest.(check int)
415
-
Removed:
"no feedback report was stored" 0
416
-
Removed:
(List.length
417
-
Removed:
(Lwt_main.run (Memory_repo.feedback repo trainee.Trainee.id)))
418
-
Removed:
);
419
-
Removed:
( "back keeps an earlier answer, which still persists on save",
420
-
Removed:
`Quick,
421
-
Removed:
fun () ->
422
-
Removed:
let c, repo = client_with_repo () in
423
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
424
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
425
-
Removed:
let _ = get c "/logbook?feedback=start" in
426
-
Removed:
let step_action step action extra =
427
-
Removed:
let token = Option.get (csrf_token (body (get c "/logbook"))) in
428
-
Removed:
post c "/feedback"
429
-
Removed:
(("dream.csrf", token)
430
-
Removed:
:: ("step", string_of_int step)
431
-
Removed:
:: ("action", action) :: extra)
432
-
Removed:
in
433
-
Removed:
(* Answer motivation, move to difficulty, return, then skip
434
-
Removed:
motivation and difficulty before saving. The earlier motivation
435
-
Removed:
answer remains in the flow. *)
436
-
Removed:
let _ = step_action 0 "next" [ ("choice", "better") ] in
437
-
Removed:
let back = step_action 1 "back" [] in
438
-
Removed:
Alcotest.(check int) "back redirects" 303 (status back);
439
-
Removed:
let _ = step_action 0 "skip" [] in
440
-
Removed:
let _ = step_action 1 "skip" [] in
441
-
Removed:
let _ = step_action 2 "save" [] in
442
-
Removed:
let reports =
443
-
Removed:
Lwt_main.run (Memory_repo.feedback repo trainee.Trainee.id)
444
-
Removed:
in
445
-
Removed:
Alcotest.(check int) "one report stored" 1 (List.length reports);
446
-
Removed:
let signals = Feedback.signals (List.hd reports) in
447
-
Removed:
Alcotest.(check bool)
448
-
Removed:
"the pre-back motivation answer persists" true
449
-
Removed:
(List.exists
450
-
Removed:
(function
451
-
Removed:
| Feedback.Motivation Feedback.Better_than_usual -> true
452
-
Removed:
| _ -> false)
453
-
Removed:
signals) );
454
-
Removed:
( "closing the feedback modal discards the flow",
455
-
Removed:
`Quick,
456
-
Removed:
fun () ->
457
-
Removed:
let c, repo = client_with_repo () in
458
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
459
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
460
-
Removed:
let start = body (get c "/logbook?feedback=start") in
461
-
Removed:
let token = Option.get (csrf_token start) in
462
-
Removed:
let _ =
463
-
Removed:
post c "/feedback"
464
-
Removed:
[
465
-
Removed:
("dream.csrf", token);
466
-
Removed:
("step", "0");
467
-
Removed:
("action", "next");
468
-
Removed:
("choice", "better");
469
-
Removed:
]
470
-
Removed:
in
471
-
Removed:
let appetite = body (get c "/logbook") in
472
-
Removed:
let token = Option.get (csrf_token appetite) in
473
-
Removed:
let closed = post c "/feedback/cancel" [ ("dream.csrf", token) ] in
474
-
Removed:
Alcotest.(check int) "close redirects" 303 (status closed);
475
-
Removed:
(* A discarded flow stores nothing. *)
476
-
Removed:
Alcotest.(check int)
477
-
Removed:
"no feedback report stored" 0
478
-
Removed:
(List.length
479
-
Removed:
(Lwt_main.run (Memory_repo.feedback repo trainee.Trainee.id)))
480
-
Removed:
);
481
-
Removed:
( "finishing a workout redirects to the logbook feedback prompt",
482
-
Removed:
`Quick,
483
-
Removed:
fun () ->
484
-
Removed:
let c, repo = client_with_repo () in
485
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
486
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
487
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
488
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
489
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
490
-
Removed:
let _ =
491
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
492
-
Removed:
in
493
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
494
-
Removed:
let finished = post c "/workout/finish" [ ("dream.csrf", token) ] in
495
-
Removed:
Alcotest.(check int) "finish redirects" 303 (status finished);
496
-
Removed:
Alcotest.(check bool)
497
-
Removed:
"redirects to the logbook with a feedback prompt" true
498
-
Removed:
(List.mem "/logbook?prompt=feedback"
499
-
Removed:
(Dream.headers finished "Location"));
500
-
Removed:
(* The workout is now in history and no longer in progress. *)
501
-
Removed:
Alcotest.(check int)
502
-
Removed:
"one workout in history" 1
503
-
Removed:
(List.length
504
-
Removed:
(Lwt_main.run (Memory_repo.history repo trainee.Trainee.id)));
505
-
Removed:
Alcotest.(check bool)
506
-
Removed:
"nothing in progress" true
507
-
Removed:
(Option.is_none
508
-
Removed:
(Lwt_main.run
509
-
Removed:
(Memory_repo.in_progress repo trainee.Trainee.id))) );
510
-
Removed:
( "beginning before recovery is refused without an override",
511
-
Removed:
`Quick,
512
-
Removed:
fun () ->
513
-
Removed:
let c, repo = client_with_repo () in
514
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
515
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
516
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
517
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
518
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
519
-
Removed:
let _ =
520
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
521
-
Removed:
in
522
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
523
-
Removed:
let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
524
-
Removed:
(* Recovery has not elapsed. Beginning the next workout without an
525
-
Removed:
override is bounced back to Home and starts nothing. *)
526
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
527
-
Removed:
let refused =
528
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
529
-
Removed:
in
530
-
Removed:
Alcotest.(check int) "early begin bounced" 303 (status refused);
531
-
Removed:
Alcotest.(check bool)
532
-
Removed:
"returns Home, not the workout" true
533
-
Removed:
(List.mem "/" (Dream.headers refused "Location"));
534
-
Removed:
Alcotest.(check bool)
535
-
Removed:
"no new workout in progress" true
536
-
Removed:
(Option.is_none
537
-
Removed:
(Lwt_main.run
538
-
Removed:
(Memory_repo.in_progress repo trainee.Trainee.id))) );
539
-
Removed:
( "overriding recovery begins the next workout on an override basis",
540
-
Removed:
`Quick,
541
-
Removed:
fun () ->
542
-
Removed:
let c, repo = client_with_repo () in
543
-
Removed:
let _ = register c ~username:"lifter" ~password:"heavyduty1" in
544
-
Removed:
let trainee = the_trainee repo ~username:"lifter" in
545
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
546
-
Removed:
let _ = post c "/routines/ideal/select" [ ("dream.csrf", token) ] in
547
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
548
-
Removed:
let _ =
549
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "false") ]
550
-
Removed:
in
551
-
Removed:
let token = Option.get (csrf_token (body (get c "/workout"))) in
552
-
Removed:
let _ = post c "/workout/finish" [ ("dream.csrf", token) ] in
553
-
Removed:
(* Recovery has not elapsed, so the next workout is begun under an
554
-
Removed:
explicit override. The deviation is recorded on the workout's
555
-
Removed:
clearance basis, never silent. *)
556
-
Removed:
let token = Option.get (csrf_token (body (get c "/"))) in
557
-
Removed:
let began =
558
-
Removed:
post c "/workout" [ ("dream.csrf", token); ("override", "true") ]
559
-
Removed:
in
560
-
Removed:
Alcotest.(check int) "override begin succeeds" 303 (status began);
561
-
Removed:
let basis =
562
-
Removed:
match
563
-
Removed:
Lwt_main.run (Memory_repo.in_progress repo trainee.Trainee.id)
564
-
Removed:
with
565
-
Removed:
| Some w -> Recovery.basis (Evidence.Workout.clearance w)
566
-
Removed:
| None -> Alcotest.failf "expected a workout in progress"
567
-
Removed:
in
568
-
Removed:
Alcotest.(check bool)
569
-
Removed:
"the workout carries an override basis" true
570
-
Removed:
(match basis with Recovery.Overridden _ -> true | _ -> false) );
571
-
Removed:
] );
572
-
Removed:
]